From e02f95d7671a1a903df87c2f72d069483e3184c6 Mon Sep 17 00:00:00 2001 From: botvs Date: Sat, 24 Jun 2017 15:03:06 +0800 Subject: [PATCH 01/19] update --- ...00\345\215\225\346\265\213\350\257\225.js" | 29 + ...44\346\230\223\347\255\226\347\225\245.js" | 7 +- ...26\347\225\245\346\241\206\346\236\266.js" | 89 +++ ...5\245_\344\275\216\351\242\221 (Copy).js" | 139 +++++ ...6\347\225\245_\344\275\216\351\242\221.js" | 139 +++++ ...13\345\212\277\344\272\244\346\230\223.js" | 141 +++++ ...32\346\212\225\347\255\226\347\225\245.js" | 37 +- ...71\345\206\262\347\255\226\347\225\245.js" | 14 +- ...03\346\236\227\345\257\271\345\206\262.js" | 538 ++++++++++++++++++ ...13\345\212\277\347\255\226\347\225\245.py" | 78 +++ README.md | 38 +- TableTemplet.js | 140 +++++ ...05\245\346\214\201\346\234\211 (Copy).js" | 86 +++ ...60\345\205\245\346\214\201\346\234\211.js" | 86 +++ ...\272\223 (\345\205\274\345\256\2712-3).py" | 238 ++++++++ ...13\350\257\225\347\211\210\357\274\211.py" | 57 +- ...vs rest (\345\244\215\345\210\266)5560.js" | 134 +++++ ...14\226\347\255\226\347\225\245 (Copy).js" | 142 +++++ ...60\345\214\226\347\255\226\347\225\245.js" | 142 +++++ ...44\346\230\223\347\261\273\345\272\223.js" | 11 + ...71\345\206\262\346\250\241\345\236\213.js" | 234 -------- ...46\347\273\206\344\277\241\346\201\257.js" | 6 +- ...56\344\273\267\347\233\221\346\216\247.js" | 105 ++-- ...\247-BitVC) (\345\244\215\345\210\266).js" | 531 +++++++++++++++++ ...60\347\273\204\345\212\237\350\203\275.js" | 39 ++ "\346\265\213\350\257\225.py" | 15 + ...76\350\241\250\345\261\225\347\244\272.js" | 36 +- ...07\347\253\240\347\255\226\347\225\245.js" | 202 +++++++ "\347\255\226\347\225\245001-szc.py" | 79 +++ ...60\345\215\226\347\244\272\344\276\213.js" | 63 +- ...20\206\346\250\241\346\235\277 (Copy).js" | 305 ++++++++++ ...6\233\264\346\226\26020170531) (Copy).js" | 315 ++++++++++ ...7\221\346\233\264\346\226\26020170622).js" | 332 +++++++++++ ...g) (\345\244\215\345\210\266)ttttttttt.js" | 532 +++++++++++++++++ ...25\245\346\241\206\346\236\266 (Copy).js" | 256 +++++++++ 35 files changed, 4959 insertions(+), 376 deletions(-) create mode 100644 "BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.js" create mode 100644 "JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.js" create mode 100644 "KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221 (Copy).js" create mode 100644 "KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.js" create mode 100644 "Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.js" create mode 100644 "OKCoin\350\267\250\346\234\237\345\270\203\346\236\227\345\257\271\345\206\262.js" create mode 100644 "Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" create mode 100644 TableTemplet.js create mode 100644 "buy-hold \344\271\260\345\205\245\346\214\201\346\234\211 (Copy).js" create mode 100644 "buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.js" create mode 100644 "python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" rename "python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.py" => "python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" (93%) create mode 100644 "\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest (\345\244\215\345\210\266)5560.js" create mode 100644 "\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245 (Copy).js" create mode 100644 "\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.js" delete mode 100644 "\345\225\206\345\223\201\346\234\237\350\264\247\345\245\227\345\210\251 - \345\244\232\345\223\201\347\247\215\347\275\221\346\240\274\345\257\271\345\206\262\346\250\241\345\236\213.js" create mode 100644 "\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC) (\345\244\215\345\210\266).js" create mode 100644 "\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" create mode 100644 "\346\265\213\350\257\225.py" create mode 100644 "\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.js" create mode 100644 "\347\255\226\347\225\245001-szc.py" create mode 100644 "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277 (Copy).js" create mode 100644 "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170531) (Copy).js" create mode 100644 "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170622).js" create mode 100644 "\351\234\207\350\215\241\347\252\201\347\240\264\347\255\226\347\225\245 (\345\210\240\345\207\217B\345\200\274\350\247\246\345\217\221\345\271\263\344\273\223\343\200\201\345\212\250\346\200\201\350\260\203\346\225\264\350\247\246\345\217\221\345\200\274 \344\274\230\345\214\226ing) (\345\244\215\345\210\266)ttttttttt.js" create mode 100644 "\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266 (Copy).js" diff --git "a/BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.js" "b/BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.js" new file mode 100644 index 00000000..15412488 --- /dev/null +++ "b/BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.js" @@ -0,0 +1,29 @@ +/* +策略出处: https://www.botvs.com/strategy/40289 +策略名称: BitMEX 简单测试 +策略作者: Tony123 +策略描述: + +现已接入BitMEX, 支持全平台API, 支持IO扩展. + +*/ + +// 只支持实盘 +function main() { + exchange.SetContractType("XBTUSD") + Log(_C(exchange.GetAccount)) + Log(_C(exchange.GetTicker)) + Log(_C(exchange.GetDepth)) + Log(_C(exchange.GetRecords)) + Log(_C(exchange.GetTrades)) + // IO Test + Log(_C(exchange.IO, "api", "GET", "user/affiliateStatus")) + + Log(_C(exchange.SetMarginLevel, 10)) + exchange.SetDirection("buy") + var orderId = exchange.Buy(-1, 3) + if (orderId) { + Log(_C(exchange.GetOrder, orderId)) + } + Log(_C(exchange.GetPosition)) +} diff --git "a/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" "b/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" index 9ce670e0..ae783c37 100644 --- "a/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" +++ "b/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" @@ -411,7 +411,10 @@ var TTManager = { } else if (lastPrice < lowest) { opCode = 2; } - obj.leavePeriod = (enterPeriod == obj.enterPeriodA) ? obj.leavePeriodA : obj.leavePeriodB; + if (opCode != 0) { + obj.leavePeriod = (enterPeriod == obj.enterPeriodA) ? obj.leavePeriodA : obj.leavePeriodB; + break; + } } } else { var spread = obj.marketPosition > 0 ? (obj.openPrice - lastPrice) : (lastPrice - obj.openPrice); @@ -424,7 +427,7 @@ var TTManager = { } else if (-spread > (IncSpace * obj.N)) { opCode = obj.marketPosition > 0 ? 1 : 2; } else if (records.length > obj.leavePeriod) { - obj.status.leavePrice = TA.Lowest(records, obj.leavePeriod, obj.marketPosition > 0 ? 'Low' : 'High') + obj.status.leavePrice = obj.marketPosition > 0 ? TA.Lowest(records, obj.leavePeriod, 'Low') : TA.Highest(records, obj.leavePeriod, 'High'); if ((obj.marketPosition > 0 && lastPrice < obj.status.leavePrice) || (obj.marketPosition < 0 && lastPrice > obj.status.leavePrice)) { obj.preBreakoutFailure = false; diff --git "a/JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.js" "b/JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.js" new file mode 100644 index 00000000..3008d078 --- /dev/null +++ "b/JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.js" @@ -0,0 +1,89 @@ +/* +策略出处: https://www.botvs.com/strategy/44593 +策略名称: JS版 商品期货 精简多品种 MACD 趋势策略框架 +策略作者: 小小梦 +策略描述: + + + +*/ + +/*backtest +start: 2016-01-30 +end: 2016-12-30 +period: 1440 +periodBase: 60 +mode: 0 +*/ + +// 作者 Zero +function Trader(q, symbol){ + var obj = {}; + obj.q = q; + obj.symbol = symbol; + obj.position = 0; + obj.isPending = false; + + obj.onOpen = function(task, ret){ + if(ret){ + obj.position = ret.position.Amount * ((ret.position.Type == PD_LONG || ret.position.Type == PD_LONG_YD) ? 1 : -1); + } + Log(task.desc, "Position:", obj.position, ret); + obj.isPending = false; + } + + obj.onCover = function(task, ret){ + obj.isPending = false; + obj.position = 0; + Log(task.desc, ret); + } + + obj.onTick = function(){ + if(obj.isPending){ + return; + } + var ct = exchange.SetContractType(obj.symbol); + if(!ct){ + return; + } + var r = exchange.GetRecords(); + if(!r || r.length < 35){ + return; + } + var macd = TA.MACD(r); + var diff = macd[0][macd[0].length - 2] - macd[1][macd[1].length - 2]; + + if(Math.abs(diff) > 0 && obj.position == 0){ + obj.ispending = true; + obj.q.pushTask(exchange, obj.symbol, (diff > 0 ? "buy" : "sell"), 1, obj.onOpen); + } + + if(Math.abs(diff) > 0 && ((diff > 0 && obj.position < 0) || (diff < 0 && obj.position > 0))){ + obj.isPending = true; + obj.q.pushTask(exchange, obj.symbol, (obj.position > 0 ? "closebuy" : "closesell"), 1, obj.onCover); + } + } + + return obj; +} + +function main(){ + var q = $.NewTaskQueue(); + Log(_C(exchange.GetAccount)); + tasks = []; + var ContractArray = ["MA701", "rb1701"]; + for(var index in ContractArray){ + tasks.push(Trader(q, ContractArray[index])); + } + while(true){ + if(exchange.IO("status")){ + for(var j in tasks){ + tasks[j].onTick(); + } + q.poll(); + } + Sleep(1000); + } +} + + diff --git "a/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221 (Copy).js" "b/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221 (Copy).js" new file mode 100644 index 00000000..d2d44087 --- /dev/null +++ "b/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221 (Copy).js" @@ -0,0 +1,139 @@ +/* +策略出处: https://www.botvs.com/strategy/42312 +策略名称: KingKeltner趋势策略_低频 (Copy) +策略作者: jdm16478 +策略描述: + + + +*/ + +/* +策略出处: vnpy +策略名称: KingKeltner趋势策略 +策略作者: ipqhjjybj +策略描述: +趋势跟踪策略 + +*/ + +KK_Length = 11 // 计算通道中值的窗口数 +kkDev = 1.3 // 计算通道宽度的偏差 +trailingPrcnt = 15 // 移动止损 +LoopInterval = 60 // 轮询间隔(秒) +SlidePrice = 0.3 // 滑动价(元) +function adjustFloat(v) { + return Math.floor(v*1000)/1000; +} + +function CancelPendingOrders() { + while (true) { + var orders = null; + while (!(orders = exchange.GetOrders())) { + Sleep(Interval); + } + + if (orders.length == 0) { + return; + } + + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]); + if (j < (orders.length-1)) { + Sleep(Interval); + } + } + } +} + +function GetAccount() { + var account; + while (!(account = exchange.GetAccount())) { + Sleep(Interval); + } + return account; +} + +function GetTicker() { + var ticker; + while (!(ticker = exchange.GetTicker())) { + Sleep(Interval); + } + return ticker; +} + +var intraTradeHigh = 0; // 移动最高价 +var intraTradeLow = 99999999; // 移动最低价 +var LastBuyPrice = 0; // 上一次买的价格 +var LastSellPrice = 0; // 上一次卖的价格 +var minMoney = 100; // 如果资金小于该数值,则不买入 +var LastRecord = null; // 初始化上一个记录 +function onTick(exchange) { + + var ticker = GetTicker(); + // Buy or Sell, Cancel pending orders first + CancelPendingOrders(); + var account = GetAccount(); + + if (true) { + var records = exchange.GetRecords(); + if (!records || records.length < (KK_Length + 3)) { + return; + } + // Price not change + var newLast = records[records.length-1]; + if ((!LastRecord) || (LastRecord.Time == newLast.Time && LastRecord.Close == newLast.Close)) { + LastRecord = newLast; + return; + } + LastRecord = newLast; + + //Log(newLast); + var kk_ATR = TA.ATR(records , KK_Length); + var kk_Mid = TA.MA(records, KK_Length); + var kk_Up = kk_Mid[kk_Mid.length-1] + kk_ATR[kk_ATR.length-1] * kkDev; + //var kk_Down= kk_Mid - kk_ATR * kkDev + + //Log("LastRecord.Close",LastRecord.Close ,"kk_up",kk_Up,"intraTradeHigh",intraTradeHigh); + if( account.Stocks <= exchange.GetMinStock() ){ + if(LastRecord.Close > kk_Up){ + Log("start buy"); + var price = ticker.Last + SlidePrice; + var amount = adjustFloat(account.Balance / price); + if (account.Balance > minMoney && amount >= exchange.GetMinStock()) { + if (exchange.Buy(price, amount, "做多")) { + intraTradeHigh = LastRecord.High + intraTradeLow = LastRecord.Low + LastBuyPrice = LastHighPrice = price; + } + } + } + } + else if( exchange.GetMinStock() < account.Stocks ){ + Log("Close",LastRecord.Close, "intraTradeHigh",intraTradeHigh ,"intraTradeHigh * ( 1 - trailingPrcnt)",intraTradeHigh * ( 1 - trailingPrcnt/100.0)) + intraTradeHigh = Math.max(intraTradeHigh , LastRecord.High) + intraTradeLow = LastRecord.Low + if(LastRecord.Close < intraTradeHigh * ( 1 - trailingPrcnt/100.0)){ // 移动止损 + Log("start sell"); + var price = ticker.Last - SlidePrice; + var sellAmount = account.Stocks; + if (sellAmount > exchange.GetMinStock()) { + exchange.Sell(ticker.Last - SlidePrice, sellAmount, "卖出"); + LastSellPrice = LastLowPrice = price; + } + } + } + } +} + + +function main() { + InitAccount = GetAccount(); + Log(exchange.GetName(), exchange.GetCurrency(), InitAccount); + + LoopInterval = Math.max(LoopInterval, 1); + while (true) { + onTick(exchange); + Sleep(LoopInterval*1000); + } +} diff --git "a/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.js" "b/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.js" new file mode 100644 index 00000000..cb73e681 --- /dev/null +++ "b/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.js" @@ -0,0 +1,139 @@ +/* +策略出处: https://www.botvs.com/strategy/42283 +策略名称: KingKeltner趋势策略_低频 +策略作者: ipqhjjybj +策略描述: + + + +*/ + +/* +策略出处: vnpy +策略名称: KingKeltner趋势策略 +策略作者: ipqhjjybj +策略描述: +趋势跟踪策略 + +*/ + +KK_Length = 11 // 计算通道中值的窗口数 +kkDev = 1.3 // 计算通道宽度的偏差 +trailingPrcnt = 15 // 移动止损 +LoopInterval = 60 // 轮询间隔(秒) +SlidePrice = 0.3 // 滑动价(元) +function adjustFloat(v) { + return Math.floor(v*1000)/1000; +} + +function CancelPendingOrders() { + while (true) { + var orders = null; + while (!(orders = exchange.GetOrders())) { + Sleep(Interval); + } + + if (orders.length == 0) { + return; + } + + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]); + if (j < (orders.length-1)) { + Sleep(Interval); + } + } + } +} + +function GetAccount() { + var account; + while (!(account = exchange.GetAccount())) { + Sleep(Interval); + } + return account; +} + +function GetTicker() { + var ticker; + while (!(ticker = exchange.GetTicker())) { + Sleep(Interval); + } + return ticker; +} + +var intraTradeHigh = 0; // 移动最高价 +var intraTradeLow = 99999999; // 移动最低价 +var LastBuyPrice = 0; // 上一次买的价格 +var LastSellPrice = 0; // 上一次卖的价格 +var minMoney = 100; // 如果资金小于该数值,则不买入 +var LastRecord = null; // 初始化上一个记录 +function onTick(exchange) { + + var ticker = GetTicker(); + // Buy or Sell, Cancel pending orders first + CancelPendingOrders(); + var account = GetAccount(); + + if (true) { + var records = exchange.GetRecords(); + if (!records || records.length < (KK_Length + 3)) { + return; + } + // Price not change + var newLast = records[records.length-1]; + if ((!LastRecord) || (LastRecord.Time == newLast.Time && LastRecord.Close == newLast.Close)) { + LastRecord = newLast; + return; + } + LastRecord = newLast; + + //Log(newLast); + var kk_ATR = TA.ATR(records , KK_Length); + var kk_Mid = TA.MA(records, KK_Length); + var kk_Up = kk_Mid[kk_Mid.length-1] + kk_ATR[kk_ATR.length-1] * kkDev; + //var kk_Down= kk_Mid - kk_ATR * kkDev + + //Log("LastRecord.Close",LastRecord.Close ,"kk_up",kk_Up,"intraTradeHigh",intraTradeHigh); + if( account.Stocks <= exchange.GetMinStock() ){ + if(LastRecord.Close > kk_Up){ + Log("start buy"); + var price = ticker.Last + SlidePrice; + var amount = adjustFloat(account.Balance / price); + if (account.Balance > minMoney && amount >= exchange.GetMinStock()) { + if (exchange.Buy(price, amount, "做多")) { + intraTradeHigh = LastRecord.High + intraTradeLow = LastRecord.Low + LastBuyPrice = LastHighPrice = price; + } + } + } + } + else if( exchange.GetMinStock() < account.Stocks ){ + Log("Close",LastRecord.Close, "intraTradeHigh",intraTradeHigh ,"intraTradeHigh * ( 1 - trailingPrcnt)",intraTradeHigh * ( 1 - trailingPrcnt/100.0)) + intraTradeHigh = Math.max(intraTradeHigh , LastRecord.High) + intraTradeLow = LastRecord.Low + if(LastRecord.Close < intraTradeHigh * ( 1 - trailingPrcnt/100.0)){ // 移动止损 + Log("start sell"); + var price = ticker.Last - SlidePrice; + var sellAmount = account.Stocks; + if (sellAmount > exchange.GetMinStock()) { + exchange.Sell(ticker.Last - SlidePrice, sellAmount, "卖出"); + LastSellPrice = LastLowPrice = price; + } + } + } + } +} + + +function main() { + InitAccount = GetAccount(); + Log(exchange.GetName(), exchange.GetCurrency(), InitAccount); + + LoopInterval = Math.max(LoopInterval, 1); + while (true) { + onTick(exchange); + Sleep(LoopInterval*1000); + } +} diff --git "a/Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.js" "b/Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.js" new file mode 100644 index 00000000..496af319 --- /dev/null +++ "b/Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.js" @@ -0,0 +1,141 @@ +/* +策略出处: https://www.botvs.com/strategy/42451 +策略名称: Ma单均线趋势交易 +策略作者: ipqhjjybj +策略描述: + + + +*/ + +/* +策略出处: internet +策略名称: MA 单均线趋势策略 +策略作者: ipqhjjybj +策略描述: 均线向上做多,均线向下做空 , bitcoin只做多 +趋势跟踪策略 + +*/ + +MA_Length = 120 // 计算通道中值的窗口数 +trailingPrcnt = 15 // 移动止损 +LoopInterval = 60 // 轮询间隔(秒) +SlidePrice = 0.3 // 滑动价(元) +function adjustFloat(v) { + return Math.floor(v*1000)/1000; +} + + +function CancelPendingOrders() { + while (true) { + var orders = null; + while (!(orders = exchange.GetOrders())) { + Sleep(Interval); + } + + if (orders.length == 0) { + return; + } + + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]); + if (j < (orders.length-1)) { + Sleep(Interval); + } + } + } +} + +function GetAccount() { + var account; + while (!(account = exchange.GetAccount())) { + Sleep(Interval); + } + return account; +} + + +function GetTicker() { + var ticker; + while (!(ticker = exchange.GetTicker())) { + Sleep(Interval); + } + return ticker; +} + +var minMoney = 100; // 如果资金小于该数值,则不买入 +var LastRecord = null; // 初始化上一个记录 + + +function onTick(exchange) { + + var ticker = GetTicker(); + // Buy or Sell, Cancel pending orders first + CancelPendingOrders(); + var account = GetAccount(); + + if (true) { + var records = exchange.GetRecords(); + if (!records || records.length < (MA_Length + 3)) { + return; + } + // Price not change + var newLast = records[records.length-1]; + if ((!LastRecord) || (LastRecord.Time == newLast.Time && LastRecord.Close == newLast.Close)) { + LastRecord = newLast; + return; + } + LastRecord = newLast; + + var kk_MA = TA.MA(records , MA_Length); + + var ma_inc = kk_MA[kk_MA.length-1] / kk_MA[kk_MA.length-2]; + + Log( "kk_MA 1", kk_MA[kk_MA.length-1] , "kk_MA 2", kk_MA[kk_MA.length-2] ) + //Log(newLast); + // var kk_ATR = TA.ATR(records , KK_Length); + // var kk_Mid = TA.MA(records, KK_Length); + // var kk_Up = kk_Mid[kk_Mid.length-1] + kk_ATR[kk_ATR.length-1] * kkDev; + //var kk_Down= kk_Mid - kk_ATR * kkDev + + //Log("LastRecord.Close",LastRecord.Close ,"kk_up",kk_Up,"intraTradeHigh",intraTradeHigh); + if( account.Stocks <= exchange.GetMinStock() ){ + if(ma_inc > 1.000001){ + + var price = ticker.Last + SlidePrice; + var amount = adjustFloat(account.Balance / price); + if (account.Balance > minMoney && amount >= exchange.GetMinStock()) { + Log("start buy"); + if (exchange.Buy(price, amount, "做多")) { + LastBuyPrice = LastHighPrice = price; + } + } + } + } + else if( exchange.GetMinStock() < account.Stocks ){ + if(ma_inc < 0.999999){ // 移动止损 + var price = ticker.Last - SlidePrice; + var sellAmount = account.Stocks; + if (sellAmount > exchange.GetMinStock()) { + Log("start sell"); + exchange.Sell(ticker.Last - SlidePrice, sellAmount, "卖出"); + LastSellPrice = LastLowPrice = price; + } + } + } + } +} + + +function main() { + InitAccount = GetAccount(); + Log(exchange.GetName(), exchange.GetCurrency(), InitAccount); + + LoopInterval = Math.max(LoopInterval, 1); + while (true) { + onTick(exchange); + Sleep(LoopInterval*1000); + } +} + + diff --git "a/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.js" "b/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.js" index 8a1d2d3d..13675538 100644 --- "a/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.js" +++ "b/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.js" @@ -4,22 +4,22 @@ 策略作者: Lizza 策略描述: -实盘:https://www.botvs.com/m/robot/26018 -这个策略适合长期看好比特币的脑残粉,使用价值平均策略来进行定投,可以有效的抵抗市场波动。(关于价值平均定投请度娘。) - -基本的思路是先想好每个月想要投入多少钱(策略变量:MoneyEveryMonth),然后决定多久交易一次,交易的间隔不建议小于5分钟(策略参数:InvestInternal)。 - -以下用一个实例说明策略思路和买卖时机: -假设每月想要买入价值72000元人民币的比特币(便于计算),每个小时交易一次,就是计划每个月交易24*30=720次,每次计划投入的资金价值为72000/720=100元(变量A)。 - -小时B,当时价格C,已投入资金D,已买入币数E,现在币价值F,本次投入资金G, 本次买入币数H -1 400 0 0 C*E=0 A*B-F=100 G/C=0.25 -2 200 100 0.25 200*0.25=50 100*2-50=150 0.75 -3 1000 250 1 1000 100*3-1000=-700 -0.7 -4 500 -550 0.3 150 100*4-150=250 0.5 - -最终的结果,投入资金300,买入0.8个比特币(价值400元),平均价格375元。 - +实盘:https://www.botvs.com/m/robot/26018 +这个策略适合长期看好比特币的脑残粉,使用价值平均策略来进行定投,可以有效的抵抗市场波动。(关于价值平均定投请度娘。) + +基本的思路是先想好每个月想要投入多少钱(策略变量:MoneyEveryMonth),然后决定多久交易一次,交易的间隔不建议小于5分钟(策略参数:InvestInternal)。 + +以下用一个实例说明策略思路和买卖时机: +假设每月想要买入价值72000元人民币的比特币(便于计算),每个小时交易一次,就是计划每个月交易24*30=720次,每次计划投入的资金价值为72000/720=100元(变量A)。 + +小时B,当时价格C,已投入资金D,已买入币数E,现在币价值F,本次投入资金G, 本次买入币数H +1 400 0 0 C*E=0 A*B-F=100 G/C=0.25 +2 200 100 0.25 200*0.25=50 100*2-50=150 0.75 +3 1000 250 1 1000 100*3-1000=-700 -0.7 +4 500 -550 0.3 150 100*4-150=250 0.5 + +最终的结果,投入资金300,买入0.8个比特币(价值400元),平均价格375元。 + 说明:程序会每次检查账户内的资金和比特币与启动时的差额,以此计算每次需要购买的数量,因此不要用其他机器人公用一个帐户,也不要手工进行买入卖出的操作。如果在交易所有充值和体现,应该在程序互动部分填入,否则程序计算会错误。 @@ -38,8 +38,6 @@ MoneyChange false 纪录资金充值或提现 StockChange false 纪录数字货币充值或提现 */ -// botvs@298456fac4241b54943e954fe81f45ee - var initAccount; var startTime; //unix timestamp var pause = false; //pause execution of strategy or continue @@ -268,5 +266,4 @@ function onexit(){ _G('StockDeposit', stockDeposit); Log('Robot Stopped!#ff0000@'); -} - +} diff --git "a/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.js" "b/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.js" index cde6f879..0fda99e4 100644 --- "a/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.js" +++ "b/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.js" @@ -4,13 +4,16 @@ 策略作者: 小小梦 策略描述: -OKCoin期货跨期对冲策略,季度、当周、次周 +### OKCoin期货跨期对冲策略,季度、当周、次周 - 1、 季度-当周 - 2、 季度-次周 - 3、 当周-次周 - 4、在周五交割前5分钟会自动 平仓, 锁定15分钟 后再正常运行。 -BUG: +### 更新: +- 更新新域名 修改API 地址 用于获取 交割时间,原地址 修改为 www.okex.com + +### BUG: 在期货策略中 不能使用 Go函数 ,会导致切换合约问题, 对此 策略已经修改,改为一般调用。 支持限价单模式。 市价单模式有一些问题。 @@ -165,11 +168,12 @@ function CheckDelivery(nowTime, Symbol, task) { while (contractName == "") { //var contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=this_week"); //只是检测this_week ,避免重复调用提高效率 switch(ContractIndex){ - case 0: contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=this_week"); + case 0: contractInfo = HttpQuery("https://www.okex.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=this_week"); + // www.okex.com 更换新域名 break; - case 1: contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=next_week"); + case 1: contractInfo = HttpQuery("https://www.okex.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=next_week"); break; - case 2: contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=quarter"); + case 2: contractInfo = HttpQuery("https://www.okex.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=quarter"); break; default: Log("contractInfo:", contractInfo); //throw "switch NumContractType Error!"; diff --git "a/OKCoin\350\267\250\346\234\237\345\270\203\346\236\227\345\257\271\345\206\262.js" "b/OKCoin\350\267\250\346\234\237\345\270\203\346\236\227\345\257\271\345\206\262.js" new file mode 100644 index 00000000..24f323f9 --- /dev/null +++ "b/OKCoin\350\267\250\346\234\237\345\270\203\346\236\227\345\257\271\345\206\262.js" @@ -0,0 +1,538 @@ +/* +策略出处: https://www.botvs.com/strategy/43049 +策略名称: OKCoin跨期布林对冲 +策略作者: 小小梦 +策略描述: + + + + +参数 默认值 描述 +-------------- --------- ------------------------------ +isLogReset false 是否清空所有日志 +P_SymbolA quarter 合约A +P_SymbolB this_week 合约B +P_Interval 500 轮询间隔 +P_isSetTest false 测试模式 +MaxUsedRatio 0.5 保证金最大使用比例 +MarginLevel 10 杠杆 +P_piece 2 每次触发开仓下单量 +CoverRatio 0.1 每次平仓比例 +minCoverAmount 2 每次平仓最小值 +P_KPeriod 0 K线周期: 1分钟|5分钟|15分钟|30分钟|1小时|1天 +Add_lv 0.05 系数递增比例 +*/ + +var P_isSetOneKLine = true; +var isShowChart = true; +var retrySlidePrice = 2; + +// 全局变量 +var KPeriod = [PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_D1][P_KPeriod]; +var DiffData = { // 差价K线数据 + plusKLine : [], // 差价K线数组 + minusKLine : [], + KPeriod : KPeriod, // 差价K线周期 +}; + +var distance = 0; // 距离 +var IDLE = 0; +var PLUS = 1; +var MINUS = 2; +var State = IDLE; // 策略 运行状态状态 +var perState = IDLE; + +var OPEN = 3; // 用于区分 是那种操作 在 BuyA_SellB 、 SellA_BuyB 函数中 +var COVER = 4; +var isTradeOnThisBar = false; // 是否在当前Bar 交易了 废弃 +var isCoverOnthisBar = false; // 废弃 +var upRatio = 0; +var downRatio = 0; + +var P = null; // 交易控制对象 +var ManagerData = { // 控制对象 + initAccount : null, // 初始账户 信息 + Account : null, // 当前账户 信息 + perAccount : null, + MaxUsedRatio : MaxUsedRatio, // 最大 保证金使用率 + MaxUsedMargin : 0, // 每次 平仓后 重新计算的 最大保证金使用量 + APosition : null, // 多头 仓位信息 + BPosition : null, // 空头 仓位信息 + floatProfit : 0, // 浮动盈亏 + CoverProfit : 0, // 平仓盈亏 + MarginLevel : MarginLevel, // 杠杆数 + Margin : 0, // 当前保证金使用 + + // 行情数据 + DepthA : null, // A 合约的 深度数据 + DepthB : null, // B 合约的 深度数据 + + // 错误信息 + ErrorStr : "", // 错误信息字符串 + ErrorTimeStamp : 0, // 错误信息 时间戳 +} + +var DiffDataOneKLine = { // K线结构 + KLine : [], // K线数组 ,整理后的差价 + KPeriod : KPeriod, // K线周期 +} +var test = { // 测试 模式 使用的结构 + amount : 4, + ProfitDiff : 0, + ID : 0, + OpenDiff : 0, +}; +var perRecordsTime = 0; // 合成的 K线 上一个bar 的时间戳 + +var PeriodBeginTime = 0; // 周期起始时间 + +function UpdateDiffData(DepthA, DepthB, RecordsA, RecordsB){ // 处理差价K线数据的更新 + var plusDiff = DepthA.Bids[0].Price - DepthB.Asks[0].Price; + var minusDiff = DepthA.Asks[0].Price - DepthB.Bids[0].Price; + if(P_isSetOneKLine){ + var Diff = _N((plusDiff + minusDiff) / 2 , 4); + } + if(RecordsA[RecordsA.length - 1].Time == RecordsB[RecordsB.length - 1].Time && RecordsB[RecordsB.length - 1].Time !== PeriodBeginTime){ + if(!P_isSetOneKLine){ + // 新K线周期出现 + var plusBar = { + Open : plusDiff, + Close : plusDiff, + High : plusDiff, + Low : plusDiff, + Time : 0, + }; + + var minusBar = { + Open : minusDiff, + Close : minusDiff, + High : minusDiff, + Low : minusDiff, + Time : 0, + }; + + PeriodBeginTime = RecordsB[RecordsB.length - 1].Time; + plusBar.Time = PeriodBeginTime; + minusBar.Time = PeriodBeginTime; + DiffData.plusKLine.push(plusBar); + DiffData.minusKLine.push(minusBar); + }else{ + var Bar = { + Open : Diff, + Close : Diff, + High : Diff, + Low : Diff, + Time : 0, + }; + PeriodBeginTime = RecordsB[RecordsB.length - 1].Time; + Bar.Time = PeriodBeginTime; + DiffDataOneKLine.KLine.push(Bar); + } + }else{ + if(!P_isSetOneKLine){ + if(plusDiff > DiffData.plusKLine[DiffData.plusKLine.length - 1].High){ + DiffData.plusKLine[DiffData.plusKLine.length - 1].High = plusDiff; + }else if(plusDiff < DiffData.plusKLine[DiffData.plusKLine.length - 1].Low){ + DiffData.plusKLine[DiffData.plusKLine.length - 1].Low = plusDiff; + } + DiffData.plusKLine[DiffData.plusKLine.length - 1].Close = plusDiff; + + if(minusDiff > DiffData.minusKLine[DiffData.minusKLine.length - 1].High){ + DiffData.minusKLine[DiffData.minusKLine.length - 1].High = minusDiff; + }else if(minusDiff < DiffData.minusKLine[DiffData.minusKLine.length - 1].Low){ + DiffData.minusKLine[DiffData.minusKLine.length - 1].Low = minusDiff; + } + DiffData.minusKLine[DiffData.minusKLine.length - 1].Close = minusDiff; + }else{ + if(Diff > DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].High){ + DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].High = Diff; + }else if(Diff < DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Low){ + DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Low = Diff; + } + DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close = Diff; + } + } + + if(!P_isSetOneKLine){ + if(DiffData.plusKLine.length > 100){ + DiffData.plusKLine.shift(); + } + + if(DiffData.minusKLine.length > 100){ + DiffData.minusKLine.shift(); + } + }else{ + if(DiffDataOneKLine.KLine.length > 100){ + DiffDataOneKLine.KLine.shift(); + } + } +} + +function UseAPI(fun, symbol, param){ + exchange.SetContractType(symbol); + if(typeof(param) == "undefined"){ + return fun(); + }else{ + return fun(param); + } +} + +function GetPositions(){ + var positions = _C(exchange.GetPosition); + for(var i = 0; i < positions.length; i++){ + if(positions[i].ContractType == P_SymbolA){ + ManagerData.APosition = positions[i]; + }else if(positions[i].ContractType == P_SymbolB){ + ManagerData.BPosition = positions[i]; + }else if(i == 2){ + throw "error:" + JSON.stringify(positions); + } + } + if(positions.length == 0){ + ManagerData.APosition = null; + ManagerData.BPosition = null; + } + return positions; +} + +function SellA_BuyB(DiffPrice, Action){ + // GetBestAmount + var Piece = P_piece; + if(Action == OPEN){ + // 检查 是否超出 保证金 + var MarginAndAmount_A = CalcPieceEqualAmount(ManagerData.DepthA.Bids[0].Price, Piece); + var MarginAndAmount_B = CalcPieceEqualAmount(ManagerData.DepthB.Asks[0].Price, Piece); + if(MarginAndAmount_A.NeedMargin + MarginAndAmount_B.NeedMargin + ManagerData.Margin > ManagerData.MaxUsedMargin){ + ManagerData.ErrorStr = "超过最大可用保证金:" + ManagerData.MaxUsedMargin; + ManagerData.ErrorTimeStamp = new Date().getTime(); + return false; + } + // 交易 + _C(exchange.SetContractType, P_SymbolA); + var infoA = P.OpenShort(P_SymbolA, Piece, ManagerData.DepthA.Bids[0].Price); + if(infoA.amount == 0){ + return false; + } + _C(exchange.SetContractType, P_SymbolB); + var dealAmount = infoA.amount; + var infoB = P.OpenLong(P_SymbolB, dealAmount, ManagerData.DepthB.Asks[0].Price); + var slidePrice = retrySlidePrice; + while((dealAmount -= infoB.amount) > 0){ + infoB = P.OpenLong(P_SymbolB, dealAmount, ManagerData.DepthB.Asks[0].Price + slidePrice); + slidePrice += retrySlidePrice; + LogStatus("while(), P_SymbolB:", P_SymbolB, infoB, dealAmount, slidePrice); + } + + // 更新数据 + ManagerData.perAccount = ManagerData.Account; + ManagerData.Account = _C(exchange.GetAccount); + ManagerData.Margin += (ManagerData.perAccount.Stocks - ManagerData.Account.Stocks); + Log("持仓信息:", GetPositions(), "本次使用保证金:", (ManagerData.perAccount.Stocks - ManagerData.Account.Stocks)); + perState = State; + State = PLUS; + }else if(Action == COVER){ + // 全平 + _C(exchange.SetContractType, P_SymbolA); + var infoA = P.Cover(P_SymbolA, ManagerData.DepthA.Bids[0].Price, Math.min(ManagerData.APosition.Amount, Math.max(_N(ManagerData.APosition.Amount * CoverRatio, 0), minCoverAmount)), PD_LONG); + if(infoA == 0){ + return false; + } + _C(exchange.SetContractType, P_SymbolB); + var dealAmount = infoA; + var infoB = P.Cover(P_SymbolB, ManagerData.DepthB.Asks[0].Price, dealAmount, PD_SHORT); + var slidePrice = retrySlidePrice; + while((dealAmount -= infoB) > 0){ + infoB = P.Cover(P_SymbolB, ManagerData.DepthB.Asks[0].Price + slidePrice, dealAmount, PD_SHORT); + slidePrice += retrySlidePrice; + LogStatus("while(), P_SymbolB:", P_SymbolB, infoB, dealAmount, slidePrice); + } + Log("持仓信息:", GetPositions()); + if(ManagerData.APosition == null && ManagerData.BPosition == null){ + perState = State; + State = IDLE; + upRatio = 0; + downRatio = 0; + Log("完全平仓!#FF0000"); + Log("更新最大保证金使用量:", DealManagerData()); + LogProfit(ManagerData.Account.Stocks - ManagerData.initAccount.Stocks); // ceshi + }else{ + ManagerData.perAccount = ManagerData.Account; + ManagerData.Account = _C(exchange.GetAccount); + Log("部分平仓:", infoA); + } + } + return true; +} + +function BuyA_SellB(DiffPrice, Action){ + // GetBestAmount + var Piece = P_piece; + if(Action == OPEN){ + // 检查 是否超出 保证金 + var MarginAndAmount_A = CalcPieceEqualAmount(ManagerData.DepthA.Asks[0].Price, Piece); + var MarginAndAmount_B = CalcPieceEqualAmount(ManagerData.DepthB.Bids[0].Price, Piece); + if(MarginAndAmount_A.NeedMargin + MarginAndAmount_B.NeedMargin + ManagerData.Margin > ManagerData.MaxUsedMargin){ + ManagerData.ErrorStr = "超过最大可用保证金:" + ManagerData.MaxUsedMargin; + ManagerData.ErrorTimeStamp = new Date().getTime(); + return false; + } + // 交易 + _C(exchange.SetContractType, P_SymbolA); + var infoA = P.OpenLong(P_SymbolA, Piece, ManagerData.DepthA.Asks[0].Price); + if(infoA.amount == 0){ + return false; + } + _C(exchange.SetContractType, P_SymbolB); + var dealAmount = infoA.amount; + var infoB = P.OpenShort(P_SymbolB, dealAmount, ManagerData.DepthB.Bids[0].Price); + var slidePrice = retrySlidePrice; + while((dealAmount -= infoB.amount) > 0){ + infoB = P.OpenShort(P_SymbolB, dealAmount, ManagerData.DepthB.Bids[0].Price - slidePrice); + slidePrice += retrySlidePrice; + LogStatus("while(), P_SymbolB:", P_SymbolB, infoB, dealAmount, slidePrice); + } + + // 更新数据 + ManagerData.perAccount = ManagerData.Account; + ManagerData.Account = _C(exchange.GetAccount); + ManagerData.Margin += (ManagerData.perAccount.Stocks - ManagerData.Account.Stocks); + Log("持仓信息:", GetPositions(), "本次使用保证金:", (ManagerData.perAccount.Stocks - ManagerData.Account.Stocks)); + perState = State; + State = MINUS; + }else if(Action == COVER){ + // 全平 + _C(exchange.SetContractType, P_SymbolA); + var infoA = P.Cover(P_SymbolA, ManagerData.DepthA.Asks[0].Price, Math.min(ManagerData.APosition.Amount, Math.max(_N(ManagerData.APosition.Amount * CoverRatio, 0), minCoverAmount)), PD_SHORT); + if(infoA == 0){ + return false; + } + _C(exchange.SetContractType, P_SymbolB); + var dealAmount = infoA; + var infoB = P.Cover(P_SymbolB, ManagerData.DepthB.Bids[0].Price, dealAmount, PD_LONG); + var slidePrice = retrySlidePrice; + while((dealAmount -= infoB) > 0){ + infoB = P.Cover(P_SymbolB, ManagerData.DepthB.Bids[0].Price - slidePrice, dealAmount, PD_LONG); + slidePrice += retrySlidePrice; + LogStatus("while(), P_SymbolB:", P_SymbolB, infoB, dealAmount, slidePrice); + } + Log("持仓信息:", GetPositions()); + if(ManagerData.APosition == null && ManagerData.BPosition == null){ + perState = State; + State = IDLE; + upRatio = 0; // 重置 + downRatio = 0; // 重置 + Log("完全平仓!#FF0000"); + Log("更新最大保证金使用量:", DealManagerData()); + LogProfit(ManagerData.Account.Stocks - ManagerData.initAccount.Stocks); // ceshi + }else{ + ManagerData.perAccount = ManagerData.Account; + ManagerData.Account = _C(exchange.GetAccount); + Log("部分平仓:", infoA); + } + } + return true; +} + +function DealManagerData(){ // 处理 ManagerData + ManagerData.perAccount = ManagerData.Account; + ManagerData.Account = _C(exchange.GetAccount); // 获取 平仓后的 账户信息 + var Position = _C(exchange.GetPosition); // 获取 平仓后的持仓信息 + if(Position.length == 0){ // 如果 平仓完成 ,没有持仓了 重置 ManagerData 的 持仓信息属性 + ManagerData.APosition = null; + ManagerData.BPosition = null; + ManagerData.Margin = 0; // 重置 当前使用的保证金 为 0 + }else{ // 如果有持仓 报错,打印持仓 + Log("平仓后还有持仓!", Position, "#FF0000"); + throw "error!"; + } + ManagerData.MaxUsedMargin = _N(ManagerData.Account.Stocks * ManagerData.MaxUsedRatio, 2); // 计算下一轮 最大的 保证金使用量 + return ManagerData.MaxUsedMargin; +} + +function CalcPieceEqualAmount(Price, Piece){ + return { + EqualAmount : (100 / Price * Piece), + NeedMargin : (100 / Price * Piece) / ManagerData.MarginLevel, + } +} + +function Loop(nowTime){ // 主循环 + var DepthA = UseAPI(exchange.GetDepth, P_SymbolA); + var DepthB = UseAPI(exchange.GetDepth, P_SymbolB); + + var RecordsA = UseAPI(exchange.GetRecords, P_SymbolA, KPeriod); + var RecordsB = UseAPI(exchange.GetRecords, P_SymbolB, KPeriod); + + // 过滤数据 + if(!RecordsA || !RecordsB || !DepthA || !DepthB || DepthA.Bids.length == 0 || DepthA.Asks.length == 0 || + DepthB.Bids.length == 0 || DepthB.Asks.length == 0 || RecordsA.length == 0 || RecordsB.length == 0){ + return; + } + + ManagerData.DepthA = DepthA; + ManagerData.DepthB = DepthB; + + // 更新 差价K线数据 + UpdateDiffData(DepthA, DepthB, RecordsA, RecordsB); + + if(isShowChart == true){ + if(!P_isSetOneKLine){ + $.PlotRecords(DiffData.plusKLine, 'plus'); + }else{ + $.PlotRecords(DiffDataOneKLine.KLine, 'KLine'); + } + } + + // BOLL + if(P_isSetOneKLine && DiffDataOneKLine.KLine.length > 20){ + var boll = TA.BOLL(DiffDataOneKLine.KLine); + var up = boll[0]; + var mid = boll[1]; + var down = boll[2]; + + if(perRecordsTime !== DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time){ + if(isShowChart == true){ + $.PlotLine("up", up[up.length - 2], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 2].Time); + $.PlotLine("mid", mid[mid.length - 2], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 2].Time); + $.PlotLine("down", down[down.length - 2], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 2].Time); + + $.PlotLine("up", up[up.length - 1], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time); + $.PlotLine("mid", mid[mid.length - 1], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time); + $.PlotLine("down", down[down.length - 1], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time); + + // $.PlotHLine(up[up.length - 1], 'UpTrack', "red"); + // $.PlotHLine(down[down.length - 1], 'DownTrack', "green"); + } + perRecordsTime = DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time; + isTradeOnThisBar = false; // 重置 是否当前Bar 交易的标记为 false + isCoverOnthisBar = false; + }else{ + if(isShowChart == true){ + $.PlotLine("up", up[up.length - 1], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time); + $.PlotLine("mid", mid[mid.length - 1], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time); + $.PlotLine("down", down[down.length - 1], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time); + + // $.PlotHLine(up[up.length - 1], 'UpTrack', "red"); + // $.PlotHLine(down[down.length - 1], 'DownTrack', "green"); + } + } + + + // 突破判断 + // 计算加仓距离 + distance = _N((up[up.length - 1] - down[down.length - 1]) * 0.5, 0); + + if(distance * 2 < 20 && (upRatio == 0 && downRatio == 0)){ // 计算安全间距 + return; + } + + if(DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close > up[up.length - 1]){ + if((State == IDLE || State == PLUS) && (DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close > (up[up.length - 1] + upRatio * distance)) /*&& isTradeOnThisBar == false*/){ // Open PLUS + if(P_isSetTest){ + // 模拟 + $.PlotFlag(nowTime, 'plus', 'P', 'flag', 'red'); + State = PLUS; + exchange.Log(LOG_TYPE_SELL, test.ID++, DepthA.Bids[0].Price, test.amount, "Open:" + P_SymbolA); + exchange.Log(LOG_TYPE_BUY, test.ID++, DepthB.Asks[0].Price, test.amount, "Open:" + P_SymbolB); + test.OpenDiff = DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close; + }else{ + var info = SellA_BuyB(DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close, OPEN); + if(info == false){ + return; + } + $.PlotFlag(nowTime, 'plus', 'P', 'flag', 'red'); + isTradeOnThisBar = true; + upRatio += Add_lv; + } + }else if(State == MINUS /*&& isCoverOnthisBar == false*/){ // Cover MINUS + if(P_isSetTest){ + // 模拟 + $.PlotFlag(nowTime, 'Cover_Minus', 'CM', 'circlepin', 'blue'); + State = IDLE; + exchange.Log(LOG_TYPE_SELL, test.ID++, DepthA.Bids[0].Price, test.amount, "Cover:" + P_SymbolA); + exchange.Log(LOG_TYPE_BUY, test.ID++, DepthB.Asks[0].Price, test.amount, "Cover:" + P_SymbolB); + test.ProfitDiff += DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close - test.OpenDiff; + Log("本次盈亏:" + (DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close - test.OpenDiff)); + LogProfit(test.ProfitDiff); + }else{ + // SellA_BuyB + var info = SellA_BuyB(DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close, COVER); + if(info == false){ + Log("MINUS 平仓失败!"); + return; + } + $.PlotFlag(nowTime, 'Cover_Minus', 'CM', 'circlepin', 'blue'); + isCoverOnthisBar = true; + } + } + }else if(DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close < down[down.length - 1]){ + if((State == IDLE || State == MINUS) && (DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close < (down[down.length - 1] - downRatio * distance)) /*&& isTradeOnThisBar == false*/){ + if(P_isSetTest){ + // 模拟 + $.PlotFlag(nowTime, 'minus', 'M', 'circlepin', 'green'); // DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time + State = MINUS; + exchange.Log(LOG_TYPE_BUY, test.ID++, DepthA.Asks[0].Price, test.amount, "Open:" + P_SymbolA); + exchange.Log(LOG_TYPE_SELL, test.ID++, DepthB.Bids[0].Price, test.amount, "Open:" + P_SymbolB); + test.OpenDiff = DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close; + }else{ + // BuyA_SellB + var info = BuyA_SellB(DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close, OPEN); + if(info == false){ + return; + } + $.PlotFlag(nowTime, 'minus', 'M', 'circlepin', 'green'); + isTradeOnThisBar = true; + downRatio += Add_lv; + } + }else if(State == PLUS /*&& isCoverOnthisBar == false*/){ + if(P_isSetTest){ + // 模拟 + $.PlotFlag(nowTime, 'Cover_Plus', 'CP', 'flag', 'blue'); + State = IDLE; + exchange.Log(LOG_TYPE_BUY, test.ID++, DepthA.Asks[0].Price, test.amount, "Cover:" + P_SymbolA); + exchange.Log(LOG_TYPE_SELL, test.ID++, DepthB.Bids[0].Price, test.amount, "Cover:" + P_SymbolB); + test.ProfitDiff += test.OpenDiff - DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close; + Log("本次盈亏:" + (test.OpenDiff - DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close)); + LogProfit(test.ProfitDiff); + }else{ + // BuyA_SellB + var info = BuyA_SellB(DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close, COVER); + if(info == false){ + Log("PLUS 平仓失败!"); + return; + } + $.PlotFlag(nowTime, 'Cover_Plus', 'CP', 'flag', 'blue'); + isCoverOnthisBar = true; + } + } + } + } + +} + +function main(){ + // 初始化工作 + if(isLogReset){ + LogReset(1); + } + Log("最大保证金使用量:", DealManagerData()); + ManagerData.initAccount = ManagerData.Account; + ManagerData.perAccount = ManagerData.Account; + exchange.SetMarginLevel(ManagerData.MarginLevel); // 初始设置杠杆 + + // 设置禁用汇率 + exchange.SetRate(1); + Log("已禁用汇率,显示价格为美元价格!"); + + // 创建交易控制对象 + P = $.NewPositionManager(exchange); + + //主要循环 + while(true){ + var nowTime = new Date().getTime(); + Loop(nowTime); + LogStatus("时间:", _D(nowTime), '\n', P_isSetTest ? JSON.stringify(test) : "Margin: " + ManagerData.Margin, '\n', ManagerData.ErrorStr, _D(ManagerData.ErrorTimeStamp), '\n', + ManagerData.initAccount, '\n', ManagerData.Account, '\n', ManagerData.APosition, '\n', ManagerData.BPosition, '\n', "upRatio:" + upRatio, '\n', "downRatio:" + downRatio, "distance:" + distance); + Sleep(P_Interval); + } +} diff --git "a/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" "b/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" new file mode 100644 index 00000000..08ece644 --- /dev/null +++ "b/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" @@ -0,0 +1,78 @@ +''' +策略出处: https://www.botvs.com/strategy/43965 +策略名称: Python 精简多品种 MACD 趋势策略 +策略作者: Zero +策略描述: + +需要引用小小梦公开的商品期货交易类库 + +> python版CTP商品期货交易类库(支持2/3 测试版) + +https://www.botvs.com/strategy/24288 + + +参数 默认值 描述 +------ ----- ---- +Amount 2 开仓手数 +''' + +''' +/*backtest +start: 2016-01-30 +end: 2016-12-30 +period: 1440 +periodBase: 60 +mode: 0 +*/ +''' + +class Trader: + def __init__(self, q, symbol): + self.q = q + self.symbol = symbol + self.position = 0 + self.isPending = False + + def onOpen(self, task, ret): + if ret: + self.position = ret['position']['Amount'] * (1 if (ret['position']['Type'] == PD_LONG or ret['position']['Type'] == PD_LONG_YD) else -1) + Log(task["desc"], "Position:", self.position, ret) + self.isPending = False + + def onCover(self, task, ret): + self.isPending = False + self.position = 0 + Log(task["desc"], ret) + + def onTick(self): + if self.isPending: + return + ct = exchange.SetContractType(self.symbol) + if not ct: + return + + r = exchange.GetRecords() + if not r or len(r) < 35: + return + macd = TA.MACD(r) + + diff = macd[0][-2] - macd[1][-2] + if abs(diff) > 0 and self.position == 0: + self.isPending = True + self.q.pushTask(exchange, self.symbol, ("buy" if diff > 0 else "sell"), 1, self.onOpen) + if abs(diff) > 0 and ((diff > 0 and self.position < 0) or (diff < 0 and self.position > 0)): + self.isPending = True + self.q.pushTask(exchange, self.symbol, ("closebuy" if self.position > 0 else "closesell"), 1, self.onCover) + +def main(): + q = ext.NewTaskQueue() + Log(_C(exchange.GetAccount)) + tasks = [] + for symbol in ["MA701", "rb1701"]: + tasks.append(Trader(q, symbol)) + while True: + if exchange.IO("status"): + for t in tasks: + t.onTick() + q.poll() + Sleep(1000) diff --git a/README.md b/README.md index 856d8d8d..0d9c4c89 100644 --- a/README.md +++ b/README.md @@ -4,22 +4,48 @@ > 开源策略列表 + - [JS版 商品期货 精简多品种 MACD 趋势策略框架](https://www.botvs.com/strategy/44593) + - [Python 精简多品种 MACD 趋势策略](https://www.botvs.com/strategy/43965) + - [转换任意K线周期管理模板(最近更新20170622)](https://www.botvs.com/strategy/41163) + - [TableTemplet](https://www.botvs.com/strategy/44319) + - [(13)策略框架 (Copy)](https://www.botvs.com/strategy/43579) + - [使用 BotVS 构建一个机械化策略 (Copy)](https://www.botvs.com/strategy/43422) + - [转换任意K线周期管理模板(最近更新20170531) (Copy)](https://www.botvs.com/strategy/43082) + - [OKCoin跨期布林对冲](https://www.botvs.com/strategy/43049) + - [Ma单均线趋势交易](https://www.botvs.com/strategy/42451) + - [策略001-szc](https://www.botvs.com/strategy/34216) + - [buy-hold 买入持有 (Copy)](https://www.botvs.com/strategy/42313) + - [KingKeltner趋势策略_低频 (Copy)](https://www.botvs.com/strategy/42312) + - [KingKeltner趋势策略_低频](https://www.botvs.com/strategy/42283) + - [buy-hold 买入持有](https://www.botvs.com/strategy/41786) + - [OKCoin期货跨期对冲策略](https://www.botvs.com/strategy/34878) + - [转换任意K线周期管理模板 (Copy)](https://www.botvs.com/strategy/41741) + - [使用 BotVS 构建一个机械化策略](https://www.botvs.com/strategy/40357) + - [知乎专栏 实例文章策略](https://www.botvs.com/strategy/40266) + - [BitMEX 简单测试](https://www.botvs.com/strategy/40289) + - [测试 默认 参数组功能](https://www.botvs.com/strategy/40155) + - [商品期货交易类库](https://www.botvs.com/strategy/12961) + - [测试](https://www.botvs.com/strategy/40045) + - [python版CTP商品期货交易类库(支持2/3 测试版)](https://www.botvs.com/strategy/24288) + - [商品期货查看账户详细信息](https://www.botvs.com/strategy/37793) + - [python版 画线类库 (兼容2/3)](https://www.botvs.com/strategy/39066) + - [【Demo】速度测试 websocket vs rest (复制)5560](https://www.botvs.com/strategy/8487) + - [股票证券查询买卖示例](https://www.botvs.com/strategy/5541) - [测试多图表展示](https://www.botvs.com/strategy/38203) + - [震荡突破策略 (删减B值触发平仓、动态调整触发值 优化ing) (复制)ttttttttt](https://www.botvs.com/strategy/23549) + - [CTP商品期货多品种海龟交易策略](https://www.botvs.com/strategy/17289) - [商品期货结算单平仓盈亏历史查询](https://www.botvs.com/strategy/38083) - [Convert_Record_Cycle](https://www.botvs.com/strategy/37678) - - [商品期货查看账户详细信息](https://www.botvs.com/strategy/37793) - - [商品期货交易类库](https://www.botvs.com/strategy/12961) - [均线-趋势_数字货币策略V0.2 (Copy)](https://www.botvs.com/strategy/37664) + - [数字货币交易类库 (期货支持OKCoin期货/BitVC) (复制)](https://www.botvs.com/strategy/30307) - [数字货币交易类库 (期货支持OKCoin期货/BitVC)](https://www.botvs.com/strategy/30199) - [转换任意K线周期](https://www.botvs.com/strategy/35986) - - [OKCoin期货跨期对冲策略](https://www.botvs.com/strategy/34878) - [API 测试新手入门](https://www.botvs.com/strategy/4) - [实盘账户模拟器](https://www.botvs.com/strategy/35977) - [js R-Breaker](https://www.botvs.com/strategy/36195) - [图表界面信息展示实例1](https://www.botvs.com/strategy/36026) - [移植 OKCoin 韭菜收割机](https://www.botvs.com/strategy/34388) - [R-Breaker11 交易策略](https://www.botvs.com/strategy/23874) - - [商品期货套利 - 多品种网格对冲模型](https://www.botvs.com/strategy/27799) - [比特币现货阶梯差价对冲](https://www.botvs.com/strategy/30573) - [策略框架模板](https://www.botvs.com/strategy/30861) - [画线类库](https://www.botvs.com/strategy/27293) @@ -28,9 +54,7 @@ - [国外知名策略R-Breaker (复制)](https://www.botvs.com/strategy/30512) - [范例-定时测试微信消息推送](https://www.botvs.com/strategy/15098) - [测试-布林带策略(基于策略框架)](https://www.botvs.com/strategy/28128) - - [CTP商品期货多品种海龟交易策略](https://www.botvs.com/strategy/17289) - [商品期货跨期对冲 - 单品种套利合约](https://www.botvs.com/strategy/27122) - - [python版CTP商品期货交易类库](https://www.botvs.com/strategy/24288) - [Python API 测试](https://www.botvs.com/strategy/21365) - [从第三方获取K线 (商品期货版) Rev. 161216](https://www.botvs.com/strategy/15498) - [均线策略 30 行搞定](https://www.botvs.com/strategy/12348) @@ -94,10 +118,8 @@ - [均线买卖策略](https://www.botvs.com/strategy/143) - [趋势跟踪震荡策略](https://www.botvs.com/strategy/179) - [多平台账户统计](https://www.botvs.com/strategy/7827) - - [差价监控](https://www.botvs.com/strategy/7944) - [计划委托买入](https://www.botvs.com/strategy/638) - [计划委托卖出](https://www.botvs.com/strategy/747) - - [股票证券查询买卖示例](https://www.botvs.com/strategy/5541) - [RSI指标买卖](https://www.botvs.com/strategy/31) - [阶梯下单 - 可设置触发价格](https://www.botvs.com/strategy/639) - [app价格提醒](https://www.botvs.com/strategy/4987) diff --git a/TableTemplet.js b/TableTemplet.js new file mode 100644 index 00000000..053336ee --- /dev/null +++ b/TableTemplet.js @@ -0,0 +1,140 @@ +/* +策略出处: https://www.botvs.com/strategy/44319 +策略名称: TableTemplet +策略作者: 职业养鸡户 +策略描述: + +//by 养鸡专业户 17/6/21 + +*/ + +var listener = Array(); +//----------绘制Table----------- +{ + TableButton = function(cmd,name){ + var self = {} + self.type = "button"; + self.cmd = cmd; + self.name = name; + return self; + } + + $.TableInfo = function() { + var self = {} + self.cols = []; + self.rows = []; + self.pushBtn = function(col,cmd,name,callback){ + var btn = TableButton(cmd,name) + self.cols.push(col) + self.rows.push({'type':'button','cmd':cmd,'name':name}) + listener[cmd] = callback; + } + self.push = function(col,row){ + self.cols.push(col) + self.rows.push(row) + } + return self; + } + function createTable(){ + var self = {} + self.type = "table" + self.title = "持仓信息" + self.cols = [] + self.rows = [] + + self.SetRowByTableInfo = function(index,argument) { + if(argument.cols != null) + self.cols = argument.cols; + self.rows[index] = argument.rows; + } + + self.SetRow = function (index,rowself){ + if(self.rows.length < index) + self.push("") + self.rows[index] = rowself + } + + self.SetRowCount = function(count){ + while(self.rows.length count){ + self.rows.splice(count,self.rows.length-count) + } + } + + self.GetRow = function(index){ + return self.rows[index] + } + + self.Init = function(title,cols,rows){ + self.title =title; + if(cols!=null) + self.cols = cols; + if(rows!=null){ + + for(var i =0;i < rows.length;i++){ + rows.push("r"+i) + } + } + } + return self; + } + + $.createTableMgr = function(){ + var self = {} + self.table =[] + + self.GetTable = function(index){ + if(typeof(index) === 'number'){ + return self.table[index] + }else{ + for(var i = 0;i < self.table.length;i++){ + if(self.table[i].title == index) + return self.table[i] + } + } + } + + self.AddTable = function(title,cols,rows){ + var tb = createTable(); + tb.Init(title,cols,rows); + + self.table.push(tb) + return tb; + } + self.AddListener = function(key,value){ + self.listener[key] = value; + } + self.UpdateCMD = function(){ + var cmd = GetCommand() + if (cmd) { + var cmdstr = cmd+""; + if(!!listener[cmdstr]){ + listener[cmdstr](cmdstr); + }else{ + Log("找不到名为:"+cmdstr+"的命令") + } + } + } + + self.LogStatus = function(before,end){ + self.UpdateCMD(); + LogStatus(before+'\n`' + JSON.stringify(self.table)+'`\n'+end); // 支持多个表格同时显示, 将以TAB显示到一组里 + + } + return self; + } +} + +function main(){ + var tbMgr = $.createTableMgr(); + var tb = tbMgr.AddTable("某状态栏") + var tbInfo = $.TableInfo(); + tbInfo.push("名字","张三") + tbInfo.pushBtn("按钮","按钮Cmd","这是个按钮",function(){ + Log("嘿嘿嘿"); + }) + tb.SetRowByTableInfo(0,tbInfo) + tbMgr.LogStatus("上","下") +} diff --git "a/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211 (Copy).js" "b/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211 (Copy).js" new file mode 100644 index 00000000..a58f4816 --- /dev/null +++ "b/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211 (Copy).js" @@ -0,0 +1,86 @@ +/* +策略出处: https://www.botvs.com/strategy/42313 +策略名称: buy-hold 买入持有 (Copy) +策略作者: jdm16478 +策略描述: + +买入持有策略 + +*/ + +/* +策略出处: rqalpha +策略名称: buy-hold买入持有 +策略作者: ipqhjjybj +策略描述: +无脑指数型 + +*/ + +LoopInterval = 60 // 轮询间隔(秒) +SlidePrice = 0.3 // 滑动价(元) +minMoney = 100; // 如果资金小于该数值,则不买入 + +function adjustFloat(v) { + return Math.floor(v*1000)/1000; +} + +function CancelPendingOrders() { + while (true) { + var orders = null; + while (!(orders = exchange.GetOrders())) { + Sleep(Interval); + } + + if (orders.length == 0) { + return; + } + + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]); + if (j < (orders.length-1)) { + Sleep(Interval); + } + } + } +} + +function GetAccount() { + var account; + while (!(account = exchange.GetAccount())) { + Sleep(Interval); + } + return account; +} + +function GetTicker() { + var ticker; + while (!(ticker = exchange.GetTicker())) { + Sleep(Interval); + } + return ticker; +} + +function onTick(exchange) { + var ticker = GetTicker(); + // Buy or Sell, Cancel pending orders first + CancelPendingOrders(); + var account = GetAccount(); + var price = ticker.Last + SlidePrice; + var amount = adjustFloat(account.Balance / price); + if (account.Balance > minMoney && amount >= exchange.GetMinStock()) { + if (exchange.Buy(price, amount, "做多")) { + LastBuyPrice = LastHighPrice = price; + } + } +} + +function main() { + InitAccount = GetAccount(); + Log(exchange.GetName(), exchange.GetCurrency(), InitAccount); + LoopInterval = Math.max(LoopInterval, 1); + while (true) { + onTick(exchange); + Sleep(LoopInterval*1000); + } +} diff --git "a/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.js" "b/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.js" new file mode 100644 index 00000000..72bab060 --- /dev/null +++ "b/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.js" @@ -0,0 +1,86 @@ +/* +策略出处: https://www.botvs.com/strategy/41786 +策略名称: buy-hold 买入持有 +策略作者: ipqhjjybj +策略描述: + +买入持有策略 + +*/ + +/* +策略出处: rqalpha +策略名称: buy-hold买入持有 +策略作者: ipqhjjybj +策略描述: +无脑指数型 + +*/ + +LoopInterval = 60 // 轮询间隔(秒) +SlidePrice = 0.3 // 滑动价(元) +minMoney = 100; // 如果资金小于该数值,则不买入 + +function adjustFloat(v) { + return Math.floor(v*1000)/1000; +} + +function CancelPendingOrders() { + while (true) { + var orders = null; + while (!(orders = exchange.GetOrders())) { + Sleep(Interval); + } + + if (orders.length == 0) { + return; + } + + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]); + if (j < (orders.length-1)) { + Sleep(Interval); + } + } + } +} + +function GetAccount() { + var account; + while (!(account = exchange.GetAccount())) { + Sleep(Interval); + } + return account; +} + +function GetTicker() { + var ticker; + while (!(ticker = exchange.GetTicker())) { + Sleep(Interval); + } + return ticker; +} + +function onTick(exchange) { + var ticker = GetTicker(); + // Buy or Sell, Cancel pending orders first + CancelPendingOrders(); + var account = GetAccount(); + var price = ticker.Last + SlidePrice; + var amount = adjustFloat(account.Balance / price); + if (account.Balance > minMoney && amount >= exchange.GetMinStock()) { + if (exchange.Buy(price, amount, "做多")) { + LastBuyPrice = LastHighPrice = price; + } + } +} + +function main() { + InitAccount = GetAccount(); + Log(exchange.GetName(), exchange.GetCurrency(), InitAccount); + LoopInterval = Math.max(LoopInterval, 1); + while (true) { + onTick(exchange); + Sleep(LoopInterval*1000); + } +} diff --git "a/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" "b/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" new file mode 100644 index 00000000..86575cc2 --- /dev/null +++ "b/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" @@ -0,0 +1,238 @@ +''' +策略出处: https://www.botvs.com/strategy/39066 +策略名称: python版 画线类库 (兼容2-3) +策略作者: 小小梦 +策略描述: + +简化了策略图表画线的逻辑, 可以直接调用封装好的函数 + +* 支持画多条线 +* 支持K线图 +* 支持flag小图标 +* 你也可以添加更多图形的支持 + +功能等同JS 版 + +移植于JS版 画线类库 +### 如有问题请联系 小小梦 359706687 + +''' + +# Python 2/3 兼容版本 +import time +chart = None +series = [] +labelIdx = {} +preBarTime = 0 +preFlagTime = 0 +preDotTime = {} + +cfg = { + "tooltip" : { + "xDateFormat" : "%Y-%m-%d %H:%M:%S, %A" + }, + "legend" : { + "enabled" : True + }, + "plotOptions" : { + "candlestick" : { + "color" : "#d75442", + "upColor" : "#6ba583" + } + }, + "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" : 2, + "inputEnabled" : True + }, + "series" : series, +} + +def GetCfg(): + global cfg + return cfg + +# 画水平线 +def PlotHLine(value = None, label = None, color = None, style = None): + global cfg, chart + if ("yAxis" in cfg) == False : + cfg.setdefault("yAxis", {"plotLines" : []}) + elif ("plotLines" in cfg["yAxis"]) == False : + cfg["yAxis"].setdefault("plotLines", []) + + obj = { + "value" : value, + "color" : color or "red", + "width" : 2, + "dashStyle" : style or "Solid", + "label" : { + "text" : label or "", + "align" : "center" + } + } + found = False + for i in range(len(cfg["yAxis"]["plotLines"])) : + if cfg["yAxis"]["plotLines"][i]["label"]["text"] == label : + cfg["yAxis"]["plotLines"][i] = obj + found = True + if not found : + cfg["yAxis"]["plotLines"].append(obj) + if not chart : + chart = Chart(cfg) + else : + chart.update(cfg) + +# 画K线 +def PlotRecords(records, title = None): + global labelIdx, series, preBarTime, chart + if not chart : + chart = Chart(cfg) + if ("candlestick" in labelIdx) == False : + cfg["__isStock"] = True + seriesIdx = len(series) + series.append({ + "type" : "candlestick", + "name" : "" if title == None else title, + "id" : "primary", + "data" : [] + }) + chart.update(cfg) + labelIdx.setdefault("candlestick", seriesIdx) + else : + seriesIdx = labelIdx["candlestick"] + if isinstance(records, dict) and ("Time" in records) == True : + Bar = records + if Bar["Time"] == preBarTime : + chart.add(seriesIdx, [Bar["Time"], Bar["Open"], Bar["High"], Bar["Low"], Bar["Close"]], -1) + elif Bar["Time"] > preBarTime : + preBarTime = Bar.Time + chart.add(seriesIdx, [Bar["Time"], Bar["Open"], Bar["High"], Bar["Low"], Bar["Close"]]) + else : + for i in range(len(records)) : + if records[i]["Time"] == preBarTime : + chart.add(seriesIdx, [records[i]["Time"], records[i]["Open"], records[i]["High"], records[i]["Low"], records[i]["Close"]], -1) + elif records[i]["Time"] > preBarTime : + preBarTime = records[i]["Time"] + chart.add(seriesIdx, [records[i]["Time"], records[i]["Open"], records[i]["High"], records[i]["Low"], records[i]["Close"]]) + return chart + +# 画指标线 +def PlotLine(label, dot, Ntime = None): + global labelIdx, chart, series, preDotTime + if not chart : + cfg.setdefault("xAxis", { + "type" : "datetime" + }) + chart = Chart(cfg) + if (label in labelIdx) == False : + seriesIdx = len(series) + preDotTime.setdefault(str(seriesIdx), 0) + labelIdx[label] = seriesIdx + series.append({ + "type" : "line", + "yAxis" : 0, + "showInLegend" : True, + "name" : label, + "data" : [], + "tooltip" : {"valueDecimals" : 5} + }) + chart.update(cfg) + else : + seriesIdx = labelIdx[label] + if Ntime == None : + Ntime = _N(time.time() * 1000, 0) + if preDotTime[str(seriesIdx)] != Ntime : + preDotTime[str(seriesIdx)] = Ntime + chart.add(seriesIdx, [Ntime, dot]) + else : + chart.add(seriesIdx, [Ntime, dot], -1) + return chart + +# 画标记 +def PlotFlag(time, text, title, shape = "", color = ""): + global chart, cfg, labelIdx, preFlagTime + if not chart : + chart = Chart(cfg) + label = "flag" + if (label in labelIdx) == False : + seriesIdx = len(series) + labelIdx[label] = seriesIdx + series.append({ + "type" : "flags", + "onSeries" : "primary", + "data" : [] + }) + chart.update(cfg) + else : + seriesIdx = labelIdx[label] + obj = { + "x" : time, + "color" : color, + "shape" : shape, + "title" : title, + "text" : text + } + if preFlagTime != time : + preFlagTime = time + chart.add(seriesIdx, obj) + else : + chart.add(seriesIdx, obj, -1) + return chart + +# 设置图表标题 +def PlotTitle(title, chartTitle = None): + global cfg + if ("subtitle" in cfg) == True : + cfg["subtitle"] = {"text" : title} + else : + cfg.setdefault("subtitle", {"text" : title}) + if chartTitle != None : + if (title in cfg) == True : + cfg["title"] = {"text" : chartTitle} + else : + cfg.setdefault("title", {"text" : chartTitle}) + if chart : + chart.update(cfg) + +# 导出函数 +ext.GetCfg = GetCfg +ext.PlotHLine = PlotHLine +ext.PlotRecords = PlotRecords +ext.PlotLine = PlotLine +ext.PlotFlag = PlotFlag +ext.PlotTitle = PlotTitle + +# 测试代码 +def main(): + isFirst = True + while True: + records = exchange.GetRecords() + if records and len(records) > 0 : + ext.PlotRecords(records, "BTC") + if isFirst : + ext.PlotFlag(records[-1]["Time"], "Start", "S") + isFirst = False + ext.PlotHLine(records[-1]["Close"], "Close") + ticker = exchange.GetTicker() + if ticker : + ext.PlotLine("Last", ticker.Last) + ext.PlotLine("buy", ticker.Buy + 10) + ext.PlotTitle("Last" + str(ticker.Last)) + Sleep(60000) + + diff --git "a/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.py" "b/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" similarity index 93% rename from "python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.py" rename to "python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" index e274fa00..dd3bd261 100644 --- "a/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.py" +++ "b/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" @@ -1,10 +1,12 @@ ''' 策略出处: https://www.botvs.com/strategy/24288 -策略名称: python版CTP商品期货交易类库 +策略名称: python版CTP商品期货交易类库(支持2-3 测试版) 策略作者: 小小梦 策略描述: python版CTP商品期货交易类库 +测试版 如有BUG 欢迎提出,作者QQ : 359706687 小小梦 +1、2017.4.25 更新:增加 if (insDetail.MaxLimitOrderVolume == 0) 条件判断,有些期货公司服务器 会返回0 值,特此处理。共修改3处 【1】self.pollTask 【2】function Cover 【3】function Open 参数 默认值 描述 @@ -16,11 +18,12 @@ import json # json 模块 import types # 类型 模块 import platform # 版本信息 +import traceback # 用于异常处理 # str() : ASCII and UTF-8 -import sys import time -reload(sys) -sys.setdefaultencoding('utf8') +# import sys +# reload(sys) +# sys.setdefaultencoding('utf8') versionMainValue = None # 记录python 版本信息 isFirstCheck = True # 记录 是否是第一次检查 @@ -32,6 +35,10 @@ def CheckVersion(): # 检查python 版本 if platformInfo[0] == '2': Log("您使用的托管者 python编译环境的python版本是",platformInfo) versionMainValue = 2 + import sys + reload(sys) + sys.setdefaultencoding('utf8') + Log("import sys, reload(sys), sys.setdefaultencoding('utf8')") elif platformInfo[0] == '3': Log("您使用的托管者 python编译环境的python版本是",platformInfo) versionMainValue = 3 @@ -114,6 +121,10 @@ def Open(e, contractType, direction, opAmount): if positionNow: needOpen = opAmount - (positionNow['Amount'] - initAmount) insDetail = _C(e.SetContractType, contractType) + # if (insDetail.MaxLimitOrderVolume == 0) + if insDetail["MaxLimitOrderVolume"] == 0: + # insDetail.MaxLimitOrderVolume = 50 + insDetail["MaxLimitOrderVolume"] = 50 if needOpen < insDetail['MinLimitOrderVolume']: break depth = _C(e.GetDepth) @@ -151,6 +162,10 @@ def Open(e, contractType, direction, opAmount): def Cover(e, contractType): insDetail = _C(e.SetContractType, contractType) + # if (insDetail.MaxLimitOrderVolume == 0) + if insDetail["MaxLimitOrderVolume"] == 0: + # insDetail.MaxLimitOrderVolume = 50 + insDetail["MaxLimitOrderVolume"] = 50 while True: n = 0 positions = _C(e.GetPosition) @@ -245,13 +260,12 @@ def AccountToTable(Str, title = '账户的信息'): desc = '--' else: desc = trans[k] - # Log(k not in trans) # ceshi v = fields[k] if type(v) == typeOfstr('int') or type(v) == typeOfstr('float'): v = _N(v, 5) tbl['rows'].append([k, desc, v]) - except BaseException, e: - Log("异常信息:", e) + except: + Log(traceback.format_exc()) return tbl # NewTaskQueue 类 @@ -308,7 +322,6 @@ def pushTask(self, e, symbol, action, amount, onFinish): def cancelAll(self, e): while True: orders = e.GetOrders() - # Log("orders:", orders) # ceshi if orders is None: return self.ERR_GET_ORDERS if len(orders) == 0: @@ -322,12 +335,14 @@ def pollTask(self, task): insDetail = task["e"].SetContractType(task["symbol"]) if insDetail is None: return self.ERR_SET_SYMBOL + # if (insDetail.MaxLimitOrderVolume == 0) + if insDetail["MaxLimitOrderVolume"] == 0: + # insDetail.MaxLimitOrderVolume = 50 + insDetail["MaxLimitOrderVolume"] = 50 ret = False isCover = (task["action"] != "buy") and (task["action"] != "sell") while True: if not ext.IsTrading(task["symbol"]): - # Log(ext.IsTrading(task["symbol"]), task["symbol"], ext.IsTrading("MA701")) # ceshi - # raise Exception("stop") # ceshi return self.ERR_NOT_TRADEING Sleep(500) ret = self.cancelAll(task["e"]) @@ -432,11 +447,9 @@ def poll(self): if not task["finished"] : processed += 1 self.pollTask(task) - # LogStatus("jieguo:", jieguo) # ceshi if processed == 0: self.tasks = [] - # Log("AA") # ceshi def size(self): return len(self.tasks) @@ -534,7 +547,7 @@ def IsTrading(symbol): hour = tup_localtime.tm_hour # tm_hour : 0~23 minute = tup_localtime.tm_min # tm_min : 0~59 - if (day == 0 or (day == 6 and (hour > 2 or hour == 2 and minute > 30))): + if (day == 6 or (day == 5 and (hour > 2 or hour == 2 and minute > 30))): return False shortName = "" # i , p @@ -561,7 +574,7 @@ def IsTrading(symbol): [13, 0, 15, 15] ] - if day >= 1 and day <= 5: + if day >= 0 and day <= 4: for i in range(len(period)): p = period[i] if ((hour > p[0] or (hour == p[0] and minute >= p[1])) and (hour < p[2] or (hour == p[2] and minute < p[3]))): @@ -570,11 +583,11 @@ def IsTrading(symbol): nperiod = [ [ ['AU', 'AG'], - [21, 0, 02, 30] + [21, 0, 2, 30] # 此处修改为 2 ], [ ['CU', 'AL', 'ZN', 'PB', 'SN', 'NI'], - [21, 0, 01, 0] + [21, 0, 1, 0] # 此处修改为 1 ], [ ['RU', 'RB', 'HC', 'BU'], @@ -598,10 +611,10 @@ def IsTrading(symbol): condB = hour < p[2] or (hour == p[2] and minute < p[3]) # in one day if p[2] >= p[0]: - if ((day >= 1 and day <= 5) and condA and condB): + if ((day >= 0 and day <= 4) and condA and condB): return True else: - if (((day >= 1 and day <= 5) and condA) or ((day >= 2 and day <= 6) and condB)): + if (((day >= 0 and day <= 4) and condA) or ((day >= 1 and day <= 5) and condB)): return True return False return False @@ -708,15 +721,7 @@ def NoName1(task, ret): Log("q.tasks`s length :", q.size()) - # count = 0 # ceshi while True: q.poll() - # LogStatus("q.tasks`s length :", q.size()) - # count += 1 # ceshi - # if count > 10: - # break - Sleep(1000) - - diff --git "a/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest (\345\244\215\345\210\266)5560.js" "b/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest (\345\244\215\345\210\266)5560.js" new file mode 100644 index 00000000..a4c9259f --- /dev/null +++ "b/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest (\345\244\215\345\210\266)5560.js" @@ -0,0 +1,134 @@ +/* +策略出处: https://www.botvs.com/strategy/8487 +策略名称: 【Demo】速度测试 websocket vs rest (复制)5560 +策略作者: 总值约: 23938.37 元 +策略描述: + +websocket 测试,支持添加多个交易所测试,注意会短时增加你的api调用频率,请在确保不影响其他机器人运行的情况下运行。如果出现”Futures_OP 4: argument error“的错误,请更新到最新的托管者程序 + +*/ + + + +var Interval=1000; + +function _N(v, precision) { + + + + if (typeof (precision) != 'number') { + + + + precision = 4; + + + + } + + + + var d = parseFloat(v.toFixed(Math.max(10, precision + 5))); + + + + s = d.toString().split("."); + + + + if (s.length < 2 || s[1].length <= precision) { + + + + return d; + + + + } + + + var b = Math.pow(10, precision); + + + + return Math.floor(d * b) / b; + + + +} + + + + +function onexit() { + + Log("【【【系统退出】】】"); +} + + +function main() { + + + + var start=Date.now(); + + + + for (var i = 0; i < exchanges.length; i++) { + + + var ecg=exchanges[i]; + //Log(ecg); + + ecg.IO("rest");//rest 模式 + var iii=0; + var sum=0; + while (iii<=10) { //连续调用10次,取平均值 + + var account = null; + start=Date.now(); + account = ecg.GetAccount(); //测试执行的API函数,可根据需要自己修改,如 GetTick + iii=iii+1; + if(account){ + var delay=(Date.now()-start); + sum=sum+delay; + + } + + + + + Sleep(1000); + + } + Log("平均毫秒数【"+_N(sum/iii,2)+"】"+ecg.GetName()+" rest"); + + ecg.IO("websocket"); //websocket 模式 + sum=0; + iii=0; + while (iii<=10) { //连续调用10次,取平均值 + + var account = null; + start=Date.now(); + account = ecg.GetAccount(); //测试执行的API函数,可根据需要自己修改,如 GetTick + iii=iii+1; + if(account){ + var delay=(Date.now()-start); + sum=sum+delay; + + } + + + + + Sleep(1000); + + } + Log("平均毫秒数【"+_N(sum/iii,2)+"】"+ecg.GetName()+" websocket"); + } +} + + + + + diff --git "a/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245 (Copy).js" "b/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245 (Copy).js" new file mode 100644 index 00000000..519bcbf7 --- /dev/null +++ "b/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245 (Copy).js" @@ -0,0 +1,142 @@ +/* +策略出处: https://www.botvs.com/strategy/43422 +策略名称: 使用 BotVS 构建一个机械化策略 (Copy) +策略作者: zhangdeli +策略描述: + +知乎专栏文章 附带策略 +使用 BotVS 构建一个机械化策略 + +*/ + +// 参数 +var ContractType = "rb1710"; +var PointAmount = 1; +var NetSize = 30; +var Interval = 500; +var SumPoints = 10; +var CoverRatio = 2; + +// 全局变量 +var Controller = { + symbol : null, + Amount : 0, + Size : 0, + BeginPrice : 0, + SumPoints : 0, + CoverRatio : 0, + Net_Long : [], + Net_Short : [], + ContractInfo : null, + isUpdateNetShow : false, // 是否要更新显示 +}; +var perBar = null; + +function loop(){ + var records = exchange.GetRecords(); + var ticker = exchange.GetTicker(); + if(!records || records.length == 0 || !ticker){ + return; + } + + if(records[records.length - 1].Time !== perBar.Time){ // 新 Bar 产生 + UpdateNet(ticker.Last); + perBar = records[records.length - 1]; + } + + // 画线 + $.PlotRecords(records, 'K线'); + + for(var i = 0; (i < Controller.Net_Long.length && Controller.isUpdateNetShow == true); i++){ // 更新显示 + $.PlotHLine(Controller.Net_Long[i].open, 'long' + i); + if(i == Controller.Net_Long.length - 1){ + for(var j = 0; j < Controller.Net_Short.length; j++){ + $.PlotHLine(Controller.Net_Short[j].open, 'short' + j, "green"); + } + $.PlotHLine(Controller.BeginPrice, 'begin', "black", "dash"); // 初始线 + Controller.isUpdateNetShow = false; + Log("更新显示!"); // ceshi + } + } + // throw "stop"; // ceshi + // Log(Controller.Net_Long); // cehsi +} + +function init(){ + Controller.symbol = ContractType; + Controller.Amount = PointAmount; + Controller.Size = NetSize; + Controller.SumPoints = SumPoints; + Controller.CoverRatio = 2; + + // 设置合约 + while(exchange.IO("status") == false || Controller.ContractInfo == null){ + Controller.ContractInfo = exchange.SetContractType(Controller.symbol); + LogStatus("时间:", new Date(), "等待连接服务器初始化。"); + Sleep(Interval); + } + + var ticker = _C(exchange.GetTicker); + var records = _C(exchange.GetRecords); + perBar = records[records.length - 1]; + // 初始更新网格 + UpdateNet(ticker.Last); +} + +function UpdateNet(price){ + // 校验网格是否没有持仓 + for(var n = 0; n < Controller.Net_Long.length; n++){ + if(Controller.Net_Long[n].hold !== 0){ + Log("Net_Long 网格仍有持仓!无法更新。"); + return false; + } + } + + for(var m = 0; m < Controller.Net_Short.length; m++){ + if(Controller.Net_Short[m].hold !== 0){ + Log("Net_Short 网格仍有持仓!无法更新。"); + return false; + } + } + + Controller.isUpdateNetShow = true; + + Controller.Net_Long = []; + Controller.Net_Short = []; + Controller.BeginPrice = price; + for(var i = 0; i < Controller.SumPoints; i++){ + var Long_point = { + open : _N(Controller.BeginPrice + (i + 1) * Controller.Size, 0), + cover : _N(Controller.BeginPrice + (i + 1) * Controller.Size + Controller.CoverRatio * Controller.Size, 0), + hold : 0, + } + Controller.Net_Long.push(Long_point); + } + for(var j = 0; j < Controller.SumPoints; j++){ + var Short_point = { + open : _N(Controller.BeginPrice - (j + 1) * Controller.Size, 0), + cover : _N(Controller.BeginPrice - (j + 1) * Controller.Size + Controller.CoverRatio * Controller.Size, 0), + hold : 0, + } + Controller.Net_Short.push(Short_point); + } +} + +function main(){ + // 入口函数初始化 + + // 主循环, 程序完成初始化后在此 循环执行,直到手动关闭。 + var LoginState = null; + var nowTimeStamp = 0; + while(true){ + nowTimeStamp = new Date().getTime(); + if(exchange.IO("status") == true){ + LoginState = true; + loop(); + }else{ + LoginState = false; + } + LogStatus("时间:", _D(nowTimeStamp), LoginState ? "已连接服务器" : "未连接服务器!"/*, 待显示的一些信息可以写在此处,如账户信息,实时行情,程序状态*/) + Sleep(Interval); // 暂停 0.5 秒, 避免轮询频率过高,访问交易所服务器过于频繁导致问题。 + } +} diff --git "a/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.js" "b/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.js" new file mode 100644 index 00000000..87293a1d --- /dev/null +++ "b/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.js" @@ -0,0 +1,142 @@ +/* +策略出处: https://www.botvs.com/strategy/40357 +策略名称: 使用 BotVS 构建一个机械化策略 +策略作者: 小小梦 +策略描述: + +知乎专栏文章 附带策略 +使用 BotVS 构建一个机械化策略 + +*/ + +// 参数 +var ContractType = "rb1710"; +var PointAmount = 1; +var NetSize = 30; +var Interval = 500; +var SumPoints = 10; +var CoverRatio = 2; + +// 全局变量 +var Controller = { + symbol : null, + Amount : 0, + Size : 0, + BeginPrice : 0, + SumPoints : 0, + CoverRatio : 0, + Net_Long : [], + Net_Short : [], + ContractInfo : null, + isUpdateNetShow : false, // 是否要更新显示 +}; +var perBar = null; + +function loop(){ + var records = exchange.GetRecords(); + var ticker = exchange.GetTicker(); + if(!records || records.length == 0 || !ticker){ + return; + } + + if(records[records.length - 1].Time !== perBar.Time){ // 新 Bar 产生 + UpdateNet(ticker.Last); + perBar = records[records.length - 1]; + } + + // 画线 + $.PlotRecords(records, 'K线'); + + for(var i = 0; (i < Controller.Net_Long.length && Controller.isUpdateNetShow == true); i++){ // 更新显示 + $.PlotHLine(Controller.Net_Long[i].open, 'long' + i); + if(i == Controller.Net_Long.length - 1){ + for(var j = 0; j < Controller.Net_Short.length; j++){ + $.PlotHLine(Controller.Net_Short[j].open, 'short' + j, "green"); + } + $.PlotHLine(Controller.BeginPrice, 'begin', "black", "dash"); // 初始线 + Controller.isUpdateNetShow = false; + Log("更新显示!"); // ceshi + } + } + // throw "stop"; // ceshi + // Log(Controller.Net_Long); // cehsi +} + +function init(){ + Controller.symbol = ContractType; + Controller.Amount = PointAmount; + Controller.Size = NetSize; + Controller.SumPoints = SumPoints; + Controller.CoverRatio = 2; + + // 设置合约 + while(exchange.IO("status") == false || Controller.ContractInfo == null){ + Controller.ContractInfo = exchange.SetContractType(Controller.symbol); + LogStatus("时间:", new Date(), "等待连接服务器初始化。"); + Sleep(Interval); + } + + var ticker = _C(exchange.GetTicker); + var records = _C(exchange.GetRecords); + perBar = records[records.length - 1]; + // 初始更新网格 + UpdateNet(ticker.Last); +} + +function UpdateNet(price){ + // 校验网格是否没有持仓 + for(var n = 0; n < Controller.Net_Long.length; n++){ + if(Controller.Net_Long[n].hold !== 0){ + Log("Net_Long 网格仍有持仓!无法更新。"); + return false; + } + } + + for(var m = 0; m < Controller.Net_Short.length; m++){ + if(Controller.Net_Short[m].hold !== 0){ + Log("Net_Short 网格仍有持仓!无法更新。"); + return false; + } + } + + Controller.isUpdateNetShow = true; + + Controller.Net_Long = []; + Controller.Net_Short = []; + Controller.BeginPrice = price; + for(var i = 0; i < Controller.SumPoints; i++){ + var Long_point = { + open : _N(Controller.BeginPrice + (i + 1) * Controller.Size, 0), + cover : _N(Controller.BeginPrice + (i + 1) * Controller.Size + Controller.CoverRatio * Controller.Size, 0), + hold : 0, + } + Controller.Net_Long.push(Long_point); + } + for(var j = 0; j < Controller.SumPoints; j++){ + var Short_point = { + open : _N(Controller.BeginPrice - (j + 1) * Controller.Size, 0), + cover : _N(Controller.BeginPrice - (j + 1) * Controller.Size + Controller.CoverRatio * Controller.Size, 0), + hold : 0, + } + Controller.Net_Short.push(Short_point); + } +} + +function main(){ + // 入口函数初始化 + + // 主循环, 程序完成初始化后在此 循环执行,直到手动关闭。 + var LoginState = null; + var nowTimeStamp = 0; + while(true){ + nowTimeStamp = new Date().getTime(); + if(exchange.IO("status") == true){ + LoginState = true; + loop(); + }else{ + LoginState = false; + } + LogStatus("时间:", _D(nowTimeStamp), LoginState ? "已连接服务器" : "未连接服务器!"/*, 待显示的一些信息可以写在此处,如账户信息,实时行情,程序状态*/) + Sleep(Interval); // 暂停 0.5 秒, 避免轮询频率过高,访问交易所服务器过于频繁导致问题。 + } +} diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" index 77808d30..8a48d650 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" @@ -128,6 +128,9 @@ function Open(e, contractType, direction, opAmount) { } } var insDetail = _C(e.SetContractType, contractType); + if (insDetail.MaxLimitOrderVolume == 0) { + insDetail.MaxLimitOrderVolume = 50 + } //Log("初始持仓", initAmount, "当前持仓", positionNow, "需要加仓", needOpen); if (needOpen < insDetail.MinLimitOrderVolume) { break; @@ -179,6 +182,9 @@ function Open(e, contractType, direction, opAmount) { function Cover(e, contractType) { var insDetail = _C(e.SetContractType, contractType); + if (insDetail.MaxLimitOrderVolume == 0) { + insDetail.MaxLimitOrderVolume = 50 + } while (true) { var n = 0; var opAmount = 0; @@ -367,12 +373,14 @@ var PositionManager = (function() { for (var i = 0; i < positions.length; i++) { // Cover Hedge Position First if (positions[i].ContractType.indexOf('&') != -1) { + Log("开始平掉", positions[i]); Cover(this.e, positions[i].ContractType) Sleep(1000) } } for (var i = 0; i < positions.length; i++) { if (positions[i].ContractType.indexOf('&') == -1) { + Log("开始平掉", positions[i]); Cover(this.e, positions[i].ContractType) Sleep(1000) } @@ -558,6 +566,9 @@ $.NewTaskQueue = function(onTaskFinish) { if (!insDetail) { return self.ERR_SET_SYMBOL; } + if (insDetail.MaxLimitOrderVolume == 0) { + insDetail.MaxLimitOrderVolume = 50 + } var ret = null; var isCover = task.action != "buy" && task.action != "sell"; do { diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\345\245\227\345\210\251 - \345\244\232\345\223\201\347\247\215\347\275\221\346\240\274\345\257\271\345\206\262\346\250\241\345\236\213.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\345\245\227\345\210\251 - \345\244\232\345\223\201\347\247\215\347\275\221\346\240\274\345\257\271\345\206\262\346\250\241\345\236\213.js" deleted file mode 100644 index c2f1962c..00000000 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\345\245\227\345\210\251 - \345\244\232\345\223\201\347\247\215\347\275\221\346\240\274\345\257\271\345\206\262\346\250\241\345\236\213.js" +++ /dev/null @@ -1,234 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/27799 -策略名称: 商品期货套利 - 多品种网格对冲模型 -策略作者: Zero -策略描述: - -商品期货对冲 + 网格 - -传统的跨期对冲一般指统计套利, 用线性回归或者其它办法生成一个套利区间, 这样套利机会比较少, 而且有预测性, 未来价差很可能不是预计的那样回归 - -为了解决这种办法, 进而更频繁的进行套利操作, 我们把两个关联品种或者跨期品种的套利价差定义成一个网格, 每满足一定的价差就开一次仓, 做一次对冲 - -这样价差来回在我们设置的网格里进行波动,我们就能不断的开仓平仓实现盈利. - -不善文案, 不做文字表达了, 具体看策略代码 - - -参数 默认值 描述 ------------ -------------------------------------------------------------------------------------- ----------- -HedgeTable (MA705&MA709)30:15:1;40:25:1;50:35:1;60:45:1(FG705&FG709)10:0:1;15:5:1;20:10:1;25:15:1 开仓表 -CoverAll false 启动时平掉所有仓位 -CalcPeriod 60 账户权益统计周期(分) -AutoRestore false 自动恢复 -*/ - -function Hedge(q, e, positions, symbolA, symbolB, hedgeSpread) { - var self = {} - self.q = q - self.symbolA = symbolA - self.symbolB = symbolB - self.name = symbolA + " & " + symbolB - self.e = e - self.isBusy = false - self.diffA = 0 - self.diffB = 0 - self.update = _D() - var arr = hedgeSpread.split(';') - self.dic = [] - var n = 0 - var coefficient = 1 - for (var i = 0; i < positions.length; i++) { - if (positions[i].ContractType == symbolA) { - n += positions[i].Amount - if (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) { - coefficient = -1 - } - } - } - _.each(arr, function(pair) { - var tmp = pair.split(':'); - if (tmp.length != 3) { - throw "开仓表不正确"; - } - var st = { - open: Number(tmp[0]), - cover: Number(tmp[1]), - amount: Number(tmp[2]), - hold: 0 - } - if (n > 0) { - var m = Math.min(n, st.amount) - n -= m - st.hold = m * coefficient - Log("恢复", self.name, st) - } - self.dic.push(st) - }); - if (n > 0) { - throw "恢复失败, 有多余仓位 " + n; - } - - self.poll = function() { - if (self.isBusy || (!$.IsTrading(self.symbolA))) { - return - } - var insDetailA = exchange.SetContractType(self.symbolA) - if (!insDetailA) { - return - } - var tickerA = exchange.GetTicker() - if (!tickerA) { - return - } - var insDetailB = exchange.SetContractType(self.symbolB) - if (!insDetailB) { - return - } - var tickerB = exchange.GetTicker() - if (!tickerB) { - return - } - - self.update = _D(tickerA.Time) - - var action = null - var diffA = _N(tickerA.Buy - tickerB.Sell) - var diffB = _N(tickerA.Sell - tickerB.Buy) - self.diffA = diffA - self.diffB = diffB - - for (var i = 0; i < self.dic.length && !action; i++) { - if (self.dic[i].hold == 0) { - if (self.dic[i].open <= diffA) { - action = [i, "sell", "buy", self.dic[i].amount] - } else if (self.dic[i].open <= -diffB) { - action = [i, "buy", "sell", -self.dic[i].amount] - } - } else { - if (self.dic[i].hold > 0 && self.dic[i].cover >= diffB) { - action = [i, "closesell", "closebuy", self.dic[i].hold] - } else if (self.dic[i].hold < 0 && self.dic[i].cover >= -diffA) { - action = [i, "closebuy", "closesell", self.dic[i].hold] - } - } - } - - if (!action) { - return - } - - Log("A卖B买: " + _N(diffA) + ", A买B卖: " + _N(diffB), ", Action: " + JSON.stringify(action)) - - self.isBusy = true - - self.q.pushTask(self.e, self.symbolA, action[1], self.dic[action[0]].amount, function(task, ret) { - if (!ret) { - self.isBusy = false - return - } - self.q.pushTask(self.e, self.symbolB, action[2], self.dic[action[0]].amount, function(task, ret) { - if (!ret) { - throw "开仓失败..." - } - self.isBusy = false - if (task.action != "buy" && task.action != "sell") { - self.dic[action[0]].hold = 0; - } else { - self.dic[action[0]].hold = action[3]; - } - }) - }) - } - return self -} - - -function main() { - SetErrorFilter("ready|login|timeout") - Log("正在与交易服务器连接...") - while (!exchange.IO("status")) Sleep(1000); - Log("与交易服务器连接成功") - var mode = exchange.IO("mode", 0); - if (typeof(mode) !== 'number') { - throw "切换模式失败, 请更新到最新托管者!"; - } else { - Log("已切换到适合多品种价格查询的立即模式"); - } - - if (CoverAll) { - Log("开始平掉所有残余仓位..."); - $.NewPositionManager().CoverAll(); - Log("操作完成"); - } - LogStatus("尝试获取持仓状态") - var positions = _C(exchange.GetPosition) - LogStatus("Ready") - - if (positions.length > 0 && !AutoRestore) { - throw "发现持仓, 请勾选自动恢复" - } - - var pairs = [] - var q = $.NewTaskQueue(function(task, ret) { - Log(task.desc, ret ? "成功" : "失败") - }) - var arr = HedgeTable.split('('); - var tbl = { - type: 'table', - title: 'Runtime', - cols: ['Pair', 'Open', 'Cover', 'Hold', 'DiffA', 'DiffB', 'Time'], - rows: [] - }; - _.each(arr, function(item) { - if (item != '') { - var tmp = item.split(')'); - var pair = tmp[0].replace('(', '').split('&'); - var symbolDetail = _C(exchange.SetContractType, pair[0]) - Log("合约", symbolDetail.InstrumentName, "一手", symbolDetail.VolumeMultiple, "份, 最大下单量", symbolDetail.MaxLimitOrderVolume, "保证金率:", _N(symbolDetail.LongMarginRatio), _N(symbolDetail.ShortMarginRatio), "交割日期", symbolDetail.StartDelivDate); - symbolDetail = _C(exchange.SetContractType, pair[1]) - Log("合约", symbolDetail.InstrumentName, "一手", symbolDetail.VolumeMultiple, "份, 最大下单量", symbolDetail.MaxLimitOrderVolume, "保证金率:", _N(symbolDetail.LongMarginRatio), _N(symbolDetail.ShortMarginRatio), "交割日期", symbolDetail.StartDelivDate); - pairs.push(Hedge(q, exchanges[0], positions, pair[0], pair[1], tmp[1])) - } - }); - - var ts = 0 - var lastUpdate = 0 - while (true) { - if (!exchange.IO("status")) { - Sleep(1000) - continue - } - - var now = new Date().getTime() - if (now - ts > (CalcPeriod * 60000)) { - var account = exchange.GetAccount() - if (account) { - var obj = JSON.parse(exchange.GetRawJSON()) - $.PlotLine('账户权益', obj['Balance'] + obj['PositionProfit']); - ts = now - } - } - // IO("wait") 会一直等待收到任何一个品种的行情推送信息, 返回收到行情的真实时间 - var n = exchange.IO("wait") - // 计算行情信息传到策略层花费的时间 - var idle = UnixNano() - n - - if (now - lastUpdate > 5000) { - tbl.rows = [] - _.each(pairs, function(t) { - for (var i = 0; i < t.dic.length; i++) { - tbl.rows.push([t.name, t.dic[i].open, t.dic[i].cover, t.dic[i].hold, t.diffA, t.diffB, t.update]) - } - }); - LogStatus('`' + JSON.stringify(tbl) + '`\nUpdate: ' + _D() + ', Idle: ' + (idle/1000000) + ' ms') - lastUpdate = now - } - - _.each(pairs, function(t) { - t.poll() - }); - - q.poll() - } -} diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.js" index e5640b12..e7a6f799 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.js" @@ -90,5 +90,9 @@ function main() { var raw = exchange.GetRawJSON() LogStatus('`' + JSON.stringify(AccountToTable(raw))+'`') Log(raw) - Log("已经在状态栏以表格形式显示") + var obj = JSON.parse(raw) + //var rights = _N(obj['Balance'] + obj['PositionProfit']); + var rights = _N(obj['PositionProfit'] + obj['CurrMargin'] + obj['Available']); + Log("已经在状态栏以表格形式显示", rights) + } diff --git "a/\345\267\256\344\273\267\347\233\221\346\216\247.js" "b/\345\267\256\344\273\267\347\233\221\346\216\247.js" index 3add96f8..6ff472ce 100644 --- "a/\345\267\256\344\273\267\347\233\221\346\216\247.js" +++ "b/\345\267\256\344\273\267\347\233\221\346\216\247.js" @@ -1,7 +1,7 @@ /* -策略出处: https://www.botvs.com/strategy/7944 +策略出处: https://www.botvs.com/strategy/1340 策略名称: 差价监控 -策略作者: 折腾中 +策略作者: Zero 策略描述: 只支持两个交易所, 可自定义差价的类型, 支持2.77托管者的自定义图表功能 @@ -17,6 +17,10 @@ EnableCR false 自定义汇率 USDCNY false USDCNY NormalDiff 0.1 普通差价 HighDiff 0.3 较高差价 + +按钮 默认值 描述 +---- ---------- ---- +重置数据 __button__ @ */ @@ -24,6 +28,51 @@ var __lastDiff = 0; var __AType = ["Last", "Buy", "Sell"][AType]; var __BType = ["Last", "Buy", "Sell"][BType]; +var cfg = { + tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'}, + title : { text : '差价分析图'}, + 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 + }, + xAxis: { type: 'datetime'}, + yAxis : { + plotLines : [{ + value : 0.0, + color : 'black', + dashStyle : 'shortdash', + width : 3, + }, { + value : NormalDiff, + color : 'green', + dashStyle : 'shortdash', + width : 1, + }, { + value : HighDiff, + color : 'red', + dashStyle : 'shortdash', + width : 1, + },{ + value : -NormalDiff, + color : 'green', + dashStyle : 'shortdash', + width : 1, + }, { + value : -HighDiff, + color : 'red', + dashStyle : 'shortdash', + width : 1, + }] + }, + series : [{ + name : '价差', + data : [], + tooltip: { + valueDecimals: 2 + } + }] + }; function _N(v, precision) { if (typeof(precision) != 'number') { precision = 4; @@ -61,6 +110,9 @@ function onTick() { } if (diff != __lastDiff) { // add添加数据到series, 参数格式为[series序号, 数据]; + cfg.yAxis.plotLines[0].value=diff; + cfg.subtitle={text:'当前价差:' + diff}; + __chart.update(cfg); __chart.add([0, [new Date().getTime(), diff]]); __lastDiff = diff; } @@ -74,46 +126,7 @@ function main() { throw "只支持两个交易所对冲"; } // 传给Chart函数的必须是一个与上下文无关的结构体(附合HighStocks规则, 详情参数HighStocks使用方法) - __chart = Chart({ - tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'}, - title : { text : '差价分析图'}, - 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 - }, - xAxis: { type: 'datetime'}, - yAxis : { - plotLines : [{ - value : NormalDiff, - color : 'green', - dashStyle : 'shortdash', - width : 1, - }, { - value : HighDiff, - color : 'red', - dashStyle : 'shortdash', - width : 1, - },{ - value : -NormalDiff, - color : 'green', - dashStyle : 'shortdash', - width : 1, - }, { - value : -HighDiff, - color : 'red', - dashStyle : 'shortdash', - width : 1, - }] - }, - series : [{ - name : '价差', - data : [], - tooltip: { - valueDecimals: 2 - } - }] - }); + __chart = Chart(cfg); // reset 清空所有图表之前的信息 // __chart.reset(); if (EnableCR) { @@ -121,7 +134,7 @@ function main() { var rate = exchanges[i].GetRate(); if (rate != 1) { exchanges[i].SetRate(USDCNY); - Log("更改", exchanges[i].GetName(), "汇率", rate, "为", USDCNY) + Log("更改", exchanges[i].GetName(), "汇率", rate, "为", USDCNY); } var eName = exchanges[i].GetName(); if (eName == "Futures_BitVC") { @@ -135,5 +148,11 @@ function main() { while (true) { onTick(); Sleep(TickInterval); + if (GetCommand() === '重置数据') { + LogReset(); + LogProfitReset(); + __chart.reset(); + Log("数据重置成功"); + } } } diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC) (\345\244\215\345\210\266).js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC) (\345\244\215\345\210\266).js" new file mode 100644 index 00000000..4770d405 --- /dev/null +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC) (\345\244\215\345\210\266).js" @@ -0,0 +1,531 @@ +/* +策略出处: https://www.botvs.com/strategy/30307 +策略名称: 数字货币交易类库 (期货支持OKCoin期货-BitVC) (复制) +策略作者: ucfyao +策略描述: + +数字货币交易类库 (期货支持OKCoin期货/BitVC) 目前测试阶段,使用请留意,如有问题 ,请联系作者 ,十分感谢! + + +参数 默认值 描述 +------------ ----- -------------------------- +OpMode 0 现货-下单方式: 吃单|挂单 +MaxSpace 0.5 现货-挂单失效距离 +SlidePrice 0.1 现货-下单滑动价(元) +MaxAmount 0.8 现货-开仓最大单次下单量 +RetryDelay 500 现货-失败重试(毫秒) +MAType 0 现货-均线算法: EMA|MA|AMA(自适应均线) +Interval 300 期货—失败重试间隔(毫秒) +F_SlidePrice 2 期货—下单滑价(元) +lv 0.5 期货—滑价增长率 +max_open_lv true 期货—开仓滑价最大增长率 +max_cover_lv true 期货—平仓滑价最大增长率 +*/ + +// 现货部分 +function CancelPendingOrders(e, orderType) { + while (true) { + var orders = e.GetOrders(); + if (!orders) { + Sleep(RetryDelay); + continue; + } + var processed = 0; + for (var j = 0; j < orders.length; j++) { + if (typeof(orderType) === 'number' && orders[j].Type !== orderType) { + continue; + } + e.CancelOrder(orders[j].Id, orders[j]); + processed++; + if (j < (orders.length - 1)) { + Sleep(RetryDelay); + } + } + if (processed === 0) { + break; + } + } +} + +function GetAccount(e, waitFrozen) { + if (typeof(waitFrozen) == 'undefined') { + waitFrozen = false; + } + var account = null; + var alreadyAlert = false; + while (true) { + account = _C(e.GetAccount); + if (!waitFrozen || (account.FrozenStocks < e.GetMinStock() && account.FrozenBalance < 0.01)) { + break; + } + if (!alreadyAlert) { + alreadyAlert = true; + Log("发现账户有冻结的钱或币", account); + } + Sleep(RetryDelay); + } + return account; +} + + +function StripOrders(e, orderId) { + var order = null; + if (typeof(orderId) == 'undefined') { + orderId = null; + } + while (true) { + var dropped = 0; + var orders = _C(e.GetOrders); + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == orderId) { + order = orders[i]; + } else { + var extra = ""; + if (orders[i].DealAmount > 0) { + extra = "成交: " + orders[i].DealAmount; + } else { + extra = "未成交"; + } + e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); + dropped++; + } + } + if (dropped === 0) { + break; + } + Sleep(RetryDelay); + } + return order; +} + +// mode = 0 : direct buy, 1 : buy as buy1 +function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, retryDelay) { + var initAccount = GetAccount(e, true); + var nowAccount = initAccount; + var orderId = null; + var prePrice = 0; + var dealAmount = 0; + var diffMoney = 0; + var isFirst = true; + var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell; + var isBuy = tradeType == ORDER_TYPE_BUY; + while (true) { + var ticker = _C(e.GetTicker); + var tradePrice = 0; + if (isBuy) { + tradePrice = _N((mode === 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4); + } else { + tradePrice = _N((mode === 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4); + } + if (!orderId) { + if (isFirst) { + isFirst = false; + } else { + nowAccount = GetAccount(e, true); + } + var doAmount = 0; + if (isBuy) { + diffMoney = _N(initAccount.Balance - nowAccount.Balance, 4); + dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 4); + doAmount = Math.min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance - 10) / tradePrice, 4)); + } else { + diffMoney = _N(nowAccount.Balance - initAccount.Balance, 4); + dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); + doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); + } + if (doAmount < e.GetMinStock()) { + break; + } + prePrice = tradePrice; + orderId = tradeFunc(tradePrice, doAmount, ticker); + if (!orderId) { + CancelPendingOrders(e, tradeType); + } + } else { + if (mode === 0 || (Math.abs(tradePrice - prePrice) > maxSpace)) { + orderId = null; + } + var order = StripOrders(e, orderId); + if (!order) { + orderId = null; + } + } + Sleep(retryDelay); + } + + if (dealAmount <= 0) { + return null; + } + + return { + price: _N(diffMoney / dealAmount, 4), + amount: dealAmount + }; +} + +$.Buy = function(e, amount) { + if (typeof(e) === 'number') { + amount = e; + e = exchange; + } + return Trade(e, ORDER_TYPE_BUY, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); +}; + +$.Sell = function(e, amount) { + if (typeof(e) === 'number') { + amount = e; + e = exchange; + } + return Trade(e, ORDER_TYPE_SELL, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); +}; + +$.CancelPendingOrders = function(e, orderType) { + if (typeof(orderType) === 'undefined') { + if (typeof(e) === 'number') { + orderType = e; + e = exchange; + } else if (typeof(e) === 'undefined') { + e = exchange; + } + } + return CancelPendingOrders(e, orderType); +}; + +$.GetAccount = function(e) { + if (typeof(e) === 'undefined') { + e = exchange; + } + return _C(e.GetAccount); +}; + +var _MACalcMethod = [TA.EMA, TA.MA, talib.KAMA][MAType]; + +// 返回上穿的周期数. 正数为上穿周数, 负数表示下穿的周数, 0指当前价格一样 +$.Cross = function(a, b) { + var crossNum = 0; + var arr1 = []; + var arr2 = []; + if (Array.isArray(a)) { + arr1 = a; + arr2 = b; + } else { + var records = null; + while (true) { + records = exchange.GetRecords(); + if (records && records.length > a && records.length > b) { + break; + } + Sleep(RetryDelay); + } + arr1 = _MACalcMethod(records, a); + arr2 = _MACalcMethod(records, b); + } + if (arr1.length !== arr2.length) { + throw "array length not equal"; + } + for (var i = arr1.length-1; i >= 0; i--) { + if (typeof(arr1[i]) !== 'number' || typeof(arr2[i]) !== 'number') { + break; + } + if (arr1[i] < arr2[i]) { + if (crossNum > 0) { + break; + } + crossNum--; + } else if (arr1[i] > arr2[i]) { + if (crossNum < 0) { + break; + } + crossNum++; + } else { + break; + } + } + return crossNum; +}; + +// 期货部分 +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) && direction == PD_LONG) || ((positions[i].Type == PD_SHORT) && 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; + var step = 0; + while (true) { + var needOpen = opAmount; + if (isFirst) { + isFirst = false; + } else { + positionNow = GetPosition(e, contractType, direction); + if (positionNow) { + needOpen = opAmount - (positionNow.Amount - initAmount); + } + } + if (needOpen < e.GetMinStock()) { + break; + } + if (step > max_open_lv) { + break; + } + var amount = needOpen; + e.SetDirection(direction == PD_LONG ? "buy" : "sell"); + var orderId; + if (direction == PD_LONG) { + orderId = e.Buy(price + F_SlidePrice * (1 + step), amount, "开多仓", contractType, price); + } else { + orderId = e.Sell(price - F_SlidePrice * (1 + step), amount, "开空仓", contractType, price); + } + while (true) { + var orders = _C(e.GetOrders); + if (orders.length === 0) { + break; + } + Sleep(Interval); + for (var j = 0; j < orders.length; j++) { + e.CancelOrder(orders[j].Id); + if (j < (orders.length - 1)) { + Sleep(Interval); + } + } + } + step += lv; + } + 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, OP_amount, direction) { + var initP = null; + var positions = null; + var isFirst = true; + var ID = null; + var step = 0; + var index = 0; + while (true) { + var n = 0; + positions = _C(e.GetPosition); + if (isFirst === true) { + if (typeof(direction) === 'undefined' && positions.length > 1 || (direction !== PD_LONG && direction !== PD_SHORT && typeof(direction) !== 'undefined')) { + throw "有多,空双向持仓,并且参数direction未明确方向!或 direction 参数异常:" + direction; + } + initP = positions; + isFirst = false; + } + for (var i = 0; i < positions.length; i++) { + if (positions[i].ContractType != contractType || (positions[i].Type !== direction && typeof(direction) !== 'undefined')) { + continue; + } + var amount = 0; + if (typeof(OP_amount) === 'undefined') { + amount = positions[i].Amount; + } else { + amount = OP_amount - (initP[i].Amount - positions[i].Amount); + } + + if (amount === 0) { + continue; + } + if (positions[i].Type == PD_LONG) { + e.SetDirection("closebuy"); + ID = e.Sell(price - F_SlidePrice * (1 + step), amount, "平多仓", contractType, price); + n++; + } else if (positions[i].Type == PD_SHORT) { + e.SetDirection("closesell"); + ID = e.Buy(price + F_SlidePrice * (1 + step), amount, "平空仓", contractType, price); + n++; + } + index = i; + } + if (n === 0) { + break; + } + Sleep(Interval); + if (typeof(ID) !== 'number') { + Log("ID:", ID); + continue; + } + + e.CancelOrder(ID); + step += lv; + if (step > max_cover_lv) { + break; + } + } + + var nowP = _C(e.GetPosition); + if (!nowP[index] || nowP[index].Type !== initP[index].Type) { + return initP.length === 0 ? 0 : initP[index].Amount; + } else { + var diff = initP[index].Amount - nowP[index].Amount; + return diff; + } +} + +var PositionManager = (function() { + function PositionManager(e) { + if (typeof(e) === 'undefined') { + e = exchange; + } + if (e.GetName() !== 'Futures_OKCoin' && e.GetName() !== 'Futures_BitVC') { + throw 'Only support Futures_OKCoin & Futures_BitVC'; + } + 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); + }; + + 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, OP_amount, direction) { + if (!this.account) { + this.account = _C(exchange.GetAccount); + } + return Cover(this.e, contractType, price, OP_amount, direction); + }; + + PositionManager.prototype.Profit = function(contractType) { + var accountNow = _C(this.e.GetAccount); + Log("NOW:", accountNow, "--account:", this.account); + return _N(accountNow.Balance - this.account.Balance); + }; + + return PositionManager; +})(); + +$.NewPositionManager = function(e) { + return new PositionManager(e); +}; + + +// 测试代码 +function main() { + if (exchange.GetName() === 'Futures_OKCoin') { + var info = exchange.SetContractType("this_week"); + Log("info 返回值:", info); + Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); + var depth = exchange.GetDepth(); + var p = $.NewPositionManager(); + p.OpenShort("this_week", 10, depth.Bids[0].Price - 2); + Log(exchange.GetPosition()); + Sleep(500 * 1000); + depth = exchange.GetDepth(); + var ret = p.Cover("this_week", depth.Bids[0].Price + 2, 5); + Log("cover ret:", ret); + //LogProfit(p.Profit()); + Log(exchange.GetPosition()); + Log("-----------------------------测试分割线----------------------------------------"); + var depth = exchange.GetDepth(); + p.OpenLong("this_week", 20, depth.Bids[0].Price + 2); + Log(exchange.GetPosition()); + Sleep(500 * 1000); + depth = exchange.GetDepth(); + var ret = p.Cover("this_week", depth.Bids[0].Price - 2, 10, PD_LONG); + Log("cover ret:", ret); + Log(exchange.GetPosition()); + Log("-----------------------------测试分割线----------------------------------------"); + var ret = p.Cover("this_week", depth.Bids[0].Price - 3, 10, PD_LONG); + Log("cover ret:", ret); + var ret = p.Cover("this_week", depth.Bids[0].Price + 3, 5, PD_SHORT); + Log("cover ret:", ret); + Log(exchange.GetPosition()); + } else if (exchange.GetName() === 'Futures_BitVC') { + var info = exchange.SetContractType("week"); + Log("info 返回值:", info); + Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); + var depth = exchange.GetDepth(); + var p = $.NewPositionManager(); + p.OpenLong("week", 500, depth.Bids[0].Price + 2); + Log(exchange.GetPosition()); + Sleep(500 * 1000); + depth = exchange.GetDepth(); + var ret = p.Cover("week", depth.Bids[0].Price - 2, 500); + Log("cover ret:", ret); + Log(exchange.GetPosition()); + Log("-----------------------------测试分割线----------------------------------------"); + var info = exchange.SetContractType("week"); + Log("info 返回值:", info); + Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); + var depth = exchange.GetDepth(); + p.OpenShort("week", 600, depth.Bids[0].Price - 2); + Log(exchange.GetPosition()); + Sleep(500 * 1000); + depth = exchange.GetDepth(); + var ret = p.Cover("week", depth.Bids[0].Price + 2, 500, PD_SHORT); + Log("cover ret:", ret); + Log(exchange.GetPosition()); + Log("-----------------------------测试分割线----------------------------------------"); + var ret = p.Cover("week", depth.Bids[0].Price + 3, 100, PD_SHORT); + Log("cover ret:", ret); + //p.Cover("week", depth.Asks[0].Price - 3, 300, PD_LONG); + Log(exchange.GetPosition()); + } else if(exchange.GetName() === 'huobi' || exchange.GetName() === 'OKCoin'){ + Log($.GetAccount()); + Log($.Buy(0.5)); + Log($.Sell(0.5)); + exchange.Buy(1000, 3); + $.CancelPendingOrders(exchanges[0]); + Log($.Cross(30, 7)); + Log($.Cross([1,2,3,2.8,3.5], [3,1.9,2,5,0.6])); + } +} + diff --git "a/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" "b/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" new file mode 100644 index 00000000..5f355a53 --- /dev/null +++ "b/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" @@ -0,0 +1,39 @@ +/* +策略出处: https://www.botvs.com/strategy/40155 +策略名称: 测试 默认 参数组功能 +策略作者: 小小梦 +策略描述: + +### 如何使用代码精确调整“回测系统默认设置” + +> 在策略的参数测试,不同时间段回测,多个标的物回测等,回测策略时由于参数需要反复调整,而且不能记录,下次回测时又要重新设置。平台为了方便参数调整,新增加功能 -- 使用代码精确调整“回测系统默认设置”。 + + +参数 默认值 描述 +-------- ------------ ------------------------- +number 9999 数字类型 +bool true 布尔类型 +string Hello World! 字符串类型 +comboBox 0 下拉框: combo1|combo2|combo3 +*/ + +/*backtest +start: 2017-03-01 +end: 2017-03-02 +period: 15 +mode: 1 +*/ + +/*args +number : 0 +bool: false +string: Hello BotVS! +comboBox : 2 +*/ + +function main(){ + while(true){ + LogStatus("测试默认参数!"); + Sleep(); + } +} diff --git "a/\346\265\213\350\257\225.py" "b/\346\265\213\350\257\225.py" new file mode 100644 index 00000000..9c49b7af --- /dev/null +++ "b/\346\265\213\350\257\225.py" @@ -0,0 +1,15 @@ +''' +策略出处: https://www.botvs.com/strategy/40045 +策略名称: 测试 +策略作者: 程序员 +策略描述: + +我的第一个botvs策略,测试 + +''' + +import time +def main(): + while True: + Log(exchange.GetAccount()) + time.sleep(60) diff --git "a/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.js" "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.js" index cd5231ac..4e489a7d 100644 --- "a/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.js" +++ "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.js" @@ -19,7 +19,7 @@ function main() { series: [{ name: '买一', data: [], - },{ + }, { name: '卖一', data: [], }] @@ -38,8 +38,31 @@ function main() { }] } - var chart = Chart([cfgA, cfgB]); + var cfgC = { + __isStock: false, + title: { + text: '饼图' + }, + series: [{ + type: 'pie', + name: 'one', + data: [ + ["A", 25], + ["B", 25], + ["C", 25], + ["D", 25], + ] + }] + }; + + + var chart = Chart([cfgA, cfgB, cfgC]); chart.reset() + // 为饼图清加一个数点,add只能更新通过add方式添加的数据点, 内置的数据点无法后期更新 + chart.add(3, { + name: "ZZ", + y: Math.random() * 100 + }); while (true) { Sleep(1000) var ticker = exchange.GetTicker() @@ -53,11 +76,16 @@ function main() { cfgB.subtitle = { text: '价差 ' + diff, }; - // update相当于重置了图表的配置 - chart.update([cfgA, cfgB]); + // update实际上等于重置了图表的配置 + chart.update([cfgA, cfgB, cfgC]); chart.add([0, [new Date().getTime(), ticker.Buy]]); chart.add([1, [new Date().getTime(), ticker.Sell]]); // 相当于更新第二个图表的第一个数据序列 chart.add([2, [new Date().getTime(), diff]]); + // 相当于更新了第三个图表的第一个数据序列 + chart.add(3, { + name: "ZZ", + y: Math.random() * 100 + }, -1); } } diff --git "a/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.js" "b/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.js" new file mode 100644 index 00000000..6537d40f --- /dev/null +++ "b/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.js" @@ -0,0 +1,202 @@ +/* +策略出处: https://www.botvs.com/strategy/40266 +策略名称: 知乎专栏 实例文章策略 +策略作者: yilidalei +策略描述: + +测试JS + + +参数 默认值 描述 +------ ----- -------- +RatioA 0.05 调整系数 +RatioB 0.1 平仓加仓偏离系数 +*/ + +// 参数变量 (待填写) +var ContractType = "rb1710"; // 标的物合约代码 ,螺纹钢 1710 合约 目前主力合约 +var UsedRatio = 0.5 +// 全局变量 (待填写) +var Interval = 500; // 轮询时间 , 毫秒 , 500 毫秒 = 0.5 秒 +var Balance_Unit = 0; +var ContractTypeInfo = null; // 合约信息 +var initAccount = null; // 初始账户信息 +var nowAccount = null; // 当前账户信息 +var LONG = 1; +var SHORT = 2; +var IDLE = 0; +var State = IDLE; +var EnterPrice = null; // 入场价 +var FloatProfitStop = null; // 浮动止损 +var LossStop = null; // 止损线 +var manager = null; // 用于引用《商品期货交易类库》 导出函数 生成的对象。 +var MaxAdds = 9; +var Adds = 0; +// 功能函数 (待填写) +function loop(){ // 主循环函数 + /*入场:以前一日收盘价上下0.5*ATR为上下轨,突破上轨做多一份资金,突破下轨做空一份资金。*/ + var records = exchange.GetRecords(PERIOD_D1); + if(!records || records.length < 21){ + return; + } + var atr = GetATR(records); + if(atr.length < 2){ + return; + } + var Bar = records[records.length - 1]; + var lastDayClose = records[records.length - 2].Close; + var lastDayATR = atr[atr.length - 2]; + var upTrack = lastDayClose + lastDayATR * 0.5; + var downTrack = lastDayClose - lastDayATR * 0.5; + + // 开仓 + if(State == IDLE && Bar.Close > upTrack){ // LONG + // Log("触发!上轨:", upTrack, "当前Bar最新收盘价(Close)", Bar.Close, "lastDayATR:", lastDayATR, "lastDayClose:", lastDayClose); // 测试代码 + // throw "暂停!"; // 测试代码 + nowAccount = CheckBalance_Unit(LONG); + var tradeInfoLong = manager.OpenLong(ContractType, _N(Balance_Unit / (ContractTypeInfo.VolumeMultiple * Bar.Close * ContractTypeInfo.LongMarginRatio), 0)); // 商品期货交易类库 导出函数,处理交易细节。 + if(tradeInfoLong){ + EnterPrice = tradeInfoLong.price; + CalcFPS_LS(EnterPrice, LONG); + State = LONG; + } + }else if(State == IDLE && Bar.Close < downTrack){ // SHORT + // Log("触发!下轨:", downTrack, "当前Bar最新收盘价(Close)", Bar.Close, "lastDayATR:", lastDayATR, "lastDayClose:", lastDayClose); // 测试代码 + // throw "暂停!"; // 测试代码 + nowAccount = CheckBalance_Unit(SHORT); + var tradeInfoShort = manager.OpenShort(ContractType, _N(Balance_Unit / (ContractTypeInfo.VolumeMultiple * Bar.Close * ContractTypeInfo.ShortMarginRatio), 0)); // 商品期货交易类库 导出函数,处理交易细节。 + if(tradeInfoShort){ + EnterPrice = tradeInfoShort.price; + CalcFPS_LS(EnterPrice, SHORT); + State = SHORT; + } + } + + // 加仓 + if(State == LONG && Bar.Close > FloatProfitStop && Adds < MaxAdds){ // 多仓状态 触发浮动止盈线 + nowAccount = CheckBalance_Unit(LONG); + var tradeInfoLong = manager.OpenLong(ContractType, _N(Balance_Unit / (ContractTypeInfo.VolumeMultiple * Bar.Close * ContractTypeInfo.LongMarginRatio), 0)); // 商品期货交易类库 导出函数,处理交易细节。 + // 移动中线 + if(tradeInfoLong){ + Adds++; + EnterPrice = tradeInfoLong.price; + CalcFPS_LS(EnterPrice, LONG); + } + }else if(State == SHORT && Bar.Close < FloatProfitStop && Adds < MaxAdds){ // 空仓状态 触发浮动止盈线 + nowAccount = CheckBalance_Unit(SHORT); + var tradeInfoShort = manager.OpenShort(ContractType, _N(Balance_Unit / (ContractTypeInfo.VolumeMultiple * Bar.Close * ContractTypeInfo.ShortMarginRatio), 0)); // 商品期货交易类库 导出函数,处理交易细节。 + // 移动中线 + if(tradeInfoShort){ + Adds++; + EnterPrice = tradeInfoShort.price; + CalcFPS_LS(EnterPrice, SHORT); + } + } + + // 平仓 + if(State == LONG && Bar.Close < LossStop){ // 平多 + manager.Cover(ContractType); + Adds = 0; + State = IDLE; + nowAccount = _C(exchange.GetAccount); + LogProfit(nowAccount.Balance - initAccount.Balance); + }else if(State == SHORT && Bar.Close > LossStop){ // 平空 + manager.Cover(ContractType); + Adds = 0; + State = IDLE; + nowAccount = _C(exchange.GetAccount); + LogProfit(nowAccount.Balance - initAccount.Balance); + } + +} + +function CalcFPS_LS(Para_EnterPrice, Direction){ // 计算 FloatProfitStop : FPS , LossStop : LS + // 以做多为例:设置当前初始线(入场价),按着一定规则(如:止损线=0.8 * 入场价)浮动止盈线和止损线,可以设置,(浮动止盈线-中线)= 1.2(中线-止损线) + /* + if(Direction == LONG){ + LossStop = 0.8 * Para_EnterPrice; + FloatProfitStop = 1.2 * (Para_EnterPrice - (0.8 * Para_EnterPrice)) + Para_EnterPrice; + }else if(Direction == SHORT){ + LossStop = 1.2 * Para_EnterPrice; + FloatProfitStop = Para_EnterPrice - 1.2 * (1.2 * Para_EnterPrice - Para_EnterPrice); + }else{ + throw "错误的Direction参数:" + Direction; + } + */ + var array = [0, RatioA * (10 - Adds) / 20, RatioA * (10 - Adds) / 20, RatioA * (10 - Adds) / 20, RatioA * (10 - Adds) / 20, RatioA * (10 - Adds) / 20]; // ceshi + if(Direction == LONG){ + LossStop = (1 - RatioA + array[Adds]) * Para_EnterPrice; // RatioA : 0.05 + FloatProfitStop = (1 + RatioB) * (Para_EnterPrice - ((1 - RatioA) * Para_EnterPrice)) + Para_EnterPrice; + }else if(Direction == SHORT){ + LossStop = (1 + RatioA - array[Adds]) * Para_EnterPrice; + FloatProfitStop = Para_EnterPrice - (1 + RatioB) * ((1 + RatioA) * Para_EnterPrice - Para_EnterPrice); + }else{ + throw "错误的Direction参数:" + Direction; + } +} + +function GetATR(records){ // 默认为 records 参数是有效值,传入,即: 不为null ,Bar 长度足够。 + var atr = TA.ATR(records); + return atr; +} + +function CheckBalance_Unit(Direction){ + ContractTypeInfo = _C(exchange.SetContractType, ContractType); + Log("标的物合约信息:", ContractTypeInfo); + Balance_Unit = _N(initAccount.Balance * UsedRatio / 10, 2); + Log("账户信息:", initAccount, "资金分配 10份,一份为:", Balance_Unit); + + var ticker = _C(exchange.GetTicker); + var OneContractMargin = ContractTypeInfo.VolumeMultiple * ticker.Last * (Direction == LONG ? ContractTypeInfo.LongMarginRatio : ContractTypeInfo.ShortMarginRatio); + if(Balance_Unit < OneContractMargin * 1.2){ + throw "最新价格:" + ticker.Last + "调整系数1.2 " + " ,资金可用部分的10分之一 不足 开" + (Direction == LONG ? "多" : "空") + "1手合约," + "1手合约需:" + OneContractMargin; + }else{ + Log("最新价格:" + ticker.Last + "调整系数1.2 " + " 1份资金 可开:", Direction == LONG ? "多" : "空", _N(Balance_Unit / OneContractMargin, 0)); + } + var nowAccount = _C(exchange.GetAccount); + if(nowAccount.Balance < Balance_Unit){ + throw "当前账户资金已小于初始资金可用部分的十分之一。当前资金:" + nowAccount.Balance + ", 初始资金可用部分的十分之一为:" + Balance_Unit; + }else if(nowAccount.Balance < OneContractMargin * 1.2){ + throw "资金不足:" + JSON.stringify(nowAccount) + ", 系数1.2,1手合约保证金:" + OneContractMargin; + } + if(nowAccount.Balance - initAccount.Balance * (1 - UsedRatio) < OneContractMargin * 1.2){ + throw "资金可用部分不足一手保证金金额。可用部分:" + (nowAccount.Balance - initAccount.Balance * (1 - UsedRatio)) + ",1手保证金" + OneContractMargin + ",系数:1.2"; + } + return nowAccount; +} + +// 入口函数 main +function main(){ + // 程序的初始化工作 (待填写) + manager = $.NewPositionManager(); // 《商品期货交易类库》导出函数 ,返回一个控制对象。 + while(true){ + if(exchange.IO("status") == true && (initAccount = exchange.GetAccount()) !== null){ + break; + } + LogStatus("等待交易时间获取账户信息初始化!" + "时间:", new Date()); + Sleep(Interval); + } + CheckBalance_Unit(LONG); + CheckBalance_Unit(SHORT); + + // 主循环, 程序完成初始化后在此 循环执行,直到手动关闭。 + var LoginState = null; + var nowTimeStamp = 0; + while(true){ + nowTimeStamp = new Date().getTime(); + if(exchange.IO("status") == true){ + LoginState = true; + loop(); + }else{ + LoginState = false; + } + LogStatus("时间:", _D(nowTimeStamp), LoginState ? "已连接服务器" : "未连接服务器!"/*, 待显示的一些信息可以写在此处,如账户信息,实时行情,程序状态*/) + Sleep(Interval); // 暂停 0.5 秒, 避免轮询频率过高,访问交易所服务器过于频繁导致问题。 + } +} + +function onexit(){ + // 做一些在程序停止时的 收尾工作。(待填写) + + Log("程序退出!"); +} diff --git "a/\347\255\226\347\225\245001-szc.py" "b/\347\255\226\347\225\245001-szc.py" new file mode 100644 index 00000000..cb172477 --- /dev/null +++ "b/\347\255\226\347\225\245001-szc.py" @@ -0,0 +1,79 @@ +''' +策略出处: https://www.botvs.com/strategy/34216 +策略名称: 策略001-szc +策略作者: 丧尸来来 +策略描述: + +实盘策略 + +''' + +import types +import time +import platform + +def main(): + perTime = 0 + amount_buy = 0 + amount_sell = 0 + diffMoney = 0 + dealAmount = 0 + price_buy = 0 + price_sell = 0 + price_stop_win = 0 + price_stop_lose = 0 + initAccount = ext.GetAccount() + while True: + LogStatus("现在时间:", _D(time.time())) + records = exchange.GetRecords(PERIOD_M30) + tiaojian = ext.szc() + nowAccount = ext.GetAccount() + if(not records or len(records) < 20): + continue + else: + if(perTime != records[-1]["Time"]): + perTime = records[-1]["Time"] + if nowAccount['Balance']>=100: + if tiaojian > 0: + Log("--------------------------------------------------------------") + nowAccount = ext.GetAccount() + amount_buy = _N(nowAccount.Balance,2) + exchange.Buy(-1, amount_buy) + lastAccount = ext.GetAccount() + diffMoney = _N(abs(nowAccount.Balance - lastAccount.Balance),4) + dealAmount = _N(abs(lastAccount.Stocks - nowAccount.Stocks),4) + price_buy = _N(diffMoney / dealAmount, 2) + Log("成交价:", price_buy) + Log("止损价:", price_stop_lose) + price_stop_lose = price_buy * 0.95 + price_stop_win = price_buy * 1.05 + else: + pass + elif nowAccount['Stocks']>=0.01: + price_now = _C(exchange.GetTicker).Last + if price_now > price_stop_win: + if tiaojian < 0: + nowAccount = ext.GetAccount() + amount_sell = _N(nowAccount.Stocks,2) + exchange.Sell(-1, amount_sell) + lastAccount = ext.GetAccount() + diffMoney = _N(abs(nowAccount.Balance - lastAccount.Balance),4) + dealAmount = _N(abs(lastAccount.Stocks - nowAccount.Stocks),4) + price_sell = _N(diffMoney / dealAmount, 2) + Log("成交价:", price_sell) + LogProfit(_N(lastAccount.Balance - initAccount.Balance, 2),'钱:',_N(lastAccount.Balance, 2),'币:',_N(lastAccount.Stocks,3)) + else: + pass + elif price_now < price_stop_lose: + Log("当前价:", _C(exchange.GetTicker).Last) + Log("止损!!!") + nowAccount = ext.GetAccount() + amount_sell = _N(nowAccount.Stocks,2) + exchange.Sell(-1, amount_sell) + lastAccount = ext.GetAccount() + LogProfit(_N(lastAccount.Balance - initAccount.Balance, 2),'钱:',_N(lastAccount.Balance, 2),'币:',_N(lastAccount.Stocks,3)) + else: + pass + else: + pass + Sleep(2000) diff --git "a/\350\202\241\347\245\250\350\257\201\345\210\270\346\237\245\350\257\242\344\271\260\345\215\226\347\244\272\344\276\213.js" "b/\350\202\241\347\245\250\350\257\201\345\210\270\346\237\245\350\257\242\344\271\260\345\215\226\347\244\272\344\276\213.js" index 4e434a82..ec28908e 100644 --- "a/\350\202\241\347\245\250\350\257\201\345\210\270\346\237\245\350\257\242\344\271\260\345\215\226\347\244\272\344\276\213.js" +++ "b/\350\202\241\347\245\250\350\257\201\345\210\270\346\237\245\350\257\242\344\271\260\345\215\226\347\244\272\344\276\213.js" @@ -8,41 +8,38 @@ 参数 默认值 描述 ------------- --------- --------- -Op 0 操作: 查询|买卖 +------------ --------- ---- ContractType 000001.SZ 合约名称 -QueryTicker false 查询行情 -Direction 0 买卖方向: 买|卖 Num 100 手数 */ -// 重试函数, 程序启动需要时间来登陆验证 -function EnsureCall(method) { - var r; - while (!(r = method.apply(this, Array.prototype.slice.call(arguments).slice(1)))) { - Sleep(1000); - } - return r; -} - -function main() { - Log("账户", EnsureCall(exchange.GetAccount)); - Log("持仓", EnsureCall(exchange.GetPosition)); - Log("订单", EnsureCall(exchange.GetOrders)); - var ins = EnsureCall(exchange.SetContractType, ContractType); - Log("交易所:", (ins.ExchangeID == "SZE" ? "深交所" : "上交所"), "合约:", ins.InstrumentName, "最小下单量:", ins.MinBuyVolume, "份, 最大下单量:", ins.MaxLimitOrderVolume); - if (QueryTicker) { - Log("合约行情:", EnsureCall(exchange.GetTicker)); - Log("盘口深度:", EnsureCall(exchange.GetDepth)); - } - if (Op === 0) { - return; - } - if (Direction === 0) { - exchange.SetDirection("buy"); - exchange.Buy(Num); // 市价单只传一个购买数量, 如果想要加其它参数可以exchange.Buy(-1, Num, .....); - } else { - exchange.SetDirection("closebuy"); - exchange.Sell(Num); - } +function main() { + while (!exchange.IO("status")) { + Sleep(1000) + } + Sleep(1000) + Log(_C(exchange.SetContractType, ContractType)); + while (!exchange.IO("status")) { + Sleep(1000) + } + exchange.SetDirection("buy") + var ticker = exchange.GetTicker() + Log("ticker", ticker) + if (ticker) { + exchange.Buy(ticker.Sell+10, Num) + Sleep(1000) + Log(exchange.GetPosition()) + } + exchange.SetDirection("closebuy") + ticker = exchange.GetTicker() + exchange.Sell(ticker.Buy - 1, Num) + Sleep(1000) + Log(exchange.GetPosition()) + Log(exchange.GetAccount()) + while(true){ + ticker = exchange.GetTicker() + if (ticker) { + LogStatus(ticker.Last, exchange.GetPosition()) + } + } } diff --git "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277 (Copy).js" "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277 (Copy).js" new file mode 100644 index 00000000..e80d78ea --- /dev/null +++ "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277 (Copy).js" @@ -0,0 +1,305 @@ +/* +策略出处: https://www.botvs.com/strategy/41741 +策略名称: 转换任意K线周期管理模板 (Copy) +策略作者: 779335834 +策略描述: + +1. 修改自小小梦的"转换任意K线周期" 模板 + +原理: + - 获得固定K线的周期,然后合成任意固定K线整数倍的新K线周期 + +功能: + - 转换基础K线为任意K线周期 + - 暂时不支持 秒级别 + +限制: + - 新K线周期必须是固定K线周期的整数倍. + - 固定K线周期为1min, 3min, 5min, 15min, 30min, 新K线周期也必须是分钟且<60 + - 固定K线周期为1hour, 新K线周期也必须是小时且<24 + - 固定K线周期为1day, 新K线周期也必须是天 + - 每次获得的固定K线周期数目必须>=2 +测试版本,如有BUG ,问题 欢迎留言。 + +输出函数: + $.RecordsManager(NewCycleMS) 生成新周期管理器, NewCycleMS 为新K线周期毫秒数. 默认(1000*60*60*2) 2hour. + $.AssembleRecords(records, BaseCycleMS) 通过原records生成新的K线的records, BaseCycleMS 为固定K线周期毫秒,默认用固定records进行计算 + $.GetRecordsTable(n) 得到新K线最新的N个条目, 默认输出所有条目, 输出为table类型,便于LogStatus输出 + $.Get***** 获得一些基本信息 + + +参数 默认值 描述 +---------------- ------------ ------- +UI_NewCycleForMS 1000*60*60*2 合成周期毫秒数 +*/ + +/*backtest + period: 60 + */ +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; +}; + +var DAY = 0; +var HOURS = 1; +var MINUTES = 2; + +function GetDHM(objTime, BaseCycle, NewCycleForMS){ + var ret = []; + if(BaseCycle % (1000 * 60 * 60 * 24) === 0){ + ret[0] = objTime.getDate(); + ret[1] = DAY; + }else if(BaseCycle % (1000 * 60 * 60) === 0){ + ret[0] = objTime.getHours(); + ret[1] = HOURS; + }else if(BaseCycle % (1000 * 60) === 0){ + ret[0] = objTime.getMinutes(); + ret[1] = MINUTES; + } + if(NewCycleForMS % (1000 * 60 * 60 * 24) === 0){ + ret[2] = DAY; + }else if(NewCycleForMS % (1000 * 60 * 60) === 0){ + ret[2] = HOURS; + }else if(NewCycleForMS % (1000 * 60) === 0){ + ret[2] = MINUTES; + } + return ret; +} + +function SearchFirstTime(ret, BaseCycle, NewCycleForMS){ + if(ret[1] === DAY && ret[2] === DAY){ + var array_day = []; + for(var i = 1 ; i < 29; i += (NewCycleForMS / BaseCycle)){ + array_day.push(i); + } + for(var j = 0 ; j < array_day.length; j++ ){ + if(ret[0] === array_day[j]){ + return true; + } + } + }else if(ret[1] === HOURS && ret[2] === HOURS){ + var array_hours = []; + for(var i = 0 ; i < 24; i += (NewCycleForMS / BaseCycle)){ + array_hours.push(i); + } + for(var j = 0 ; j < array_hours.length ; j++){ + if(ret[0] === array_hours[j]){ + return true; + } + } + }else if(ret[1] === MINUTES && ret[2] === MINUTES){ + var array_minutes = []; + for(var i = 0; i < 60; i += (NewCycleForMS / BaseCycle)){ + array_minutes.push(i); + } + for(var j = 0; j < array_minutes.length; j++){ + if(ret[0] === array_minutes[j]){ + return true; + } + } + }else{ + throw "目标周期与基础周期不匹配!目标周期毫秒数:" + NewCycleForMS + " 基础周期毫秒数: " + BaseCycle; + } +} + +function Calc_High(AssRecords, n, BaseCycle, NewCycleForMS){ + var max = AssRecords[n].High; + for(var i = 1 ; i < NewCycleForMS / BaseCycle; i++){ + max = Math.max(AssRecords[n + i].High, max); + } + return max; +} + +function Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS){ + var min = AssRecords[n].Low; + for(var i = 1 ; i < NewCycleForMS / BaseCycle; i++){ + min = Math.min(AssRecords[n + i].Low, min); + } + return min; +} + +function _RecordsManager(NewCycleForMS) { + if (typeof NewCycleForMS == 'string') { + this._NewCycleForMS = 1; + var arrayNum = NewCycleForMS.split("*"); + for(var indexNum = 0 ; indexNum < arrayNum.length ; indexNum++){ + this._NewCycleForMS = this._NewCycleForMS * Number(arrayNum[indexNum]); + } + } else { + this._NewCycleForMS = NewCycleForMS; + } + + this._Records = new Array(); + + this.GetNewCycleForMS = function() { + return this._NewCycleForMS; + }; + + this.AssembleRecords = function(records, BaseCycle) { + var NewCycleForMS = this._NewCycleForMS; + var AssRecords = records.slice(0); // 深拷贝 + var AfterAssRecords = []; + + if (!records || records.length == 0) { + Log("record 为空!"); + return records; + } + if(records.length < 2){ + throw (!records) ? "传入的records参数为 错误" + records : "基础K线长度小于2"; + } + if (typeof BaseCycle === 'undefined') { + BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time; + } + if(NewCycleForMS % BaseCycle !== 0){ + throw "目标周期‘" + NewCycleForMS + "’不是 基础周期 ‘" + BaseCycle + "’ 的整倍数,无法合成!"; + } + if(NewCycleForMS / BaseCycle > records.length){ + Log("records: ", records, "NewCycleForMS: ", NewCycleForMS, ", BaseCycle: ", BaseCycle); + throw "基础K线数量不足,请检查是否基础K线周期过小!"; + } + + // 判断时间戳, 找到 基础K线 相对于 目标K线的起始时间。 + var objTime = new Date(); + var isFirstFind = true; + var FirstStamp = null; + for (var i = 0; i < AssRecords.length; i++) { + objTime.setTime(AssRecords[i].Time); + var ret = GetDHM(objTime, BaseCycle, NewCycleForMS); + + if (isFirstFind === true && SearchFirstTime(ret, BaseCycle, NewCycleForMS) === true) { + FirstStamp = AssRecords[i].Time; + for (j = 0; j < i; j++) { + AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。 + } + isFirstFind = false; + break; // 排除后跳出 + }else if(isFirstFind === false){ + if((AssRecords[i].Time - FirstStamp) % NewCycleForMS === 0){ + for (j = 0; j < i; j++) { + AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。 + } + break; + } + } + } + var BarObj = { // 定义一个 K线柱结构 + Time: 0, + Open: 0, + High: 0, + Low: 0, + Close: 0, + Volume: 0, + }; + var n = 0; + for (n = 0; n < AssRecords.length - (NewCycleForMS / BaseCycle); n += (NewCycleForMS / BaseCycle)) { // 合成 + /* + { + Time :一个时间戳, 精确到毫秒,与Javascript的 new Date().getTime() 得到的结果格式一样 + Open :开盘价 + High :最高价 + Low :最低价 + Close :收盘价 + Volume :交易量 + } + */ + BarObj.Time = AssRecords[n].Time; + BarObj.Open = AssRecords[n].Open; + BarObj.High = Calc_High(AssRecords, n, BaseCycle, NewCycleForMS); + BarObj.Low = Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS); + BarObj.Close = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Close; + BarObj.Volume = 0; + for (var j = n; j < n + (NewCycleForMS / BaseCycle); j++) { + BarObj.Volume += AssRecords[j].Volume; + } + AfterAssRecords.push(cloneObj(BarObj)); + } + + BarObj.Time = AssRecords[Math.max(n - (NewCycleForMS / BaseCycle), 0)].Time + NewCycleForMS; // 最后一根时间不能变, + BarObj.Open = AssRecords[n].Open; + BarObj.Close = AssRecords[AssRecords.length - 1].Close; + BarObj.Volume = 0; + var max = AssRecords[n].High; + var min = AssRecords[n].Low; + for(var index_n = n + 1 ;index_n < AssRecords.length; index_n++){ + max = Math.max(max, AssRecords[index_n].High); + min = Math.min(min, AssRecords[index_n].Low); + BarObj.Volume += AssRecords[index_n].Volume; + } + BarObj.High = max; + BarObj.Low = min; + AfterAssRecords.push(cloneObj(BarObj)); + + this._Records = AfterAssRecords; + return AfterAssRecords; + }; + + this.GetKlineName = function () { + return " " + this._NewCycleForMS / 60 / 1000 + " 分钟K线"; + }; + + /* 获得records数据表格*/ + this.GetRecordsTable = function (n) { + if (typeof n !== 'undefined' && n >=0 ) { + var records = this._Records.slice(-n); + } else { + var records = this._Records.slice(0); + } + + var record_array = new Array(); + for (var i = records.length - 1; i >= 0; i--) { + var newDate = new Date(); + newDate.setTime(records[i].Time); + var time_str = newDate.toLocaleString(); + record_array.push([time_str, records[i].Open, records[i].Close, + records[i].High, records[i].Low, records[i].Volume]); + } + var title = this.GetKlineName() + "(" + records.length + "根)"; + var table = {type: 'table', title: title, + cols: ['Time', 'Open','Close', 'High', 'Low', 'Volume'], + rows: record_array}; + return table; + } +} + +$.RecordsManager = function (NewCycleForMS) { + + if (typeof NewCycleForMS === 'undefined') { + NewCycleForMS = UI_NewCycleForMS; + } + var RecordsManager = new _RecordsManager(NewCycleForMS); + return RecordsManager; +} + +function main() { + var records = exchange.GetRecords(); + while (!records || records.length < 24) { + records = exchange.GetRecords(); + Sleep(1000); + } + + while (true) { + records = _C(exchange.GetRecords); + record_manager0 = $.RecordsManager(); + new_records0 = record_manager0.AssembleRecords(records); + var table0 = record_manager0.GetRecordsTable(); + + var BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time; + record_manager1 = $.RecordsManager(BaseCycle); + new_records1 = record_manager1.AssembleRecords(records); + var table1 = record_manager1.GetRecordsTable(); + LogStatus('`' + JSON.stringify([table0, table1]) +'`'); + Sleep(1000); + } +} diff --git "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170531) (Copy).js" "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170531) (Copy).js" new file mode 100644 index 00000000..c03fb3c8 --- /dev/null +++ "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170531) (Copy).js" @@ -0,0 +1,315 @@ +/* +策略出处: https://www.botvs.com/strategy/43082 +策略名称: 转换任意K线周期管理模板(最近更新20170531) (Copy) +策略作者: guangming +策略描述: + +更新于20170531 + a. fix Volume计算错误 + +1. 修改自小小梦的"转换任意K线周期" 模板 + +原理: + - 获得固定K线的周期,然后合成任意固定K线整数倍的新K线周期 + +功能: + - 转换基础K线为任意K线周期 + - 暂时不支持 秒级别 + +限制: + - 新K线周期必须是固定K线周期的整数倍. + - 固定K线周期为1min, 3min, 5min, 15min, 30min, 新K线周期也必须是分钟且<60 + - 固定K线周期为1hour, 新K线周期也必须是小时且<24 + - 固定K线周期为1day, 新K线周期也必须是天 + - 每次获得的固定K线周期数目必须>=2 +测试版本,如有BUG ,问题 欢迎留言。 + +输出函数: + $.RecordsManager(NewCycleMS) 生成新周期管理器, NewCycleMS 为新K线周期毫秒数. 默认(1000*60*60*2) 2hour. + $.AssembleRecords(records, BaseCycleMS) 通过原records生成新的K线的records, BaseCycleMS 为固定K线周期毫秒,默认用固定records进行计算 + $.GetRecordsTable(n) 得到新K线最新的N个条目, 默认输出所有条目, 输出为table类型,便于LogStatus输出 + $.Get***** 获得一些基本信息 + + +参数 默认值 描述 +---------------- ------------ ------- +UI_NewCycleForMS 1000*60*60*2 合成周期毫秒数 +*/ + +/*backtest + period: 60 + */ +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; +}; + +var DAY = 0; +var HOURS = 1; +var MINUTES = 2; + +function GetDHM(objTime, BaseCycle, NewCycleForMS){ + var ret = []; + if(BaseCycle % (1000 * 60 * 60 * 24) === 0){ + ret[0] = objTime.getDate(); + ret[1] = DAY; + }else if(BaseCycle % (1000 * 60 * 60) === 0){ + ret[0] = objTime.getHours(); + ret[1] = HOURS; + }else if(BaseCycle % (1000 * 60) === 0){ + ret[0] = objTime.getMinutes(); + ret[1] = MINUTES; + } + if(NewCycleForMS % (1000 * 60 * 60 * 24) === 0){ + ret[2] = DAY; + }else if(NewCycleForMS % (1000 * 60 * 60) === 0){ + ret[2] = HOURS; + }else if(NewCycleForMS % (1000 * 60) === 0){ + ret[2] = MINUTES; + } + return ret; +} + +function SearchFirstTime(ret, BaseCycle, NewCycleForMS){ + if(ret[1] === DAY && ret[2] === DAY){ + var array_day = []; + for(var i = 1 ; i < 29; i += (NewCycleForMS / BaseCycle)){ + array_day.push(i); + } + for(var j = 0 ; j < array_day.length; j++ ){ + if(ret[0] === array_day[j]){ + return true; + } + } + }else if(ret[1] === HOURS && ret[2] === HOURS){ + var array_hours = []; + for(var i = 0 ; i < 24; i += (NewCycleForMS / BaseCycle)){ + array_hours.push(i); + } + for(var j = 0 ; j < array_hours.length ; j++){ + if(ret[0] === array_hours[j]){ + return true; + } + } + }else if(ret[1] === MINUTES && ret[2] === MINUTES){ + var array_minutes = []; + for(var i = 0; i < 60; i += (NewCycleForMS / BaseCycle)){ + array_minutes.push(i); + } + for(var j = 0; j < array_minutes.length; j++){ + if(ret[0] === array_minutes[j]){ + return true; + } + } + }else{ + throw "目标周期与基础周期不匹配!目标周期毫秒数:" + NewCycleForMS + " 基础周期毫秒数: " + BaseCycle; + } +} + +function Calc_High(AssRecords, n, BaseCycle, NewCycleForMS){ + var max = AssRecords[n].High; + for(var i = 1 ; i < NewCycleForMS / BaseCycle; i++){ + max = Math.max(AssRecords[n + i].High, max); + } + return max; +} + +function Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS){ + var min = AssRecords[n].Low; + for(var i = 1 ; i < NewCycleForMS / BaseCycle; i++){ + min = Math.min(AssRecords[n + i].Low, min); + } + return min; +} + +function _RecordsManager(NewCycleForMS) { + if (typeof NewCycleForMS == 'string') { + this._NewCycleForMS = 1; + var arrayNum = NewCycleForMS.split("*"); + for(var indexNum = 0 ; indexNum < arrayNum.length ; indexNum++){ + this._NewCycleForMS = this._NewCycleForMS * Number(arrayNum[indexNum]); + } + } else { + this._NewCycleForMS = NewCycleForMS; + } + + this._Records = new Array(); + + this.GetNewCycleForMS = function() { + return this._NewCycleForMS; + }; + + this.GetRecords = function() { + return this._Records; + } + + this.AssembleRecords = function(records, BaseCycle) { + var NewCycleForMS = this._NewCycleForMS; + var AssRecords = records.slice(0); // 深拷贝 + var AfterAssRecords = []; + + if (!records || records.length == 0) { + Log("record 为空@!"); + return records; + } + if(records.length < 2){ + throw (!records) ? "传入的records参数为 错误" + records : "基础K线长度小于2"; + } + if (typeof BaseCycle === 'undefined') { + BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time; + } + if(NewCycleForMS % BaseCycle !== 0){ + throw "目标周期‘" + NewCycleForMS + "’不是 基础周期 ‘" + BaseCycle + "’ 的整倍数,无法合成!"; + } + if(NewCycleForMS / BaseCycle > records.length){ + Log("records: ", records, "NewCycleForMS: ", NewCycleForMS, ", BaseCycle: ", BaseCycle); + throw "基础K线数量不足,请检查是否基础K线周期过小!"; + } + + // 判断时间戳, 找到 基础K线 相对于 目标K线的起始时间。 + var objTime = new Date(); + var isFirstFind = true; + var FirstStamp = null; + for (var i = 0; i < AssRecords.length; i++) { + objTime.setTime(AssRecords[i].Time); + var ret = GetDHM(objTime, BaseCycle, NewCycleForMS); + + if (isFirstFind === true && SearchFirstTime(ret, BaseCycle, NewCycleForMS) === true) { + FirstStamp = AssRecords[i].Time; + for (j = 0; j < i; j++) { + AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。 + } + isFirstFind = false; + break; // 排除后跳出 + }else if(isFirstFind === false){ + if((AssRecords[i].Time - FirstStamp) % NewCycleForMS === 0){ + for (j = 0; j < i; j++) { + AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。 + } + break; + } + } + } + var BarObj = { // 定义一个 K线柱结构 + Time: 0, + Open: 0, + High: 0, + Low: 0, + Close: 0, + Volume: 0, + }; + var n = 0; + for (n = 0; n < AssRecords.length - (NewCycleForMS / BaseCycle); n += (NewCycleForMS / BaseCycle)) { // 合成 + /* + { + Time :一个时间戳, 精确到毫秒,与Javascript的 new Date().getTime() 得到的结果格式一样 + Open :开盘价 + High :最高价 + Low :最低价 + Close :收盘价 + Volume :交易量 + } + */ + BarObj.Time = AssRecords[n].Time; + BarObj.Open = AssRecords[n].Open; + BarObj.High = Calc_High(AssRecords, n, BaseCycle, NewCycleForMS); + BarObj.Low = Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS); + BarObj.Close = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Close; + BarObj.Volume = 0; + for (var j = n; j < n + (NewCycleForMS / BaseCycle); j++) { + BarObj.Volume += AssRecords[j].Volume; + } + AfterAssRecords.push(cloneObj(BarObj)); + } + + BarObj.Time = AssRecords[Math.max(n - (NewCycleForMS / BaseCycle), 0)].Time + NewCycleForMS; // 最后一根时间不能变, + BarObj.Open = AssRecords[n].Open; + BarObj.Close = AssRecords[AssRecords.length - 1].Close; + BarObj.Volume = AssRecords[n].Volume; + //BarObj.Volume = 0; + var max = AssRecords[n].High; + var min = AssRecords[n].Low; + for(var index_n = n + 1 ;index_n < AssRecords.length; index_n++){ + max = Math.max(max, AssRecords[index_n].High); + min = Math.min(min, AssRecords[index_n].Low); + BarObj.Volume += AssRecords[index_n].Volume; + } + BarObj.High = max; + BarObj.Low = min; + AfterAssRecords.push(cloneObj(BarObj)); + + this._Records = AfterAssRecords; + return AfterAssRecords; + }; + + this.GetKlineName = function () { + return " " + this._NewCycleForMS / 60 / 1000 + " 分钟K线"; + }; + + /* 获得records数据表格*/ + this.GetRecordsTable = function (n) { + if (typeof n !== 'undefined' && n >=0 ) { + var records = this._Records.slice(-n); + } else { + var records = this._Records.slice(0); + } + + var record_array = new Array(); + for (var i = records.length - 1; i >= 0; i--) { + var newDate = new Date(); + newDate.setTime(records[i].Time); + var time_str = newDate.toLocaleString(); + record_array.push([time_str, records[i].Open, records[i].Close, + records[i].High, records[i].Low, records[i].Volume]); + } + var title = this.GetKlineName() + "(" + records.length + "根)"; + var table = {type: 'table', title: title, + cols: ['Time', 'Open','Close', 'High', 'Low', 'Volume'], + rows: record_array}; + return table; + } +} + +$.RecordsManager = function (NewCycleForMS) { + + if (typeof NewCycleForMS === 'undefined') { + NewCycleForMS = UI_NewCycleForMS; + } + var RecordsManager = new _RecordsManager(NewCycleForMS); + return RecordsManager; +} + +function main() { + var records = exchange.GetRecords(); + while (!records || records.length < 24) { + records = exchange.GetRecords(); + Sleep(1000); + } + + while (true) { + records = _C(exchange.GetRecords); + record_manager0 = $.RecordsManager(); + new_records0 = record_manager0.AssembleRecords(records); + var table0 = record_manager0.GetRecordsTable(); + + var BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time; + record_manager1 = $.RecordsManager(BaseCycle); + new_records1 = record_manager1.AssembleRecords(records); + var table1 = record_manager1.GetRecordsTable(); + LogStatus('`' + JSON.stringify([table0, table1]) +'`'); + records = record_manager1.GetRecords(); + //Log(records[records.length-1]); + Sleep(60000); + } +} diff --git "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170622).js" "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170622).js" new file mode 100644 index 00000000..0a655f69 --- /dev/null +++ "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170622).js" @@ -0,0 +1,332 @@ +/* +策略出处: https://www.botvs.com/strategy/41163 +策略名称: 转换任意K线周期管理模板(最近更新20170622) +策略作者: 青铜战国级机器人 +策略描述: + +更新于20170622 + a. RecordsManager 增加Name参数,便于区分不同的K线 + b. Fix 当固定K线数目不满一根新K线周期时,Time计算不正确的问题 + +更新于20170531 + a. fix Volume计算错误 + +1. 修改自小小梦的"转换任意K线周期" 模板 + +原理: + - 获得固定K线的周期,然后合成任意固定K线整数倍的新K线周期 + +功能: + - 转换基础K线为任意K线周期 + - 暂时不支持 秒级别 + +限制: + - 新K线周期必须是固定K线周期的整数倍. + - 固定K线周期为1min, 3min, 5min, 15min, 30min, 新K线周期也必须是分钟且<60 + - 固定K线周期为1hour, 新K线周期也必须是小时且<24 + - 固定K线周期为1day, 新K线周期也必须是天 + - 每次获得的固定K线周期数目必须>=2 +测试版本,如有BUG ,问题 欢迎留言。 + +输出函数: + $.RecordsManager(NewCycleMS, Name) 生成新周期管理器 + NewCycleMS 为新K线周期毫秒数. 默认(1000*60*60*2) 2hour. + Name: 为该K线管理指定名字 + 返回K线管理器 + $.AssembleRecords(records, BaseCycleMS) + records: 拿到的原始records + BaseCycleMS 为固定K线周期毫秒,默认用固定records进行计算 + 返回新K线周期的records + $.GetRecordsTable(n) 得到新K线最新的N个条目, 默认输出所有条目, 输出为table类型,便于LogStatus输出 + $.Get***** 获得一些基本信息 + + +参数 默认值 描述 +---------------- ------------ ------- +UI_NewCycleForMS 1000*60*60*2 合成周期毫秒数 +*/ + +/*backtest + period: 60 + */ +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; +}; + +var DAY = 0; +var HOURS = 1; +var MINUTES = 2; + +function GetDHM(objTime, BaseCycle, NewCycleForMS){ + var ret = []; + if(BaseCycle % (1000 * 60 * 60 * 24) === 0){ + ret[0] = objTime.getDate(); + ret[1] = DAY; + }else if(BaseCycle % (1000 * 60 * 60) === 0){ + ret[0] = objTime.getHours(); + ret[1] = HOURS; + }else if(BaseCycle % (1000 * 60) === 0){ + ret[0] = objTime.getMinutes(); + ret[1] = MINUTES; + } + if(NewCycleForMS % (1000 * 60 * 60 * 24) === 0){ + ret[2] = DAY; + }else if(NewCycleForMS % (1000 * 60 * 60) === 0){ + ret[2] = HOURS; + }else if(NewCycleForMS % (1000 * 60) === 0){ + ret[2] = MINUTES; + } + return ret; +} + +function SearchFirstTime(ret, BaseCycle, NewCycleForMS){ + if(ret[1] === DAY && ret[2] === DAY){ + var array_day = []; + for(var i = 1 ; i < 29; i += (NewCycleForMS / BaseCycle)){ + array_day.push(i); + } + for(var j = 0 ; j < array_day.length; j++ ){ + if(ret[0] === array_day[j]){ + return true; + } + } + }else if(ret[1] === HOURS && ret[2] === HOURS){ + var array_hours = []; + for(var i = 0 ; i < 24; i += (NewCycleForMS / BaseCycle)){ + array_hours.push(i); + } + for(var j = 0 ; j < array_hours.length ; j++){ + if(ret[0] === array_hours[j]){ + return true; + } + } + }else if(ret[1] === MINUTES && ret[2] === MINUTES){ + var array_minutes = []; + for(var i = 0; i < 60; i += (NewCycleForMS / BaseCycle)){ + array_minutes.push(i); + } + for(var j = 0; j < array_minutes.length; j++){ + if(ret[0] === array_minutes[j]){ + return true; + } + } + }else{ + throw "目标周期与基础周期不匹配!目标周期毫秒数:" + NewCycleForMS + " 基础周期毫秒数: " + BaseCycle; + } +} + +function Calc_High(AssRecords, n, BaseCycle, NewCycleForMS){ + var max = AssRecords[n].High; + for(var i = 1 ; i < NewCycleForMS / BaseCycle; i++){ + max = Math.max(AssRecords[n + i].High, max); + } + return max; +} + +function Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS){ + var min = AssRecords[n].Low; + for(var i = 1 ; i < NewCycleForMS / BaseCycle; i++){ + min = Math.min(AssRecords[n + i].Low, min); + } + return min; +} + +function _RecordsManager(NewCycleForMS, Name) { + if (typeof NewCycleForMS == 'string') { + this._NewCycleForMS = 1; + var arrayNum = NewCycleForMS.split("*"); + for(var indexNum = 0 ; indexNum < arrayNum.length ; indexNum++){ + this._NewCycleForMS = this._NewCycleForMS * Number(arrayNum[indexNum]); + } + } else { + this._NewCycleForMS = NewCycleForMS; + } + this._Name = ""; + if (Name) { + this._Name = Name; + } + this._Records = new Array(); + + this.GetNewCycleForMS = function() { + return this._NewCycleForMS; + }; + + this.GetRecords = function() { + return this._Records; + } + + this.AssembleRecords = function(records, BaseCycle) { + var NewCycleForMS = this._NewCycleForMS; + var AssRecords = records.slice(0); // 深拷贝 + var AfterAssRecords = []; + + if (!records || records.length == 0) { + Log("record 为空@!"); + return records; + } + if(records.length < 2){ + throw (!records) ? "传入的records参数为 错误" + records : "基础K线长度小于2"; + } + if (typeof BaseCycle === 'undefined') { + BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time; + } + if(NewCycleForMS % BaseCycle !== 0){ + throw "目标周期‘" + NewCycleForMS + "’不是 基础周期 ‘" + BaseCycle + "’ 的整倍数,无法合成!"; + } + if(NewCycleForMS / BaseCycle > records.length){ + Log("records: ", records, "NewCycleForMS: ", NewCycleForMS, ", BaseCycle: ", BaseCycle); + throw "基础K线数量不足,请检查是否基础K线周期过小!"; + } + + // 判断时间戳, 找到 基础K线 相对于 目标K线的起始时间。 + var objTime = new Date(); + var isFirstFind = true; + var FirstStamp = null; + for (var i = 0; i < AssRecords.length; i++) { + objTime.setTime(AssRecords[i].Time); + var ret = GetDHM(objTime, BaseCycle, NewCycleForMS); + + if (isFirstFind === true && SearchFirstTime(ret, BaseCycle, NewCycleForMS) === true) { + FirstStamp = AssRecords[i].Time; + for (j = 0; j < i; j++) { + AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。 + } + isFirstFind = false; + break; // 排除后跳出 + }else if(isFirstFind === false){ + if((AssRecords[i].Time - FirstStamp) % NewCycleForMS === 0){ + for (j = 0; j < i; j++) { + AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。 + } + break; + } + } + } + var BarObj = { // 定义一个 K线柱结构 + Time: 0, + Open: 0, + High: 0, + Low: 0, + Close: 0, + Volume: 0, + }; + var n = 0; + for (n = 0; n < AssRecords.length - (NewCycleForMS / BaseCycle); n += (NewCycleForMS / BaseCycle)) { // 合成 + /* + { + Time :一个时间戳, 精确到毫秒,与Javascript的 new Date().getTime() 得到的结果格式一样 + Open :开盘价 + High :最高价 + Low :最低价 + Close :收盘价 + Volume :交易量 + } + */ + BarObj.Time = AssRecords[n].Time; + BarObj.Open = AssRecords[n].Open; + BarObj.High = Calc_High(AssRecords, n, BaseCycle, NewCycleForMS); + BarObj.Low = Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS); + BarObj.Close = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Close; + BarObj.Volume = 0; + for (var j = n; j < n + (NewCycleForMS / BaseCycle); j++) { + BarObj.Volume += AssRecords[j].Volume; + } + AfterAssRecords.push(cloneObj(BarObj)); + } + + if (n == 0) { + BarObj.Time = AssRecords[0].Time; + } else { + BarObj.Time = AssRecords[n - (NewCycleForMS / BaseCycle)].Time + NewCycleForMS; // 最后一根时间不能变, + } + BarObj.Open = AssRecords[n].Open; + BarObj.Close = AssRecords[AssRecords.length - 1].Close; + BarObj.Volume = AssRecords[n].Volume; + //BarObj.Volume = 0; + var max = AssRecords[n].High; + var min = AssRecords[n].Low; + for(var index_n = n + 1 ;index_n < AssRecords.length; index_n++){ + max = Math.max(max, AssRecords[index_n].High); + min = Math.min(min, AssRecords[index_n].Low); + BarObj.Volume += AssRecords[index_n].Volume; + } + BarObj.High = max; + BarObj.Low = min; + AfterAssRecords.push(cloneObj(BarObj)); + + this._Records = AfterAssRecords; + return AfterAssRecords; + }; + + this.GetKlineName = function () { + return " " + this._NewCycleForMS / 60 / 1000 + " 分钟K线"; + }; + + /* 获得records数据表格*/ + this.GetRecordsTable = function (n) { + if (typeof n !== 'undefined' && n >=0 ) { + var records = this._Records.slice(-n); + } else { + var records = this._Records.slice(0); + } + + var record_array = new Array(); + for (var i = records.length - 1; i >= 0; i--) { + var newDate = new Date(); + newDate.setTime(records[i].Time); + var time_str = newDate.toLocaleString(); + record_array.push([time_str, records[i].Open, records[i].Close, + records[i].High, records[i].Low, records[i].Volume]); + } + var title = this._Name + " " + this.GetKlineName() + "(" + records.length + "根)"; + var table = {type: 'table', title: title, + cols: ['Time', 'Open','Close', 'High', 'Low', 'Volume'], + rows: record_array}; + return table; + } +} + +$.RecordsManager = function (NewCycleForMS, Name) { + + if (typeof NewCycleForMS === 'undefined') { + NewCycleForMS = UI_NewCycleForMS; + } + var RecordsManager = new _RecordsManager(NewCycleForMS, Name); + return RecordsManager; +} + +function main() { + var records = exchange.GetRecords(); + while (!records || records.length < 24) { + records = exchange.GetRecords(); + Sleep(1000); + } + + while (true) { + records = _C(exchange.GetRecords); + record_manager0 = $.RecordsManager(UI_NewCycleForMS, "Hello World"); + new_records0 = record_manager0.AssembleRecords(records); + var table0 = record_manager0.GetRecordsTable(); + + var BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time; + record_manager1 = $.RecordsManager(BaseCycle); + new_records1 = record_manager1.AssembleRecords(records); + var table1 = record_manager1.GetRecordsTable(); + LogStatus('`' + JSON.stringify([table0, table1]) +'`'); + records = record_manager1.GetRecords(); + //Log(records[records.length-1]); + Sleep(60000); + } +} diff --git "a/\351\234\207\350\215\241\347\252\201\347\240\264\347\255\226\347\225\245 (\345\210\240\345\207\217B\345\200\274\350\247\246\345\217\221\345\271\263\344\273\223\343\200\201\345\212\250\346\200\201\350\260\203\346\225\264\350\247\246\345\217\221\345\200\274 \344\274\230\345\214\226ing) (\345\244\215\345\210\266)ttttttttt.js" "b/\351\234\207\350\215\241\347\252\201\347\240\264\347\255\226\347\225\245 (\345\210\240\345\207\217B\345\200\274\350\247\246\345\217\221\345\271\263\344\273\223\343\200\201\345\212\250\346\200\201\350\260\203\346\225\264\350\247\246\345\217\221\345\200\274 \344\274\230\345\214\226ing) (\345\244\215\345\210\266)ttttttttt.js" new file mode 100644 index 00000000..aed79193 --- /dev/null +++ "b/\351\234\207\350\215\241\347\252\201\347\240\264\347\255\226\347\225\245 (\345\210\240\345\207\217B\345\200\274\350\247\246\345\217\221\345\271\263\344\273\223\343\200\201\345\212\250\346\200\201\350\260\203\346\225\264\350\247\246\345\217\221\345\200\274 \344\274\230\345\214\226ing) (\345\244\215\345\210\266)ttttttttt.js" @@ -0,0 +1,532 @@ +/* +策略出处: https://www.botvs.com/strategy/23549 +策略名称: 震荡突破策略 (删减B值触发平仓、动态调整触发值 优化ing) (复制)ttttttttt +策略作者: 总值约: 23938.37 元 +策略描述: + +1、吃单优化为在触发值上挂单 +2、止损仓 在被套的情况下开启止损仓。 +3、动态阀值 +4、加入 STOCHRSI 指标 + + +参数 默认值 描述 +---------------- ----- ------------- +NPeriod 4 计算周期 +Ks 0.5 上轨系数 +Kx 0.5 下轨系数 +AmountOP true 开仓量 +Interval 2000 重试间隔(毫秒) +LoopInterval 3 轮询间隔(秒) +PeriodShow 500 图表最大显示K线柱数 +InitMoveStop -20 初始止损值 +step 5 滑动止损步长 +isShowTouchLine true 显示触发值 +isCurrentKLineOP true 是否允许当前K线平仓后交易 +*/ + +var ChartCfg = { + __isStock: true, + title: { + text: '震荡突破策略' + }, + yAxis: [{ + title: {text: 'KL'},//标题 + style: {color: '#4572A7'},//样式 + opposite: false, //生成右边Y轴 + plotLines: [{ + value: 0, + color: 'red', + width: 2, + label: { + text: '触发值A', + align: 'center' + }, + }, { + value: 0, + color: 'green', + width: 2, + label: { + text: '触发值B', + align: 'center' + }, + }] + }, + { + title:{text: "STOCHRSI"}, + opposite: true //生成右边Y轴 ceshi + } + ], + series: [{ + type: 'candlestick', + name: '当前周期', + id: 'primary', + data: [] + }, { + type: 'flags', + onSeries: 'primary', + data: [], + },{ + type: 'spline', + yAxis: 1, + name: 'F', + data: [] + },{ + type: 'spline', + yAxis: 1, + name: 'S', + data: [] + }] +}; + +/* +plotLines: [{ + value: 0, + color: 'red', + width: 2, + label: { + text: '触发值A', + align: 'center' + }, + }, { + value: 0, + color: 'green', + width: 2, + label: { + text: '触发值B', + align: 'center' + }, + }] +*/ +var STATE_IDLE = 0; +var STATE_LONG = 1; +var STATE_SHORT = 2; +var State = STATE_IDLE; + +var LastBarTime = 0; +var UpTrack = 0; +var BottomTrack = 0; +var chart = null; +var InitAccount = null; +var Counter = { + w: 0, + l: 0 +}; + +function LLV(array,period){ + if(!array || array.length - period < 0){ + throw "error:" + array; + } + var min = array[array.length - period]; + for(var i = array.length - period; i < array.length; i++){ + if( array[i] < min ){ + min = array[i]; + } + } + return min; +} + +function HHV(array,period){ + if(!array || array.length - period < 0){ + throw "error:" + array; + } + var max = array[array.length - period]; + for(var i = array.length - period; i < array.length; i++){ + if( array[i] > max){ + max = array[i]; + } + } + return max; +} + +function DeleteNullEle(initArr){ + var dealArr = []; + var initArrLen = initArr.length; + for(var i = 0,j = 0 ; i < initArrLen ; i++,j++){ + if(initArr[i] === null || isNaN(initArr[i]) ){ + j--; + continue; + } + dealArr[j] = initArr[i]; + } + return dealArr; +} + +function FstochRSI(records,n,m,p1,p2){ + var len = records.length; + //var LC = records[len-2];//上一周期收盘价 + //var rsi = TA.RSI(records,n);// RSI 数组 ,talib + var rsi = talib.RSI(records,n); + rsi = DeleteNullEle(rsi);//ceshi + + var arr1 = []; + var arr2 = []; + var arr3 = []; + var arr4 = []; + var rsi_a = []; + var rsi_b = []; + var k = []; + var d = null; + + for(var a = 0 ;a < rsi.length ; a++ ){//改造 不用 LLV + if(a < m){ + continue; + } + for(var aa = 0 ; aa <= a; aa++ ){ + rsi_a.push(rsi[aa]); + } + arr1.push(rsi[a] - LLV(rsi_a,m)); + } + for(var b = 0 ;b < rsi.length ; b++ ){//改造 不用 HHV + if(b < m){ + continue; + } + for(var bb = 0 ; bb <= b; bb++ ){ + rsi_b.push(rsi[bb]); + } + arr2.push(HHV(rsi_b,m) - LLV(rsi_b,m)); + } + + arr1 = DeleteNullEle(arr1); + arr2 = DeleteNullEle(arr2); + //Log("arr1:",arr1.length,"-",arr1);//ceshi + //Log("arr2:",arr2.length,"-",arr2);//ceshi + + arr3 = talib.MA(arr1,p1); + arr4 = talib.MA(arr2,p1); + + arr3 = DeleteNullEle(arr3); + arr4 = DeleteNullEle(arr4); + + //Log("ceshi");//ceshi + var c = 0; + var diff = 0; + if(arr3.length !== arr4.length){//实测 长度不相等 + throw "error: !=" + arr3.length + "----" + arr4.length; + diff = arr4.length - arr3.length; //example diff = 10 - 6 + }else{ + //throw "error:" + arr3.length + "----" + arr4.length; + } + + for( ;c < arr3.length ; c++ ){ + k.push(arr3[c] / arr4[c + diff] * 100); + } + + d = talib.MA(k,p2); + + return [k,d,rsi]; +} + +function CancelPendingOrders() { + while (true) { + var orders = exchange.GetOrders(); + for (var i = 0; i < orders.length; i++) { + exchange.CancelOrder(orders[i].Id); + Sleep(Interval); + } + if (orders.length === 0) { + break; + } + } +} + +var isBegin = false; +var isTrade_OC = false; +var stochrsiFast = 0; +var stochrsiSlow = 0; +function onTick(exchange) { + var records = exchange.GetRecords(); + if (!records || (records.length < 50 || records.length <= NPeriod)) { //默认 STOCHRSI 指标 最大周期14 限制 + return; + } + //Log(records.length);//ceshi + //throw "stop"; //ceshi + + var stochrsi = FstochRSI(records,14,14,3,3); // 计算 STOCHRSI 指标 + var Bar = records[records.length - 1]; + if (LastBarTime !== Bar.Time) { + isTrade_OC = false; + var HH = TA.Highest(records, NPeriod, 'High'); + var HC = TA.Highest(records, NPeriod, 'Close'); + var LL = TA.Lowest(records, NPeriod, 'Low'); + var LC = TA.Lowest(records, NPeriod, 'Close'); + + var Range = Math.max(HH - LC, HC - LL); + + UpTrack = _N(Bar.Open + (Ks * Range)); + DownTrack = _N(Bar.Open - (Kx * Range)); + //更新触发值 + table.a3 = UpTrack; + table.b3 = DownTrack; + + if (LastBarTime > 0) { + var PreBar = records[records.length - 2]; + chart.add(0, [PreBar.Time, PreBar.Open, PreBar.High, PreBar.Low, PreBar.Close], -1); + chart.add(2,[records[records.length - 2].Time,stochrsi[0][stochrsi[0].length - 2]], -1); //增加 快线 + chart.add(3,[records[records.length - 2].Time,stochrsi[1][stochrsi[1].length - 2]], -1); //增加 慢线 + } else { + for (var i = Math.min(records.length, NPeriod * 3); i > 1; i--) { + var b = records[records.length - i]; + //Log(stochrsi[0][stochrsi[0].length - 1],stochrsi[1][stochrsi[1].length - 1]);//ceshi + chart.add(0, [b.Time, b.Open, b.High, b.Low, b.Close]); + if(isBegin === false){ + chart.add(1, {x:(new Date()).getTime(), color: "black", shape: 'flag', title: "title", text: "开始"}); + isBegin = true; + } + //chart.add(2,[records[records.length - 1].Time,stochrsi[0][stochrsi[0].length - 1]]); //增加快线 + //chart.add(3,[records[records.length - 1].Time,stochrsi[1][stochrsi[1].length - 1]]); //增加慢线 + } + } + chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close]); + chart.add(2,[records[records.length - 2].Time,stochrsi[0][stochrsi[0].length - 2]]); //增加 快线 + chart.add(3,[records[records.length - 2].Time,stochrsi[1][stochrsi[1].length - 2]]); //增加 慢线 + if(isShowTouchLine === true){//是否显示触发值 + ChartCfg.yAxis[0].plotLines[0].value = UpTrack; + ChartCfg.yAxis[0].plotLines[1].value = DownTrack; + } + ChartCfg.subtitle = { + text: '触发值A: ' + UpTrack + ' 触发值B: ' + DownTrack + }; + chart.update(ChartCfg); + //chart.reset(PeriodShow); //ceshi 取消 + LastBarTime = Bar.Time; + } else { + chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close], -1); + chart.add(2,[records[records.length - 1].Time,stochrsi[0][stochrsi[0].length - 1]], -1); // 增加 快线 + chart.add(3,[records[records.length - 1].Time,stochrsi[1][stochrsi[1].length - 1]], -1); // 增加 慢线 + } + //Log(stochrsi);//ceshi + //LogStatus("Price:", Bar.Close, "Up:", UpTrack, "Down:", DownTrack, "Wins: ", Counter.w, "Losses:", Counter.l, "Date:", new Date(),"\n",NowPositionInfo); + var msg; + var fcolor = null; + var ftitle = ""; + stochrsiFast = table.a6 = stochrsi[0][stochrsi[0].length - 1]; + stochrsiSlow = table.b6 = stochrsi[1][stochrsi[1].length - 1]; + if((isTrade_OC === true && isCurrentKLineOP === false) && ( isTurnOP_Long === false && isTurnOP_Short === false ) ){//是否允许当前K线交易,排除反手的条件 + return; + } + + + if (State === STATE_IDLE) { + if ( isTurnOP_Long || (Bar.Close >= UpTrack && stochrsiFast < 30 && isTurnOP_Short === false) ) { // 加入STOCHRSI 控制 + msg = '做多 触发价: ' + Bar.Close + ' 触发值A:' + UpTrack + "stochrsiFast" + stochrsiFast; + if(isTurnOP_Long === true){ + msg = "反手做多" + msg + "#FF0000"; + } + Log(msg); + buyInfo = $.Buy(AmountOP); + State = STATE_LONG; + Log("buyInfo:",buyInfo); + if(buyInfo === null){ + return; + } + if(NowPositionInfo.direction === NONE){ + NowPositionInfo.direction = LONG; + fcolor = 'red'; + ftitle = 'L'; + moveStop = InitMoveStop; //设置 默认止损额度 + moveLevel = 0; + lastMoveStop = 0; + } + chart.add(1, {x:(new Date()).getTime(), color: fcolor, shape: 'flag', title: ftitle, text: msg}); + } + } + + if (State === STATE_IDLE) { + if ( isTurnOP_Short || (Bar.Close <= DownTrack && stochrsiFast > 70 && isTurnOP_Long === false) ) {//是否触发 反手 加入 STOCHRSI 控制 + msg = '做空 触发价: ' + Bar.Close + ' 触发值B:' + DownTrack + "stochrsiFast" + stochrsiFast; + if(isTurnOP_Short === true){ + msg = "反手做空" + msg + "#FF0000"; + } + Log(msg); + sellInfo = $.Sell(AmountOP); + Log("sellInfo:",sellInfo); + if(sellInfo === null){ + return; + } + State = STATE_SHORT; + if(NowPositionInfo.direction === NONE){ + NowPositionInfo.direction = SHORT; + fcolor = 'green'; + ftitle = 'S'; + moveStop = InitMoveStop; //设置默认止损额度 + moveLevel = 0; + lastMoveStop = 0; + } + chart.add(1, {x:(new Date()).getTime(), color: fcolor, shape: 'circlepin', title: ftitle, text: msg}); + } + } + //滑动止损 + if( (State === STATE_SHORT && NowPositionInfo.direction === SHORT ) || ( NowPositionInfo.direction === LONG && State === STATE_LONG) ){ + if(NowPositionInfo.floatProfit > step){//滑动止损 结束后 lastMoveStop 要赋值 0 , moveLevel 要赋值 0 , moveStop 重新赋值初始止损值 + moveStop = 0; + if(NowPositionInfo.floatProfit - lastMoveStop > step){ + lastMoveStop = (++moveLevel) * step; + } + } + table.b5 = "lastLine" + lastMoveStop + ", Level" + moveLevel + " ,default" + moveStop; + //Log("NowPositionInfo",NowPositionInfo,"止损",moveStop + moveLevel * step); //ceshi + if(NowPositionInfo.floatProfit <= moveStop + moveLevel * step ){ + //cover + //Log("NowPositionInfo",NowPositionInfo,"止损",moveStop + moveLevel * step); //ceshi + if(NowPositionInfo.direction === SHORT){//空仓止损 + buyInfo = $.Buy(NowPositionInfo.amount); + if(buyInfo === null){ + return; + } + isTurnOP_Short = false;//重置 反手条件为false + isTurnOP_Long = false;//重置 反手条件为false + State = STATE_IDLE; + Log("止损平仓",NowPositionInfo,"moveStop + moveLevel * step",moveStop + moveLevel * step,_C(exchange.GetTicker),buyInfo);//ceshi + CalculateCounter(buyInfo);//处理Counter 计数 + NowPositionInfo.direction = NONE; + Calculate(); + InitAccount = _C(exchange.GetAccount); + LogProfit(Profit,InitAccount); + fcolor = 'blue'; + ftitle = '止损 平仓'; + msg = "moveLevel:" + moveLevel + ", lastMoveStop:" + lastMoveStop; + isTrade_OC = true;//当前bar 已经交易 + if(moveStop !== 0){//突破止损反手 + isTurnOP_Long = true; + } + } + if(NowPositionInfo.direction === LONG){//多仓止损 + sellInfo = $.Sell(NowPositionInfo.amount); + if(sellInfo === null){ + return; + } + isTurnOP_Long = false;//重置反手条件为false + isTurnOP_Short = false;//重置反手条件为false + State = STATE_IDLE; + Log("止损平仓",NowPositionInfo,"moveStop + moveLevel * step",moveStop + moveLevel * step,_C(exchange.GetTicker),sellInfo);//ceshi + CalculateCounter(sellInfo);//处理Counter 计数 + NowPositionInfo.direction = NONE; + Calculate(); + InitAccount = _C(exchange.GetAccount); + LogProfit(Profit,InitAccount); + fcolor = 'blue'; + ftitle = '止损 平仓'; + msg = "moveLevel:" + moveLevel + ", lastMoveStop:" + lastMoveStop; + isTrade_OC = true;//当前bar 已经交易 + if(moveStop !== 0){//突破止损反手 + isTurnOP_Short = true; + } + } + chart.add(1, {x:(new Date()).getTime(), color: fcolor, shape: 'circlepin', title: ftitle, text: msg}); + } + } +} + +//反手 +var isTurnOP_Long = false; +var isTurnOP_Short = false; + +//滑动止损 参数 +//var step = 5; //滑动步长 +var moveStop = InitMoveStop; //初始止损 +var lastMoveStop = 0; //上次止损挡位 +var moveLevel = 0; //止损等级 +//var OpAmount = 1;//ceshi +//var maxProfit = 0.2; +var buyInfo = null; +var sellInfo = null; +var SHORT = 2; +var LONG = 1; +var NONE = 0; +var NowPositionInfo = { // + avgPrice : 0 , + amount : 0, + floatProfit : 0, + direction : 0 // 0 未持仓 , 1多仓 , 2空仓 +}; + + +function CalculateCounter(CoverInfo) { + if(NowPositionInfo.direction === STATE_LONG && (CoverInfo.price - NowPositionInfo.avgPrice > 0)){//处理多仓 + Counter.w++; + }else if(NowPositionInfo.direction === STATE_LONG){ + Counter.l++; + } + if(NowPositionInfo.direction === STATE_SHORT && (NowPositionInfo.avgPrice - CoverInfo.price > 0)){//处理空仓 + Counter.w++; + }else if(NowPositionInfo.direction === STATE_SHORT){ + Counter.l++; + } + table.b4 = Counter; //更新 Counter +} + + +var Profit = 0; +function Calculate(nowAccount,nowDepth){//计算并更新收益 、 浮动收益 、计算 持仓均价 、持仓量 + if(typeof(nowAccount) === 'undefined' ){ + nowAccount = _C(exchange.GetAccount); + nowDepth = _C(exchange.GetDepth); + } + var diff_stocks = nowAccount.Stocks - InitAccount.Stocks;//币之差 + var diff_balance = nowAccount.Balance - InitAccount.Balance;//钱之差 + NowPositionInfo.avgPrice = _N(Math.abs(diff_balance) / Math.abs(diff_stocks),5); + //throw nowAccount.Stocks + "----" + nowAccount.Balance;//ceshi + NowPositionInfo.amount = _N(Math.abs(diff_stocks),5); + NowPositionInfo.floatProfit = _N(diff_balance + diff_stocks * (NowPositionInfo.direction === LONG?nowDepth.Bids[0].Price : nowDepth.Asks[0].Price),5); //此次交易的浮动盈亏 + Profit = (nowAccount.Stocks - beginAccount.Stocks) * (NowPositionInfo.direction === LONG?nowDepth.Bids[0].Price : nowDepth.Asks[0].Price) + (nowAccount.Balance - beginAccount.Balance); //总盈亏 + table.b1 = nowAccount;//更新当前的账户信息 + table.a5 = NowPositionInfo; + //更新入界面 +} + +var table = null; +function main() { + CancelPendingOrders(); + _CInterval = 200; + InitAccount = exchange.GetAccount();//上次平仓后账户信息 + beginAccount = InitAccount; //启动时账户信息 + LoopInterval = Math.min(1, LoopInterval); + //清空 + LogReset(); + LogProfitReset(); + chart = Chart(ChartCfg); + chart.reset(); + + Log('交易平台:', exchange.GetName(), InitAccount); + LogStatus("Ready..."); + Log(InitAccount); + + LoopInterval = Math.max(LoopInterval, 1); + //初始化表格 + table = $.TableInit(2,7); + table.a0 = "初始账户:↓"; + table.a1 = beginAccount; + table.b0 = "当前账户:↓"; + table.a2 = "触发值A:↓"; + table.b2 = "触发值B:↓"; + table.a4 = "NowPositionInfo:↓"; + //table.b4 = "stop"; + //table.a5 = "Counter:"; + + + var beginTime = 0; + while (true) { + beginTime = (new Date()).getTime(); + onTick(exchange); + /* //ceshi + if(NowPositionInfo.floatProfit < -5){ + Log("ticker:",_C(exchange.GetTicker),NowPositionInfo); + } + //ceshi + */ + Calculate(); + $.UpdateLogStatus("loop used time:" + ((new Date()).getTime() - beginTime) + "ms"); + Sleep(LoopInterval * 1000); + } +} + +/* +0.是否当前K线允许交易 处理还有问题 +1.触发平仓触发值,导致平仓,是否增加反转。 +2. 计算浮动盈亏的函数 +//改进 +1、动态 触发值调整,根据波动率 +2、参数 步长 、系数、试试 本K 重复开仓选项 +3、双仓 +*/ diff --git "a/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266 (Copy).js" "b/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266 (Copy).js" new file mode 100644 index 00000000..4422074c --- /dev/null +++ "b/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266 (Copy).js" @@ -0,0 +1,256 @@ +/* +策略出处: https://www.botvs.com/strategy/43579 +策略名称: (13)策略框架 (Copy) +策略作者: dsfaong +策略描述: + +策略框架 + + +参数 默认值 描述 +---------- ----- --------- +isLogReset true 启动时是否清除日志 + +按钮 默认值 描述 +------------ ---------- ------- +upDateAmount true 更新开仓量按钮 +cmdOpen __button__ 开仓命令 +cmdCover __button__ 平仓命令 +*/ + +var Interval = 500; +var _long = 1; +var free = 0; +var state = free; //每次开仓 平仓 重置 +var buyInfo = null; //每次平仓重置 +var sellInfo = null; //每次开仓重置 +var initAccount = null; //每次平仓重置 +var beginAccount = null; //不重置 +var Profit = 0; //已实现盈亏 +var prefloatProfit = 0;//上次的浮动盈亏,滑动止盈 更新 +var openBalance = 0;//开仓量 +var isCover = false; + +var tiaojian = 0; //这里可以设置 触发条件,比如 自定义的指标函数 发出开仓信号(比如返回了 数值 1 ), 比如 0 时 是等待, 等于 2 时 是平仓 + //也可能 触发了平仓条件 +var Amount = 1; //这里可以把 交易的量(币数) 写在程序里 自动控制(比如,根据盘口量), 也可以设置在界面上做成界面上的参数,在程序运行的时候传进来。 + +var NowPositionInfo = {//持仓信息, 每次平仓更新 + avgPrice: 0, + amount: 0 , + floatProfit: 0 +}; + +function openUpdate(){//开仓后的更新 + state = _long; + sellInfo = null; + tiaojian = 0;//重置条件 +} +function closeUpdate(){//平仓后的更新 + state = free; + addLevel = 0; + buyInfo = null; + initAccount = _C(exchange.GetAccount); + NowPositionInfo.avgPrice = 0; + NowPositionInfo.amount = 0; + NowPositionInfo.floatProfit = 0; + isCover = true; + tiaojian = 0;//重置条件 +} + +function Calculate(nowAccount,nowDepth){//计算并更新收益 、 浮动收益 、计算 持仓均价 、持仓量 + if(typeof(nowAccount) === 'undefined' ){ + nowAccount = _C(exchange.GetAccount); + nowDepth = _C(exchange.GetDepth); + } + var diff_stocks = nowAccount.Stocks - initAccount.Stocks;//币之差 + var diff_balance = nowAccount.Balance - initAccount.Balance;//钱之差 + NowPositionInfo.avgPrice = Math.abs(diff_balance) / Math.abs(diff_stocks); + NowPositionInfo.amount = Math.abs(diff_stocks); + NowPositionInfo.floatProfit = diff_balance + diff_stocks * nowDepth.Bids[0].Price; //此次交易的浮动盈亏 + Profit = (initAccount.Stocks - beginAccount.Stocks) * nowDepth.Bids[0].Price + (initAccount.Balance - beginAccount.Balance); //实现盈亏 + + //更新入界面 +} + +function get_Command(){//负责交互的函数,交互及时更新 相关数值 ,熟悉的用户可以自行扩展 + var keyValue = 0;// 命令传来的参数 数值 + var way = null; //路由 + var cmd = GetCommand(); //获取 交互命令API + if (cmd) { + Log("按下了按钮:",cmd);//日志显示 + arrStr = cmd.split(":"); // GetCommand 函数返回的 是一个字符串,这里我处理的麻烦了,因为想熟悉一下JSON ,所以先对字符串做出处理,把函数返回的字符串以 : 号分割成2个字符串。储存在字符串数组中。 + + if(arrStr.length === 2){//接受的不是 数值型的,是按钮型的。 + jsonObjStr = '{' + '"' + arrStr[0] + '"' + ':' + arrStr[1] + '}'; // 把 字符串数组中的元素重新 拼接 ,拼接成 JSON 字符串 用于转换为JSON 对象。 + jsonObj = JSON.parse(jsonObjStr); // 转换为JSON 对象 + + for(var key in jsonObj){ // 遍历对象中的 成员名 + keyValue = jsonObj[key]; //取出成员名对应的 值 , 就是交互按钮的值 + } + + if(arrStr[0] == "upDateAmount"){// 此处为 数字型 。这里处理分为 按钮 和 数字型 。 详见 策略参数 设置界面 下的 交互设置 + way = 1; + } + if(arrStr[0] == "扩展1"){ + way = 2; + } + if(arrStr[0] == "扩展2"){ + way = 3; + } + if(arrStr[0] == "扩展3"){ + way = 4; + } + }else if(arrStr.length === 1){// 此处为 按钮型 + //路由 + if(cmd == "cmdOpen"){ + way = 0; + } + if(cmd == "cmdCover"){ + way = 5; + } + }else{ + throw "error:" + cmd + "--" + arrStr; + } + switch(way){ // 分支选择 操作 + case 0://处理 发出开仓信号 + tiaojian = 1; + break; + case 1://处理 + Amount = keyValue;//把交互界面设置的 数值 传递给 Amount + Log("开仓量修改为:",Amount);//提示信息 + break; + case 2://处理 + + break; + case 3://处理 + + break; + case 4://处理 + + break; + case 5://处理 发出平仓信号 + tiaojian = 2; + break; + default: break; + } + } +} + +function Loop(){//循环主体 + //获取 行情、账户等信息 + var account = _C(exchange.GetAccount); + var records = _C(exchange.GetRecords); + var depth = _C(exchange.GetDepth); + var len = records.length - 1; + + //对获取的数据 容错处理 + if(records.length < 10 ){//这里可以对 API 获取的数据 容错处理,这里举个例子 就是 获取的K线长度 必须大于10,小于10了 就返回 不做处理并在界面显示提示信息。 + //输出到状态栏表格,显示K线长度不足 + msg = "K线长度不足,获取中..."; + return; + } + msg = "K line `s length:" + (len + 1); + + //图表模板的使用--------------- + $.Draw(records); + //--------------------------- + + + //第一次启动 处理的内容--------- + if(isFirst === true){ + $.SignOP((new Date()).getTime(),null,null,3,"图表显示启动!");// 测试标记 自定义信息 到图表上 + Log("程序启动!"); + isFirst = false; + } + //-------------------------- + + //策略运行时状态栏表格上的显示数据 table.b1 就是往 b1 这个格子里 写入 "stock:" + account.Stocks + "#ff00ff"; 这些数据,可以对比截图,自己动手试试。 + table.b1 = "stock:" + account.Stocks + "#ff00ff"; + table.c1 = "Fstock:" + account.FrozenStocks + "#ff00ff"; + table.d1 = "balance:" + account.Balance + "#ff00ff"; + table.e1 = "Fbalance:" + account.FrozenBalance + "#ff00ff"; + table.b2 = "open:" + records[len].Open; + table.c2 = "high:" + records[len].High; + table.d2 = "low:" + records[len].Low; + table.e2 = "close:" + records[len].Close; + table.b3 = "bids[0].price:" + depth.Bids[0].Price; + table.c3 = "bids[0].amount:" + depth.Bids[0].Amount; + table.d3 = "asks[0].price:" + depth.Asks[0].Price; + table.e3 = "asks[0].amount:" + depth.Asks[0].Amount; + table.c4 = "avgPrice:" + NowPositionInfo.avgPrice; + table.d4 = "amount:" + NowPositionInfo.amount; + table.e4 = "floatProfit:" + NowPositionInfo.floatProfit; + //------------------------------------------------------------------------- + + //处理 策略交互 + get_Command();//获取 并处理交互 + + + //这里可以自定义 触发 操作的代码,比如 指标交叉了(当然这是你自定义的), 就可以给 tiaojian 这个变量赋值 1, 即: tiaojian = 1; 这样下面满足条件就执行相应操作。 + + + if(state === free && tiaojian === 1 ){//开仓条件,可以自行扩展,指标形态、差价、交易量 等等 + //触发了上面的if括号内的条件,这个里面就是执行具体的开仓操作了,举个例子是用 数字货币交易类库 这个模板处理开仓。 + buyInfo = $.Buy(Amount); + if(buyInfo === null){// $.Buy这个函数 返回 null 说明有原因导致 没有买到(即没有开仓成功,原因有多个可能。) + return; + } + $.SignOP((new Date()).getTime(),buyInfo.price,buyInfo.amount,1);// 把操作标记 到图表上 . 图表模板 用法可以看论坛上的帖子 + openUpdate(); + }else if(state === _long && tiaojian === 2 ){ + sellInfo = $.Sell(NowPositionInfo.amount); + if(buyInfo === null){ + return; + } + $.SignOP((new Date()).getTime(),sellInfo.price,sellInfo.amount,0);// 把操作标记 到图表上 + closeUpdate(); + } + + + //如果平仓了,更新收益----------------------- + Calculate();//计算收益,更新持仓状态 + if(isCover === true){ + LogProfit(Profit); + isCover = false; + } + //---------------------------------------- + + //更新图表--------------------------- + $.UpDateChart(records); + //--------------------------------- +} + +var table = null; +var msg = "";//显示在状态栏表格头部的 消息 +var isFirst = true; + +function main(){ + //初始化 + if(isLogReset === true){ + LogReset(); + } + beginAccount = _C(exchange.GetAccount);//程序开始运行时的初始账户信息 + initAccount = beginAccount;//每次开仓前的账户信息 + table = $.TableInit(5,6); + //初始化表格 5,代表 表格生成5列 分别是 a b c d e , 6代表表格生成 6行 分别是 0 1 2 3 4 5 6 。 这样最左上角的表格单元的坐标就是 a0 , table.a0 = 3; 此时就会显示到相应的表格 + + //给表格写上不许要变动的内容------------------ + table.a1 = "account:" + "#ff00ff"; + table.a2 = "records[length-1]:"; + table.a3 = "depth.Bids[0]/Asks[0]:"; + table.a0 = "beginAccount:"; + table.b0 = "stock:" + beginAccount.Stocks; + table.c0 = "Fstock:" + beginAccount.FrozenStocks; + table.d0 = "balance:" + beginAccount.Balance; + table.e0 = "Fbalance:" + beginAccount.FrozenBalance; + //---------------------------------------------------- + + while(true){ + Loop();//循环函数 + $.UpDateLogStatus(msg);//更新表格 数据 + msg = ""; + Sleep(Interval); + } +} + From 7c402723f8f3898b1a7a33805c72864161226d8f Mon Sep 17 00:00:00 2001 From: botvs Date: Thu, 30 Nov 2017 19:47:11 +0800 Subject: [PATCH 02/19] update --- ...77\346\234\272\345\231\250\344\272\272.js" | 182 +++++ ...5\351\227\250 \347\255\226\347\225\245.js" | 353 ++++++++++ ...44\346\230\223\347\255\226\347\225\245.js" | 9 +- ...06\345\223\201\346\234\237\350\264\247.js" | 5 + ...60\350\264\247\347\211\210\357\274\211.js" | 293 -------- Hedge_BTC-ETH Demo.js | 157 +++++ "JS\347\211\210\346\234\254Dual Thrust.js" | 120 ++++ ...5\245_\344\275\216\351\242\221 (Copy).js" | 139 ---- ...346\215\237 (\345\244\215\345\210\266).js" | 199 ------ ...71\345\206\262\347\255\226\347\225\245.js" | 8 +- ...13\345\212\277\347\255\226\347\225\245.py" | 11 +- ...(\346\265\213\350\257\225\347\211\210).py" | 157 +++++ README.md | 78 +-- ...222\214okcoin\344\270\200\350\207\264).js" | 130 ++++ ...67\346\240\274\346\217\220\351\206\222.js" | 50 -- ...01\351\207\221\344\272\244\346\230\223.js" | 47 ++ ...05\245\346\214\201\346\234\211 (Copy).js" | 86 --- ...Thrust OKCoin \346\234\237\350\264\247.py" | 2 +- ...\272\223 (\345\205\274\345\256\2712-3).py" | 3 + ...13\350\257\225\347\211\210\357\274\211.py" | 2 +- ...44\346\230\223\347\261\273\345\272\223.py" | 21 +- ...7\346\240\207\346\241\206\346\236\266).js" | 333 +++++++++ ...vs rest (\345\244\215\345\210\266)5560.js" | 134 ---- ...00\347\233\256\345\235\207\350\241\241.js" | 231 +++++++ ...07\350\241\241\347\255\226\347\225\245.js" | 43 ++ ...14\226\347\255\226\347\225\245 (Copy).js" | 142 ---- ...44\346\230\223\347\263\273\347\273\237.js" | 5 + ...01\346\261\202\346\214\207\347\202\271.py" | 251 +++++++ ...\346\234\254(two platforms hedging-JS).js" | 225 ++++++ ...44\346\230\223\347\261\273\345\272\223.js" | 487 +++++++++++-- ...45R-Breaker (\345\244\215\345\210\266).js" | 106 --- ...77\347\224\250\350\214\203\344\276\213.js" | 28 + ...07\347\272\277\347\255\226\347\225\245.js" | 120 ++++ ...10\251 V2.1 (\345\244\215\345\210\266).js" | 305 -------- ...\217\212 Demo \347\250\213\345\272\217.js" | 106 +++ ...56\344\273\267\347\233\221\346\216\247.js" | 2 +- ...vs\345\256\236\347\216\260\347\211\210.py" | 630 +++++++++++++++++ ...1OKCoin\346\234\237\350\264\247-BitVC).js" | 33 +- ...\214\201$.CTA\345\207\275\346\225\260).js" | 284 +++++--- ...47\345\270\201\345\256\232\346\212\225.py" | 53 ++ ...21\346\216\247\345\210\206\346\236\220.js" | 471 +++++++++++++ ...44\346\230\223\347\261\273\345\272\223.js" | 211 ++++-- ...60\347\273\204\345\212\237\350\203\275.js" | 4 +- ...357\274\211 (\345\244\215\345\210\266).js" | 274 -------- ...73\347\272\277\347\261\273\345\272\223.js" | 3 + ...06\346\236\266\346\250\241\346\235\277.js" | 10 + ...07\347\272\277\347\255\226\347\225\245.js" | 52 ++ ...25\350\276\271\347\275\221\346\240\274.js" | 650 ++++++++++++++++++ ...345\212\250\346\203\205\345\206\2652.0.js" | 2 +- ...20\206\346\250\241\346\235\277 (Copy).js" | 305 -------- ...6\233\264\346\226\26020170531) (Copy).js" | 315 --------- ...7\221\346\233\264\346\226\26020171113).js" | 86 ++- ...g) (\345\244\215\345\210\266)ttttttttt.js" | 532 -------------- ...25\245\346\241\206\346\236\266 (Copy).js" | 256 ------- 54 files changed, 5310 insertions(+), 3431 deletions(-) create mode 100644 "2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.js" create mode 100644 "BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.js" delete mode 100644 "Dual Thrust \357\274\210\347\216\260\350\264\247\347\211\210\357\274\211.js" create mode 100644 Hedge_BTC-ETH Demo.js create mode 100644 "JS\347\211\210\346\234\254Dual Thrust.js" delete mode 100644 "KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221 (Copy).js" delete mode 100644 "MACD\344\275\216\344\271\260\351\253\230\345\215\226\350\207\252\345\212\250\350\267\237\345\215\225\346\273\221\345\212\250\346\255\242\346\215\237 (\345\244\215\345\210\266).js" create mode 100644 "Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" create mode 100644 "StochRSI(\345\222\214okcoin\344\270\200\350\207\264).js" delete mode 100644 "app\344\273\267\346\240\274\346\217\220\351\206\222.js" create mode 100644 "bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.js" delete mode 100644 "buy-hold \344\271\260\345\205\245\346\214\201\346\234\211 (Copy).js" create mode 100644 "stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).js" delete mode 100644 "\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest (\345\244\215\345\210\266)5560.js" create mode 100644 "\344\270\200\347\233\256\345\235\207\350\241\241.js" create mode 100644 "\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.js" delete mode 100644 "\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245 (Copy).js" create mode 100644 "\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.py" create mode 100644 "\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" delete mode 100644 "\345\233\275\345\244\226\347\237\245\345\220\215\347\255\226\347\225\245R-Breaker (\345\244\215\345\210\266).js" create mode 100644 "\345\235\207\347\272\277MA\346\214\207\346\240\207\344\275\277\347\224\250\350\214\203\344\276\213.js" create mode 100644 "\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.js" delete mode 100644 "\345\244\232\345\271\263\345\217\260\345\257\271\345\206\262\347\250\263\345\256\232\345\245\227\345\210\251 V2.1 (\345\244\215\345\210\266).js" create mode 100644 "\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.js" create mode 100644 "\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.py" rename "\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC) (\345\244\215\345\210\266).js" => "\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" (63%) create mode 100644 "\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.py" create mode 100644 "\346\225\260\345\255\227\350\264\247\345\270\201\345\267\256\344\273\267\347\233\221\346\216\247\345\210\206\346\236\220.js" delete mode 100644 "\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211 (\345\244\215\345\210\266).js" create mode 100644 "\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.js" create mode 100644 "\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" delete mode 100644 "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277 (Copy).js" delete mode 100644 "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170531) (Copy).js" rename "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170622).js" => "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020171113).js" (78%) delete mode 100644 "\351\234\207\350\215\241\347\252\201\347\240\264\347\255\226\347\225\245 (\345\210\240\345\207\217B\345\200\274\350\247\246\345\217\221\345\271\263\344\273\223\343\200\201\345\212\250\346\200\201\350\260\203\346\225\264\350\247\246\345\217\221\345\200\274 \344\274\230\345\214\226ing) (\345\244\215\345\210\266)ttttttttt.js" delete mode 100644 "\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266 (Copy).js" diff --git "a/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.js" "b/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.js" new file mode 100644 index 00000000..855f1add --- /dev/null +++ "b/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.js" @@ -0,0 +1,182 @@ +/* +策略出处: https://www.botvs.com/strategy/1088 +策略名称: 2014年的简易短线机器人 +策略作者: botvsing +策略描述: + +**策略的介绍** + +策略分享地址: +https://www.botvs.com/strategy/1088 +这个策略是我做虚拟货币以来的主要策略,后面经过不断完善和修改,复杂了很多,但主要思想并没有改变,分享的这个版本是无明显bug的 最初版本,最为简单清晰,没有仓位管理,每次交易都是满仓,没有卡死后重启等等,但也足够说明问题。 +策略从2014年8月运行,直到今年年初交易所收手续费。期间运行的还算很好,亏损的时间很少。资金从最初的200元跑到了80比特币。具体的过程可以看[小草的新浪博客](http://blog.sina.com.cn/u/2389357153)里[虚拟货币自动化交易之路](http://blog.sina.com.cn/s/blog_8e6ab2610102v6sq.html)系列文章。 + +**为什么分享这个策略** + +1.交易所收取手续费后,几乎杀死了所有的高频策略,我的也不例外。但策略改改也许还能用,大家可以研究一下。 +2.好久没有分享东西了,这篇文章早就想写了。 +3.和大家共同交流学习。 + +**策略的原理** + +这个策略原理极为简单,可以理解为准高频的做市策略,各位看了之后可能想打人,这都能赚钱,当时几乎谁都能写出来。我开始也没预料到它能这么有效,可见心中有想法要赶紧付出实践,说不一定有意外之喜。在比特币机器人初兴的2014年,写出赚钱的策略太容易了。 +和所有的高频策略一样,本策略也是基于orderbook,下图就是一个典型的比特币交易所的订单分布, + https://dn-filebox.qbox.me/0d8ec18c831404d3d1c19e17299c78017abcfd48.png +可以看到左侧是买单,显示了不同价格的挂单数量,右侧是卖单。可以想象如果一个人要买入比特币,如果不想挂单等待的话,只能选择吃单,如果他的单子比较多,会使得卖单挂单大量成交,对价格造成冲击,但是这种冲击一般不会一直持续,还有人想吃单卖出,价格在极短时间很可能还会恢复,反过来理解有人要卖币也类似。 +以图中的挂单为例,如果要直接买入5个币,那么价格会达到10377,在这时如果有人要直接卖出5个币,价格会达到10348,这个空间就是利润空间.策略会在稍低于10377的价格挂单,如10376.99,同时会以稍高于10348的价格买入,如10348.01,这是如果刚才的情况发生了,显然就会赚到其中的差价。虽然不会每次都如此完美,但在概率的作用下,赚钱的几率实际高得惊人。 +以现在策略的参数讲解一下具体操作,这个参数当然无法使用了,仅作一个说明。它会向上寻找累计卖挂单量为8个币的价格,这里是10377,那么此时的卖价就是这个价格减去0.01(减去多少可以是随机的),同理向下寻找累计买挂单为8个币,这里是10348,那么此时的卖价就是10348.01,此时买卖价的差价是10376.99-10348.01=28.98,大于策略预设的差价1.5,就以这两个价格挂单等待成交,如果价差小于1.5,也会找一个价格进行挂单,如盘口价格加减10,等待捡漏(更合适的应该是继续往下找跟多的深度)。 + +**进一步的说明** + +1. 没有钱或币了怎么办? +这种情况在我的钱较少是十分普遍,大多数时候只挂一边的单子,但不是大问题。其实可以加入币钱平衡的逻辑,但在平衡的过程难免产生损失,毕竟每一次的成交都是概率的垂青,我选择保持单边等待成交,当然这样也浪费了另一边的成交机会。 +2. 仓位是如何管理的? +刚开始都是满仓买入卖出,后来根据不同的参数分为不同的组,不会一次完全成交。 +3. 没有止损吗? +策略有完整的买卖挂单的逻辑,我认为不需要止损(可以讨论),还有就是概率的垂青,成交就是机会,止损可惜了。 +4. 如何调整为赚币的策略? +此时的参数是对称的,即向上8个币的累计卖单,向下8个币的累计买单,稍微不平衡一下,比如向上改为15个币的累计卖单,使得卖币机会更难得,有更大的几率会以更低的价格接回来,这样就会赚币,反过来就赚钱。实际上前期策略如此有效,币和钱都是增加的。 + +**代码讲解** + +完整的代码可以见我在www.botvs.com得策略分享,这里只讲解核心逻辑函数。在没有改动的情况下,在botvs自带的模拟盘竟然运转完全正常,这是一个3年多前的策略,平台还支持到现在,太让人感动了。 +首先是获取买卖价函数GetPrice(),需要获取订单深度信息,注意不同平台的订单深度信息长度不同,以及即使遍历了所有订单仍然没有所需要的量的情况(在后期许多0.01的网格挂单会导致这种情况),调用是GetPrice('Buy')就是获取买价。 +``` +function GetPrice(Type) { + //_C()是平台的容错函数 + var depth=_C(exchange.GetDepth); + var amountBids=0; + var amountAsks=0; + //计算买价,获取累计深度达到预设的价格 + if(Type=="Buy"){ + for(var i=0;i<20;i++){ + amountBids+=depth.Bids[i].Amount; + //参数floatamountbuy是预设的累计深度 + if (amountBids>floatamountbuy){ + //稍微加0.01,使得订单排在前面 + return depth.Bids[i].Price+0.01;} + } + } + //同理计算卖价 + if(Type=="Sell"){ + for(var j=0; j<20; j++){ + amountAsks+=depth.Asks[j].Amount; + if (amountAsks>floatamountsell){ + return depth.Asks[j].Price-0.01;} + } + } + //遍历了全部深度仍未满足需求,就返回一个价格,以免出现bug + return depth.Asks[0].Price +} +``` +每个循环的主函数onTick(),这里定的循环时间3.5s,每次循环都会把原来的单子撤销,重新挂单,越简单越不会遇到bug. +``` +function onTick() { + var buyPrice = GetPrice("Buy"); + var sellPrice= GetPrice("Sell"); + //diffprice是预设差价,买卖价差如果小于预设差价,就会挂一个相对更深的价格 + if ((sellPrice - buyPrice) <= diffprice){ + buyPrice-=10; + sellPrice+=10;} + //把原有的单子全部撤销,实际上经常出现新的价格和已挂单价格相同的情况,此时不需要撤销 + CancelPendingOrders() + //获取账户信息,确定目前账户存在多少钱和多少币 + var account=_C(exchange.GetAccount); + //可买的比特币量,_N()是平台的精度函数 + var amountBuy = _N((account.Balance / buyPrice-0.1),2); + //可卖的比特币量,注意到没有仓位的限制,有多少就买卖多少,因为我当时的钱很少 + var amountSell = _N((account.Stocks),2); + if (amountSell > 0.02) { + exchange.Sell(sellPrice,amountSell);} + if (amountBuy > 0.02) { + exchange.Buy(buyPrice, amountBuy);} + //休眠,进入下一轮循环 + Sleep(sleeptime); +} +``` + +**尾巴** + +整个程序也就40多行,看上去十分简单,但当时也花了我一个多星期,这还是在botvs平台上情况下。最大的优势还是起步早,在2014年,市场上以搬砖为主,网格和抢盘口的高频也不多,使得策略如鱼得水,后来竞争不可避免越来越激烈,我的钱也越来越多,面临的挑战很多,每隔一段时间都要进行较大的改动来应对,但总体还算顺利。在交易平台不收取手续费的情况下,是程序化交易的天堂,散户因为不收手续费跟倾向于操作,为高频和套利提供了空间,这一切也基本随着动辄0.1-0.2%的双向手续费终结了,不仅是自己被收费的问题,而是整个市场活跃度下降。 +但不需要高频的量化策略任然有很大的空间。 + + +参数 默认值 描述 +--------------- ------ ---- +sleeptime 3500 休眠时间 +floatamountbuy 8 买单深度 +floatamountsell 8 卖单高度 +diffprice 1.5 套利差价 +*/ + +/* +就是我刚开始编写机器人的源代码,几乎没有改动,参数也是原来的参数。这个版本的程序有许多 +需要改进的地方,但即使如此,它也当时表现除了惊人的盈利能力,在我本金不多时,不加杠杆平 +均每天盈利在5%左右。当然无论从哪一方面,它都不适应今天的市场。 +我同时也发了一篇文章在社区,大家可以看看。 +by 小草 +*/ + +//稍微改了一下,用了平台的容错函数_C(),和精度函数_N(). +//取消全部订单 +function CancelPendingOrders() { + var orders = _C(exchange.GetOrders); + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]);} +} + +//计算将要下单的价格 +function GetPrice(Type) { + var depth=_C(exchange.GetDepth); + var amountBids=0; + var amountAsks=0; + //计算买价,获取累计深度达到预设的价格 + if(Type=="Buy"){ + for(var i=0;i<20;i++){ + amountBids+=depth.Bids[i].Amount; + //floatamountbuy就是预设的累计买单深度 + if (amountBids>floatamountbuy){ + //稍微加0.01,使得订单排在前面 + return depth.Bids[i].Price+0.01;} + } + } + //同理计算卖价 + if(Type=="Sell"){ + for(var j=0; j<20; j++){ + amountAsks+=depth.Asks[j].Amount; + if (amountAsks>floatamountsell){ + return depth.Asks[j].Price-0.01;} + } + } + //遍历了全部深度仍未满足需求,就返回一个价格,以免出现bug + return depth.Asks[0].Price +} + +function onTick() { + var buyPrice = GetPrice("Buy"); + var sellPrice= GetPrice("Sell"); + //买卖价差如果小于预设值diffprice,就会挂一个相对更深的价格 + if ((sellPrice - buyPrice) <= diffprice){ + buyPrice-=10; + sellPrice+=10;} + //把原有的单子全部撤销,实际上经常出现新的价格和已挂单价格相同的情况,此时不需要撤销 + CancelPendingOrders() + //获取账户信息,确定目前账户存在多少钱和多少币 + var account=_C(exchange.GetAccount); + //可买的比特币量 + var amountBuy = _N((account.Balance / buyPrice-0.1),2); + //可卖的比特币量,注意到没有仓位的限制,有多少就买卖多少,因为我当时的钱很少 + var amountSell = _N((account.Stocks),2); + if (amountSell > 0.02) { + exchange.Sell(sellPrice,amountSell);} + if (amountBuy > 0.02) { + exchange.Buy(buyPrice, amountBuy);} + //休眠,进入下一轮循环 + Sleep(sleeptime); +} + +function main() { + while (true) { + onTick(); + } +} diff --git "a/BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.js" "b/BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.js" new file mode 100644 index 00000000..17c92497 --- /dev/null +++ "b/BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.js" @@ -0,0 +1,353 @@ +/* +策略出处: https://www.botvs.com/strategy/59120 +策略名称: BotVS 商品期货 量化 测试入门 策略 +策略作者: 小小梦 +策略描述: + +知乎专栏 文章: +via. https://zhuanlan.zhihu.com/p/30880706 + + +参数 默认值 描述 +---------------- ------ ------ +_Interval 500 轮询间隔 +_StrContractType rb1801 测试合约代码 + +按钮 默认值 描述 +---------------- ------------------- -------------- +changeSymbol MA801 更改商品期货合约代码 +OPEN_LONG true 开多 +OPEN_SHORT true 开空 +COVER true 按数量平仓 +GET_PNEDING __button__ 获取当前合约未完成的订单 +GET_ORDER 空 获取当前合约指定id 的订单 +GET_POSITION 空 获取当前合约持仓信息 +GET_ALL_POSITION __button__ 获取所有合约持仓信息 +CANCEL_ORDER 空 取消订单 +JS_CODE Log("call js code") 调用 JS 代码 +*/ + +// 商品期货 测试 程序 +/* +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) + } +} diff --git "a/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" "b/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" index ae783c37..ade34246 100644 --- "a/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" +++ "b/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" @@ -44,6 +44,12 @@ KeepRatio 10 暂停/继续 __button__ 暂停/继续 */ +/*backtest +start: 2016-03-01 +end: 2016-12-30 +period: 60 +*/ + var _bot = $.NewPositionManager(); var TTManager = { @@ -426,7 +432,8 @@ var TTManager = { obj.status.st++; } else if (-spread > (IncSpace * obj.N)) { opCode = obj.marketPosition > 0 ? 1 : 2; - } else if (records.length > obj.leavePeriod) { + } + if (opCode == 0 && records.length > obj.leavePeriod) { obj.status.leavePrice = obj.marketPosition > 0 ? TA.Lowest(records, obj.leavePeriod, 'Low') : TA.Highest(records, obj.leavePeriod, 'High'); if ((obj.marketPosition > 0 && lastPrice < obj.status.leavePrice) || (obj.marketPosition < 0 && lastPrice > obj.status.leavePrice)) { diff --git "a/Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.js" "b/Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.js" index d43fd9c2..44ade495 100644 --- "a/Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.js" +++ "b/Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.js" @@ -33,6 +33,11 @@ NotifyWX true 下单微信通知 CoverAll false 启动策略时清空合约仓位 */ +/*backtest +start: 2016-01-15 09:00:00 +end: 2017-01-01 15:00:00 +period: 1d +*/ var ChartCfg = { __isStock: true, title: { diff --git "a/Dual Thrust \357\274\210\347\216\260\350\264\247\347\211\210\357\274\211.js" "b/Dual Thrust \357\274\210\347\216\260\350\264\247\347\211\210\357\274\211.js" deleted file mode 100644 index 48371f34..00000000 --- "a/Dual Thrust \357\274\210\347\216\260\350\264\247\347\211\210\357\274\211.js" +++ /dev/null @@ -1,293 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/21583 -策略名称: Dual Thrust (现货版) -策略作者: 小小梦 -策略描述: - -Dual Thrust 策略包含完整的图表显示, 图表动态更新,模板引用等功能, 可做学习模板使用. - - -参数 默认值 描述 ------------- ----- ---------- -NPeriod 4 计算周期 -Ks 0.5 上轨系数 -Kx 0.5 下轨系数 -AmountOP true 开仓量 -Interval 2000 重试间隔(毫秒) -LoopInterval 3 轮询间隔(秒) -PeriodShow 500 图表最大显示K线柱数 -maxProfit 0.5 止盈值 -*/ - -var ChartCfg = { - __isStock: true, - title: { - text: 'Dual Thrust 上下轨图' - }, - yAxis: { - plotLines: [{ - value: 0, - color: 'red', - width: 2, - label: { - text: '上轨', - align: 'center' - }, - }, { - value: 0, - color: 'green', - width: 2, - label: { - text: '下轨', - align: 'center' - }, - }] - }, - series: [{ - type: 'candlestick', - name: '当前周期', - id: 'primary', - data: [] - }, { - type: 'flags', - onSeries: 'primary', - data: [], - }] -}; - -var STATE_IDLE = 0; -var STATE_LONG = 1; -var STATE_SHORT = 2; -var State = STATE_IDLE; - -var LastBarTime = 0; -var UpTrack = 0; -var BottomTrack = 0; -var chart = null; -var InitAccount = null; -var Counter = { - w: 0, - l: 0 -}; - -function _N(v) { - return Decimal(v).toSD(4, 1).toNumber(); -} - -function CancelPendingOrders() { - while (true) { - var orders = exchange.GetOrders(); - for (var i = 0; i < orders.length; i++) { - exchange.CancelOrder(orders[i].Id); - Sleep(Interval); - } - if (orders.length === 0) { - break; - } - } -} - -var isTrade_OC = false; -function onTick(exchange) { - var records = exchange.GetRecords(); - if (!records || records.length <= NPeriod) { - return; - } - var Bar = records[records.length - 1]; - if (LastBarTime !== Bar.Time) { - isTrade_OC = false; - var HH = TA.Highest(records, NPeriod, 'High'); - var HC = TA.Highest(records, NPeriod, 'Close'); - var LL = TA.Lowest(records, NPeriod, 'Low'); - var LC = TA.Lowest(records, NPeriod, 'Close'); - - var Range = Math.max(HH - LC, HC - LL); - - UpTrack = _N(Bar.Open + (Ks * Range)); - DownTrack = _N(Bar.Open - (Kx * Range)); - if (LastBarTime > 0) { - var PreBar = records[records.length - 2]; - chart.add(0, [PreBar.Time, PreBar.Open, PreBar.High, PreBar.Low, PreBar.Close], -1); - } else { - for (var i = Math.min(records.length, NPeriod * 3); i > 1; i--) { - var b = records[records.length - i]; - chart.add(0, [b.Time, b.Open, b.High, b.Low, b.Close]); - } - } - chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close]); - ChartCfg.yAxis.plotLines[0].value = UpTrack; - ChartCfg.yAxis.plotLines[1].value = DownTrack; - ChartCfg.subtitle = { - text: '上轨: ' + UpTrack + ' 下轨: ' + DownTrack - }; - chart.update(ChartCfg); - chart.reset(PeriodShow); - - LastBarTime = Bar.Time; - } else { - chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close], -1); - } - - LogStatus("Price:", Bar.Close, "Up:", UpTrack, "Down:", DownTrack, "Wins: ", Counter.w, "Losses:", Counter.l, "Date:", new Date(),"\n",NowPositionInfo); - var msg; - var fcolor = null; - var ftitle = ""; - if(isTrade_OC === true){ - return; - } - - if (State === STATE_IDLE || State === STATE_SHORT) { - if (Bar.Close >= UpTrack) { - msg = '做多 触发价: ' + Bar.Close + ' 上轨:' + UpTrack; - Log(msg); - buyInfo = $.Buy(AmountOP); //Trade(State, STATE_LONG); - State = STATE_LONG; - Log("buyInfo:",buyInfo); - if(buyInfo === null){ - return; - } - //chart.add(1, {x:Bar.Time, color: 'red', shape: 'flag', title: '多', text: msg}); - if(NowPositionInfo.direction === NONE){ - NowPositionInfo.direction = LONG; - fcolor = 'red'; - ftitle = '多'; - }else if(NowPositionInfo.direction === SHORT){ - State = STATE_IDLE; - NowPositionInfo.direction = NONE; - Calculate(); - //Profit = (nowAccount.Stocks - beginAccount.Stocks) * (NowPositionInfo.direction === SHORT?nowDepth.Bids[0].Price : nowDepth.Asks[0].Price) + (beginAccount.Balance - nowAccount.Balance); //总盈亏 - InitAccount = _C(exchange.GetAccount); - LogProfit(Profit,InitAccount); - fcolor = 'blue'; - ftitle = '平'; - isTrade_OC = true;//当前bar 已经交易 - } - chart.add(1, {x:Bar.Time, color: fcolor, shape: 'flag', title: ftitle, text: msg}); - } - } - - if (State === STATE_IDLE || State === STATE_LONG) { - if (Bar.Close <= DownTrack) { - msg = '做空 触发价: ' + Bar.Close + ' 下轨:' + DownTrack; - Log(msg); - sellInfo = $.Sell(AmountOP); //Trade(State, STATE_SHORT); - //chart.add(1, {x:Bar.Time, color: 'green', shape: 'circlepin', title: '空', text: msg}); - Log("sellInfo:",sellInfo); - if(sellInfo === null){ - return; - } - State = STATE_SHORT; - if(NowPositionInfo.direction === NONE){ - NowPositionInfo.direction = SHORT; - fcolor = 'green'; - ftitle = '空'; - }else if(NowPositionInfo.direction === LONG){ - State = STATE_IDLE; - NowPositionInfo.direction = NONE; - Calculate(); - //Profit = (nowAccount.Stocks - beginAccount.Stocks) * (NowPositionInfo.direction === SHORT?nowDepth.Bids[0].Price : nowDepth.Asks[0].Price) + (beginAccount.Balance - nowAccount.Balance); //总盈亏 - InitAccount = _C(exchange.GetAccount); - LogProfit(Profit,InitAccount); - fcolor = 'blue'; - ftitle = '平'; - isTrade_OC = true;//当前bar 已经交易 - } - chart.add(1, {x:Bar.Time, color: fcolor, shape: 'circlepin', title: ftitle, text: msg}); - } - } - - if( (State === STATE_SHORT && NowPositionInfo.direction === SHORT ) || ( NowPositionInfo.direction === LONG && State === STATE_LONG) ){ - if(NowPositionInfo.floatProfit >= maxProfit ){ - //cover - if(NowPositionInfo.direction === SHORT){ - buyInfo = $.Buy(NowPositionInfo.amount); - if(buyInfo === null){ - return; - } - State = STATE_IDLE; - NowPositionInfo.direction = NONE; - Calculate(); - InitAccount = _C(exchange.GetAccount); - LogProfit(Profit,InitAccount); - fcolor = 'blue'; - ftitle = '止盈 平仓'; - isTrade_OC = true;//当前bar 已经交易 - } - if(NowPositionInfo.direction === LONG){ - sellInfo = $.Sell(NowPositionInfo.amount); - if(sellInfo === null){ - return; - } - State = STATE_IDLE; - NowPositionInfo.direction = NONE; - Calculate(); - InitAccount = _C(exchange.GetAccount); - LogProfit(Profit,InitAccount); - fcolor = 'blue'; - ftitle = '止盈 平仓'; - isTrade_OC = true;//当前bar 已经交易 - } - chart.add(1, {x:Bar.Time, color: fcolor, shape: 'circlepin', title: ftitle, text: msg}); - } - } -} - -//var OpAmount = 1;//ceshi -//var maxProfit = 0.2; -var buyInfo = null; -var sellInfo = null; -var SHORT = 2; -var LONG = 1; -var NONE = 0; -var NowPositionInfo = { // - avgPrice : 0 , - amount : 0, - floatProfit : 0, - direction : 0 // 0 未持仓 , 1多仓 , 2空仓 -}; - - -function onexit() { - -} - - -var Profit = 0; -function Calculate(nowAccount,nowDepth){//计算并更新收益 、 浮动收益 、计算 持仓均价 、持仓量 - if(typeof(nowAccount) === 'undefined' ){ - nowAccount = _C(exchange.GetAccount); - nowDepth = _C(exchange.GetDepth); - } - var diff_stocks = nowAccount.Stocks - InitAccount.Stocks;//币之差 - var diff_balance = nowAccount.Balance - InitAccount.Balance;//钱之差 - NowPositionInfo.avgPrice = Math.abs(diff_balance) / Math.abs(diff_stocks); - //throw nowAccount.Stocks + "----" + nowAccount.Balance;//ceshi - NowPositionInfo.amount = Math.abs(diff_stocks); - NowPositionInfo.floatProfit = diff_balance + diff_stocks * (NowPositionInfo.direction === SHORT?nowDepth.Bids[0].Price : nowDepth.Asks[0].Price); //此次交易的浮动盈亏 - Profit = (nowAccount.Stocks - beginAccount.Stocks) * (NowPositionInfo.direction === SHORT?nowDepth.Bids[0].Price : nowDepth.Asks[0].Price) + (nowAccount.Balance - beginAccount.Balance); //总盈亏 - - //更新入界面 -} - -function main() { - CancelPendingOrders(); - InitAccount = exchange.GetAccount();//上次平仓后账户信息 - beginAccount = InitAccount; //启动时账户信息 - LoopInterval = Math.min(1, LoopInterval); - //清空 - LogReset(); - LogProfitReset(); - chart = Chart(ChartCfg); - chart.reset(); - - Log('交易平台:', exchange.GetName(), InitAccount); - LogStatus("Ready..."); - Log(InitAccount); - - LoopInterval = Math.max(LoopInterval, 1); - while (true) { - onTick(exchange); - Calculate(); - Sleep(LoopInterval * 1000); - } -} diff --git a/Hedge_BTC-ETH Demo.js b/Hedge_BTC-ETH Demo.js new file mode 100644 index 00000000..27223506 --- /dev/null +++ b/Hedge_BTC-ETH Demo.js @@ -0,0 +1,157 @@ +/* +策略出处: https://www.botvs.com/strategy/48536 +策略名称: Hedge_BTC-ETH Demo +策略作者: 小小梦 +策略描述: + +BTC 和 ETH 的 跨品种对冲 思路测试 DEMO +根据价格比 画出 图表,分析 价格比 变化,寻找套利空间。 +策略可行性 未知, 有兴趣的 同学可以研究一下~ + +by littleDream + + +参数 默认值 描述 +---- ----- ------------ +Mode 0 模式: BOLL|SMA +*/ + +/*exchanges +A : BTC +B : ETH +*/ + +var RateUpDateTime = new Date().getTime() +var UpDateCyc = 60 * 60 * 1000 +var SumInCyc = 0 +var AddCounts = 1 +var RateArray = [] + +var BTC_hold_amount = 0 +var ETH_hold_amount = 0 + +var IDLE = 0 +var PLUS = 1 +var STATE = IDLE + +var fee_btc = { + buy : 0.2, // 0.2 % , 千分之四 + sell : 0.2 +} + +var fee_eth = { + buy : 0.2, + sell : 0.2 +} + +var ModeStr = ["BOLL", "SMA"][Mode] + +function CalcPriceForNoFee(price, fee, type){ + if(type == "buy"){ + return price * (1 - fee / 100) + }else if(type == "sell"){ + return price * (1 + fee / 100) + } +} + +function loop(nowTime){ + var depthA = exchanges[0].GetDepth() + var depthB = exchanges[1].GetDepth() + var sma120 = null + var sma10 = null + + var boll = null + + if(!depthA || !depthB || depthA.Asks.length == 0 || depthA.Bids.length == 0 || depthB.Asks.length == 0 || depthB.Bids.length == 0){ + return + } + + var Rate = CalcPriceForNoFee((depthA.Bids[0].Price + depthA.Asks[0].Price) / 2, 0.2, "buy") / CalcPriceForNoFee((depthB.Bids[0].Price + depthB.Asks[0].Price) / 2, 0.2, "sell") + + if(nowTime - RateUpDateTime > UpDateCyc){ + RateArray.push(Rate) + + $.PlotLine("avgRate", RateArray[RateArray.length - 2], RateUpDateTime) + + if(RateArray.length > 60){ + if(ModeStr == "SMA"){ + sma120 = talib.SMA(RateArray, 60) + sma10 = talib.SMA(RateArray, 10) + + $.PlotLine("sma120", sma120[sma120.length - 2], RateUpDateTime) + $.PlotLine("sma10", sma10[sma10.length - 2], RateUpDateTime) + }else if(ModeStr == "BOLL"){ + boll = TA.BOLL(RateArray, 20, 2.5) + $.PlotLine("up", boll[0][boll[0].length - 2], RateUpDateTime) + $.PlotLine("down", boll[2][boll[2].length - 2], RateUpDateTime) + } + } + + RateUpDateTime += UpDateCyc + SumInCyc = 0 + AddCounts = 1 + }else{ + SumInCyc += Rate + AddCounts++ + + RateArray[RateArray.length - 1] = (SumInCyc / AddCounts) + + $.PlotLine("avgRate", RateArray[RateArray.length - 1], RateUpDateTime) + if(RateArray.length > 60){ + if(ModeStr == "SMA"){ + sma120 = talib.SMA(RateArray, 60) + sma10 = talib.SMA(RateArray, 10) + + $.PlotLine("sma120", sma120[sma120.length - 1], RateUpDateTime) + $.PlotLine("sma10", sma10[sma10.length - 1], RateUpDateTime) + }else if(ModeStr == "BOLL"){ + boll = TA.BOLL(RateArray, 20, 2.5) + $.PlotLine("up", boll[0][boll[0].length - 1], RateUpDateTime) + $.PlotLine("down", boll[2][boll[2].length - 1], RateUpDateTime) + } + } + } + + if(ModeStr == "SMA"){ + if(STATE == IDLE && (sma120 && sma10) && sma120[sma120.length - 2] > sma10[sma10.length - 2] && sma120[sma120.length - 1] < sma10[sma10.length - 1]){ + // PLUS + var SellInfo = $.Sell(exchanges[1], 5) + var sumMoney = SellInfo.price * SellInfo.amount + var amount = _N(sumMoney / depthA.Asks[0].Price, 2) + var BuyInfo = $.Buy(exchanges[0], amount) + + ETH_hold_amount = SellInfo.amount + BTC_hold_amount = amount + STATE = PLUS + // throw "stop" // ceshi + } + + if(STATE == PLUS && (sma120 && sma10) && sma120[sma120.length - 2] < sma10[sma10.length - 2] && sma120[sma120.length - 1] > sma10[sma10.length - 1]){ + // COVER + var BuyInfo = $.Buy(exchanges[1], ETH_hold_amount) + var SellInfo = $.Sell(exchanges[0], BTC_hold_amount) + + ETH_hold_amount = 0 + BTC_hold_amount = 0 + STATE = IDLE + Log(exchanges[0].GetAccount(), exchanges[1].GetAccount()) + } + } +} + + + + +function main() { + var AccountA = exchanges[0].GetAccount() + var AccountB = exchanges[1].GetAccount() + + Log("AccountA:", AccountA, "AccountB:", AccountB) + + while(true){ + var beginTime = new Date().getTime() + loop(beginTime) + Sleep(500) + } + +} diff --git "a/JS\347\211\210\346\234\254Dual Thrust.js" "b/JS\347\211\210\346\234\254Dual Thrust.js" new file mode 100644 index 00000000..ab544eb2 --- /dev/null +++ "b/JS\347\211\210\346\234\254Dual Thrust.js" @@ -0,0 +1,120 @@ +/* +策略出处: https://www.botvs.com/strategy/36100 +策略名称: JS版本Dual Thrust +策略作者: BotVs@太极 +策略描述: + +JS版本Dual Thrust + +*/ + +// botvs@505d17ec1da140d9467374ae4c1ad024 +//========================================== +//API: Chart 函数使用的简单例子(画图功能) +var chart = { // 这个 chart 在JS 语言中 是对象, 在使用Chart 函数之前我们需要声明一个配置图表的对象变量chart。 + __isStock: true, // 标记是否为一般图表,有兴趣的可以改成 false 运行看看。 + tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'}, // 缩放工具 + title : { text : '差价分析图'}, // 标题 + 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 + }, + xAxis: { type: 'datetime'}, // 坐标轴横轴 即:x轴, 当前设置的类型是 :时间 + yAxis : { // 坐标轴纵轴 即:y轴, 默认数值随数据大小调整。 + title:{text: '差价'}, // 标题 + opposite:false, // 是否启用右边纵轴 + }, + series : [ // 数据系列,该属性保存的是 各个 数据系列(线, K线图, 标签等..) + {name:"上轨:",id:"0",color:'#778899',dashStyle:'shortdash',data:[]}, // 索引为0, data 数组内存放的是该索引系列的 数据 + {name:"周期开盘价:",id:"1",color:'#32CD32',data:[]}, // 索引为1,设置了dashStyle : 'shortdash' 即:设置 虚线。 + {name:"下轨:",id:"2",color:'#303030',dashStyle:'shortdash',data:[]}, + {name:"当前价:",id:"3",color:'#FF3030',data:[]}, + //RGB颜色对照表 http://www.114la.com/other/rgb.htm + ] +}; +//========================================== +function Highest(records, attr, n) { //最高 + var v = 0; + for (var pos = records.length - n; pos < records.length; pos++) { + v = Math.max(v, records[pos][attr]); + } + return v; +} + +function Lowest(records, attr, n) { //最低 + var v = -1; + for (var pos = records.length - n; pos < records.length; pos++) { + if (v == -1) { + v = records[pos][attr]; + } else { + v = Math.min(v, records[pos][attr]); + } + } + return v; +} + +var NPeriod=7; //N的周期 +var Ks=0.5; //上轨系数 +var Kx=0.5; //下轨系数 +var ObjChart = Chart(chart); // 调用 Chart 函数,初始化 图表。 +ObjChart.reset(); // 清空 +function onTick(e){ + var Records =_C(e.GetRecords); //返回一个K线历史, K线周期在创建机器人时指定 + var Bar = Records[Records.length-1]; //当前周期 + var HH = Highest(Records, 'High', NPeriod); //最高价-最高价-HH + var HC = Highest(Records, 'Close', NPeriod); //收盘价-最高价-HC + var LL = Lowest(Records, 'Low', NPeriod); //最低价-最低价-LL + var LC = Lowest(Records, 'Close', NPeriod); //收盘价-最低价-LC + + Log("HH:",HH,"HC:",HC,"LL:",LL,"LC:",LC); + + var Range = 0; + if ((HH - LC) >= (HC - LL)) { + Range = HH - LC; + } else { + Range = HC - LL; + } + + var BuyPosition = Bar.Open + (Ks * Range); + var SellPosition = Bar.Open - (Kx * Range); + //======================== + var Ticker_Last=e.GetTicker().Last //最后成交价 + Log(BuyPosition,"-",Bar.Open,"-",SellPosition); + //画线 + var nowTime = new Date().getTime(); //获取时间戳, + ObjChart.add([0, [nowTime,BuyPosition]]); //上轨 + //ObjChart.add([1, [nowTime,Bar.Open]]); //触发值 + ObjChart.add([2, [nowTime,SellPosition]]); //下轨 + ObjChart.add([3, [nowTime,Ticker_Last]]); //当前价格 + ObjChart.update(chart); // 更新图表以显示出来。 + //======================== + + + +/* + var Account=_C(e.GetAccount); //账户余额 + //判断是否具备开仓条件 + if (parseFloat(Account.Balance)>=8000){ + Log(Account); + Log(Account.Stocks); + Buy(e,1); + } + + //判断是否具备平仓条件 + if (parseFloat(Account.Stocks)>=1){ + Log(Account); + Log(Account.Stocks); + Sell(e,1); + } +*/ +} + +function main() { + Log("策略启动"); + while(true) { + onTick(exchanges[0]); + Sleep(1000); + } +} + diff --git "a/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221 (Copy).js" "b/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221 (Copy).js" deleted file mode 100644 index d2d44087..00000000 --- "a/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221 (Copy).js" +++ /dev/null @@ -1,139 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/42312 -策略名称: KingKeltner趋势策略_低频 (Copy) -策略作者: jdm16478 -策略描述: - - - -*/ - -/* -策略出处: vnpy -策略名称: KingKeltner趋势策略 -策略作者: ipqhjjybj -策略描述: -趋势跟踪策略 - -*/ - -KK_Length = 11 // 计算通道中值的窗口数 -kkDev = 1.3 // 计算通道宽度的偏差 -trailingPrcnt = 15 // 移动止损 -LoopInterval = 60 // 轮询间隔(秒) -SlidePrice = 0.3 // 滑动价(元) -function adjustFloat(v) { - return Math.floor(v*1000)/1000; -} - -function CancelPendingOrders() { - while (true) { - var orders = null; - while (!(orders = exchange.GetOrders())) { - Sleep(Interval); - } - - if (orders.length == 0) { - return; - } - - for (var j = 0; j < orders.length; j++) { - exchange.CancelOrder(orders[j].Id, orders[j]); - if (j < (orders.length-1)) { - Sleep(Interval); - } - } - } -} - -function GetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(Interval); - } - return account; -} - -function GetTicker() { - var ticker; - while (!(ticker = exchange.GetTicker())) { - Sleep(Interval); - } - return ticker; -} - -var intraTradeHigh = 0; // 移动最高价 -var intraTradeLow = 99999999; // 移动最低价 -var LastBuyPrice = 0; // 上一次买的价格 -var LastSellPrice = 0; // 上一次卖的价格 -var minMoney = 100; // 如果资金小于该数值,则不买入 -var LastRecord = null; // 初始化上一个记录 -function onTick(exchange) { - - var ticker = GetTicker(); - // Buy or Sell, Cancel pending orders first - CancelPendingOrders(); - var account = GetAccount(); - - if (true) { - var records = exchange.GetRecords(); - if (!records || records.length < (KK_Length + 3)) { - return; - } - // Price not change - var newLast = records[records.length-1]; - if ((!LastRecord) || (LastRecord.Time == newLast.Time && LastRecord.Close == newLast.Close)) { - LastRecord = newLast; - return; - } - LastRecord = newLast; - - //Log(newLast); - var kk_ATR = TA.ATR(records , KK_Length); - var kk_Mid = TA.MA(records, KK_Length); - var kk_Up = kk_Mid[kk_Mid.length-1] + kk_ATR[kk_ATR.length-1] * kkDev; - //var kk_Down= kk_Mid - kk_ATR * kkDev - - //Log("LastRecord.Close",LastRecord.Close ,"kk_up",kk_Up,"intraTradeHigh",intraTradeHigh); - if( account.Stocks <= exchange.GetMinStock() ){ - if(LastRecord.Close > kk_Up){ - Log("start buy"); - var price = ticker.Last + SlidePrice; - var amount = adjustFloat(account.Balance / price); - if (account.Balance > minMoney && amount >= exchange.GetMinStock()) { - if (exchange.Buy(price, amount, "做多")) { - intraTradeHigh = LastRecord.High - intraTradeLow = LastRecord.Low - LastBuyPrice = LastHighPrice = price; - } - } - } - } - else if( exchange.GetMinStock() < account.Stocks ){ - Log("Close",LastRecord.Close, "intraTradeHigh",intraTradeHigh ,"intraTradeHigh * ( 1 - trailingPrcnt)",intraTradeHigh * ( 1 - trailingPrcnt/100.0)) - intraTradeHigh = Math.max(intraTradeHigh , LastRecord.High) - intraTradeLow = LastRecord.Low - if(LastRecord.Close < intraTradeHigh * ( 1 - trailingPrcnt/100.0)){ // 移动止损 - Log("start sell"); - var price = ticker.Last - SlidePrice; - var sellAmount = account.Stocks; - if (sellAmount > exchange.GetMinStock()) { - exchange.Sell(ticker.Last - SlidePrice, sellAmount, "卖出"); - LastSellPrice = LastLowPrice = price; - } - } - } - } -} - - -function main() { - InitAccount = GetAccount(); - Log(exchange.GetName(), exchange.GetCurrency(), InitAccount); - - LoopInterval = Math.max(LoopInterval, 1); - while (true) { - onTick(exchange); - Sleep(LoopInterval*1000); - } -} diff --git "a/MACD\344\275\216\344\271\260\351\253\230\345\215\226\350\207\252\345\212\250\350\267\237\345\215\225\346\273\221\345\212\250\346\255\242\346\215\237 (\345\244\215\345\210\266).js" "b/MACD\344\275\216\344\271\260\351\253\230\345\215\226\350\207\252\345\212\250\350\267\237\345\215\225\346\273\221\345\212\250\346\255\242\346\215\237 (\345\244\215\345\210\266).js" deleted file mode 100644 index 25d504c0..00000000 --- "a/MACD\344\275\216\344\271\260\351\253\230\345\215\226\350\207\252\345\212\250\350\267\237\345\215\225\346\273\221\345\212\250\346\255\242\346\215\237 (\345\244\215\345\210\266).js" +++ /dev/null @@ -1,199 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/20266 -策略名称: MACD低买高卖自动跟单滑动止损 (复制) -策略作者: 13633698059 -策略描述: - -交叉后前一柱指金叉后的第一柱的值, 交叉后前一柱指金叉前的最后一个柱的值, 滑动价格指下单时加的价格,比如买单会现价加上这个价格,卖单会减去这个价格 - - -参数 默认值 描述 ------------- ------ ------- -ac1 0.005 交叉后第一柱 -bc1 -1e-06 交叉后前一柱 -SlidePrice 0.3 滑动价格 -TrailingStop 0.5 止损点 -orderTimeout 30 买单超时(秒) -*/ - - -Fixed = function(v) { - return Math.floor(v*1000)/1000; -}; - -// for orders -WaitOrder = function(exchange, orderId, timeoutToCancel) { - var ts = (new Date()).getTime(); - while (true) { - Sleep(3000); - var orderInfo = exchange.GetOrder(orderId); - if (!orderInfo) { - continue; - } - if (orderInfo.Status == ORDER_STATE_CLOSED || orderInfo.Status == ORDER_STATE_CANCELED) { - return orderInfo; - } - if (((new Date()).getTime() - ts) > timeoutToCancel) { - exchange.CancelOrder(orderId); - } - } -}; - -Buy = function(exchange, maxPrice, slidePrice, balanceRatio, timeoutS) { - var ts = (new Date()).getTime(); - var account; - var dealAmount = 0.0; - var usedBlance = 0.0; - var maxBalanceUse = 0.0; - var isFirst = true; - do { - if (isFirst) { - isFirst = false; - } else { - Sleep(3000); - } - - var ticker = exchange.GetTicker(); - if (!ticker) { - continue; - } - - var buyPrice = ticker.Sell + slidePrice; - - // Price too high, wait... - if (buyPrice > maxPrice) { - continue; - } - - // Initialize at first - if (!account) { - account = exchange.GetAccount(); - if (!account) { - continue; - } - // Initialize maxBalanceUse - maxBalanceUse = account.Balance * balanceRatio; - } - - var buyAmount = Fixed((maxBalanceUse - usedBlance) / buyPrice); - if (buyAmount < exchange.GetMinStock()) { - break; - } - - orderId = exchange.Buy(buyPrice, buyAmount); - if (!orderId) { - Log(buyPrice, buyAmount, maxBalanceUse, usedBlance); - continue; - } - - var orderInfo = WaitOrder(exchange, orderId, timeoutS); - dealAmount += orderInfo.DealAmount; - usedBlance += orderInfo.Price * orderInfo.DealAmount; - if (orderInfo.Status == ORDER_STATE_CLOSED) { - break; - } - } while (((new Date()).getTime() - ts) < timeoutS); - - return {amount: dealAmount, price: (dealAmount > 0 ? usedBlance / dealAmount : 0)}; -}; - -Sell = function(exchange, sellAmount, slidePrice) { - // Account info must set - var account = exchange.GetAccount(); - while (!account) { - Sleep(2000); - account = exchange.GetAccount(); - } - - sellAmount = Math.min(sellAmount, account.Stocks); - - var cash = 0.0; - var remain = sellAmount; - - while (remain >= exchange.GetMinStock()) { - var ticker = exchange.GetTicker(); - if (!ticker) { - Sleep(2000); - continue; - } - var sellPrice = ticker.Buy - slidePrice; - var sellOrderId = exchange.Sell(sellPrice, remain); - if (!sellOrderId) { - Sleep(2000); - continue; - } - var orderInfo = WaitOrder(exchange, sellOrderId, 10000); - remain -= orderInfo.DealAmount; - cash += orderInfo.Price * orderInfo.DealAmount; - } - return {amount: sellAmount, price: (sellAmount > 0 ? cash / sellAmount : 0)}; -}; - -var BuyInfo; -var BanlanceRatio = 1.0; -var Profit = 0.0; -var timeAtBuy = 0; - -function onTick(exchange) { - var ticker = exchange.GetTicker(); - var records = exchange.GetRecords(); - if (!ticker || !records || records.length < 45) { - return; - } - - var ticks = []; - for (var i = 0; i < records.length; i++) { - ticks.push(records[i].Close); - } - - var macd = TA.MACD(records, 12, 26, 9); - var dif = macd[0]; - var dea = macd[1]; - var his = macd[2]; - - var op = 0; - if (!BuyInfo) { - if (dif[ticks.length-1] > 0 && his[ticks.length-1] > ac1 && his[ticks.length-2] < bc1) { - op = 1; - } - } else { - if (records[records.length-2].Time > timeAtBuy && records[records.length-1].Close < records[records.length-1].Open - 0.5 - && records[records.length-2].Close < records[records.length-2].Open - 0.5 - && records[records.length-1].Close < records[records.length-2].Close - 0.5) { - op = 2; - } else if (records[records.length-2].Time > timeAtBuy && BuyInfo.price > records[records.length-1].Close && records[records.length-1].Close < records[records.length-1].Open - 0.5) { - op = 2; - } else if ((BuyInfo.price < ticker.Last || dif[ticks.length-1] < 0) && his[ticks.length-1] <= 0) { - op = 2; - } else if ((BuyInfo.price > ticker.Last) && ((BuyInfo.price - ticker.Last) / BuyInfo.price > TrailingStop)) { - op = 2; - } - } - - if (op == 1) { - var info = Buy(exchange, ticker.Sell + (SlidePrice * 3), SlidePrice, BanlanceRatio, orderTimeout * 1000); - if (info.amount > 0) { - BuyInfo = info; - timeAtBuy = records[records.length-1].Time; - } - } else if (op == 2) { - var info = Sell(exchange, BuyInfo.amount, SlidePrice); - if (info.amount > 0) { - Profit += info.amount * (info.price - BuyInfo.price); - LogProfit(Profit); - BuyInfo = null; - } - } -} - -function main() { - var account = exchange.GetAccount(); - if (account) { - Log(exchange.GetName(), exchange.GetCurrency(), account); - } - - while (true) { - onTick(exchange); - Sleep(30000); - } -} diff --git "a/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.js" "b/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.js" index 0fda99e4..f1f2b91f 100644 --- "a/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.js" +++ "b/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.js" @@ -411,7 +411,7 @@ function Hedge_Open_Cover(task){ if((task.action[1] === "buy" && task.action[2] === "sell") || (task.action[1] === "sell" && task.action[2] === "buy")){ // open var tradeInfo_A = DealActionLimit(task, A, task.action[3]); var dealAmount_A = Math.abs(task.action[3]); - while(tradeInfo_A == false || (dealAmount_A -= tradeInfo_A.amount) !== 0){ + while(tradeInfo_A == false || (dealAmount_A -= tradeInfo_A.amount) > 0){ // 此处应该 判断是否小于 0 。 等于 0 会引起 BUG ,修改为 大于 0 Log("合约:" + task.symbolA + "已对冲" + (tradeInfo_A == false ? 0 : tradeInfo_A.amount), "剩余,重试!张数:" + dealAmount_A); tradeInfo_A = DealActionLimit(task, A, dealAmount_A, true); Sleep(Interval); @@ -419,7 +419,7 @@ function Hedge_Open_Cover(task){ var tradeInfo_B = DealActionLimit(task, B, task.action[3]); var dealAmount_B = Math.abs(task.action[3]); - while(tradeInfo_B == false || (dealAmount_B -= tradeInfo_B.amount) !== 0){ + while(tradeInfo_B == false || (dealAmount_B -= tradeInfo_B.amount) > 0){ Log("合约:" + task.symbolB + "已对冲" + (tradeInfo_B == false ? 0 : tradeInfo_B.amount), "剩余,重试!张数:" + dealAmount_B); tradeInfo_B = DealActionLimit(task, B, dealAmount_B, true); Sleep(Interval); @@ -430,7 +430,7 @@ function Hedge_Open_Cover(task){ }else if((task.action[1] === "closesell" && task.action[2] === "closebuy") || (task.action[1] === "closebuy" && task.action[2] === "closesell")){ // cover var tradeInfo_A_Piece = DealActionLimit(task, A, task.action[3]); var dealAmount_A = Math.abs(task.action[3]); - while(tradeInfo_A_Piece == false || (dealAmount_A -= tradeInfo_A_Piece) !== 0){ + while(tradeInfo_A_Piece == false || (dealAmount_A -= tradeInfo_A_Piece) > 0){ // 此处应该 判断是否小于 0 。 等于 0 会引起 BUG ,修改为 大于 0 Log("合约:" + task.symbolA + "已对冲" + (tradeInfo_A == false ? 0 : tradeInfo_A_Piece), "剩余,重试!张数:" + dealAmount_A); tradeInfo_A_Piece = DealActionLimit(task, A, dealAmount_A, true); Sleep(Interval); @@ -438,7 +438,7 @@ function Hedge_Open_Cover(task){ var tradeInfo_B_Piece = DealActionLimit(task, B, task.action[3]); var dealAmount_B = Math.abs(task.action[3]); - while(tradeInfo_B_Piece == false || (dealAmount_B -= tradeInfo_B_Piece) !== 0){ + while(tradeInfo_B_Piece == false || (dealAmount_B -= tradeInfo_B_Piece) > 0){ Log("合约:" + task.symbolB + "已对冲" + (tradeInfo_B == false ? 0 : tradeInfo_B_Piece), "剩余,重试!张数:" + dealAmount_B); tradeInfo_B_Piece = DealActionLimit(task, B, dealAmount_B, true); Sleep(Interval); diff --git "a/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" "b/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" index 08ece644..c992c87a 100644 --- "a/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" +++ "b/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" @@ -11,9 +11,10 @@ https://www.botvs.com/strategy/24288 -参数 默认值 描述 ------- ----- ---- -Amount 2 开仓手数 +参数 默认值 描述 +------------ ------------ ---- +Amount 2 开仓手数 +ContractList MA701,rb1701 合约列表 ''' ''' @@ -68,8 +69,8 @@ def main(): q = ext.NewTaskQueue() Log(_C(exchange.GetAccount)) tasks = [] - for symbol in ["MA701", "rb1701"]: - tasks.append(Trader(q, symbol)) + for symbol in ContractList.split(','): + tasks.append(Trader(q, symbol.strip())) while True: if exchange.IO("status"): for t in tasks: diff --git "a/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" "b/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" new file mode 100644 index 00000000..944dd3f4 --- /dev/null +++ "b/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" @@ -0,0 +1,157 @@ +''' +策略出处: https://www.botvs.com/strategy/46031 +策略名称: Python版 TableTemplet (测试版) +策略作者: 小小梦 +策略描述: + + + +''' + +# TableTemplet +import json +listener = {} + +class Table(): + """docstring for Table""" + def __init__(self): + self.tb = { + "type" : "table", + "title" : "Table", + "cols" : [], + "rows" : [] + } + + def SetColRow(self, col_index, row_index, row): + if (type(col_index) is int) and (type(row_index) is int) : + if (col_index > len(self.tb["cols"])) or (row_index > len(self.tb["rows"])) : + Log("索引超出范围!col_index:", col_index, "row_index:", row_index) + else : + self.tb["rows"][row_index - 1][col_index - 1] = row + else : + Log("col_index:", col_index, "row_index:", row_index) + raise "SetColRow 参数错误!" + + def SetBtn(self, col_index, row_index, cmd, name, callback): + global listener + if (type(col_index) is int) and (type(row_index) is int) : + if (col_index > len(self.tb["cols"])) or (row_index > len(self.tb["rows"])) : + Log("索引超出范围!col_index:", col_index, "row_index:", row_index) + else : + self.tb["rows"][row_index - 1][col_index - 1] = {"type" : "button", "cmd" : cmd, "name" : name} + listener[cmd] = callback + else : + Log("col_index:", col_index, "row_index:", row_index) + raise "SetColRow 参数错误!" + + def SetRows(self, row_index, Rows): + pass + + def SetCols(self, Cols): + self.tb["cols"] = Cols + + def GetRows(self, row_index): + if (type(row_index) is int) and (row_index < len(self.tb["rows"])) : + return self.tb["rows"][row_index - 1] + else : + Log("参数错误! 或者 参数索引超出范围!") + + def Init(self, title, col_length, row_length): + self.tb["title"] = title + for i in range(1, row_length + 1) : + if i == 1 : + for n in range(1, col_length + 1) : + self.tb["cols"].append(n) + self.tb["rows"].append([]) + for m in range(1, col_length + 1) : + self.tb["rows"][i - 1].append(str(i) + "/" + str(m)) + + +class CreateTableManager(): + """docstring for CreateTableManager""" + def __init__(self): # CreateTableManager 构造函数 + self.tables = [] # 用于储存 table 对象 + + def GetTable(self, index): + if type(index) is int : + return self.tables[index] + elif type(index) is str : + for i in range(len(self.tables)) : + if self.tables[i]["title"] == index: + return self.tables[i] + else : + Log("GetTable参数:", index) + raise "GetTable 参数错误!" + + def AddTable(self, title, col_length, row_length): # cols, rows + tb = Table() + tb.Init(title, col_length, row_length) + self.tables.append(tb.tb) + return tb + + def UpdateCMD(self): + global listener + cmd = GetCommand() + if cmd : + if listener[cmd] : + listener[cmd](cmd) + else : + Log("找不到名为:" + cmd + "的命令") + + def LogStatus(self, before, end): + self.UpdateCMD() + LogStatus(before + '\n`' + json.dumps(self.tables) + '`\n' + end) + +# 导出函数 +ext.CreateTableManager = CreateTableManager + +# 测试代码 + +def test1(cmd): # 用作函数回调 + Log(_D(), cmd) + +def main(): + account = exchange.GetAccount() + array1 = ["aa", "bb", "cc"] + array2 = [1, 2, 4, 55] + + TbM = ext.CreateTableManager() + tb1 = TbM.AddTable("tb1", 6, 7) + + tb1.SetColRow(3, 4, "hello") + tb1.SetColRow(3, 5, 12) + tb1.SetColRow(3, 6, account) + tb1.SetColRow(3, 7, array1) + tb1.SetColRow(3, 2, array2) + tb1.SetBtn(3, 1, "Cover", "平仓", test1) # 由于 python 没有多行 匿名函数(如JS 的 function(){...})所以可以声明普通函数传入。 + tb_1 = TbM.GetTable(0) + tb_2 = TbM.GetTable("tb1") + Log(tb_1) + Log(tb_2, "#FF0000") + tb1_row1 = tb1.GetRows(1) + Log(tb1_row1) + tb1_row1[0] = "修改" + x = 0 + + # tb2 + tb2 = TbM.AddTable("tb2", 4, 4) + + while True : + x = x + 1 + tb1_row1[0] = _D() + tb1.SetCols([x + 1, x + 2, x + 3, x + 4, x + 5, x + 6]) + TbM.LogStatus("begin", "end") + Sleep(1000) + + + + + + + + + + + + + diff --git a/README.md b/README.md index 0d9c4c89..c53f0b96 100644 --- a/README.md +++ b/README.md @@ -4,54 +4,65 @@ > 开源策略列表 - - [JS版 商品期货 精简多品种 MACD 趋势策略框架](https://www.botvs.com/strategy/44593) + - [2014年的简易短线机器人](https://www.botvs.com/strategy/1088) + - [python版 Dual Thrust OKCoin 期货](https://www.botvs.com/strategy/21856) + - [商品期货交易类库](https://www.botvs.com/strategy/12961) + - [简单多品种商品期货均线策略](https://www.botvs.com/strategy/57029) + - [数字货币现货交易类库](https://www.botvs.com/strategy/10989) + - [数字货币交易类库 (期货支持OKCoin期货/BitVC, 支持$.CTA函数)](https://www.botvs.com/strategy/57267) + - [测试 默认 参数组功能](https://www.botvs.com/strategy/40155) + - [转换任意K线周期管理模板(最近更新20171113)](https://www.botvs.com/strategy/41163) + - [全球10大交易系统之 Aberration 多品种商品期货交易系统](https://www.botvs.com/strategy/25943) + - [Dual Thrust 商品期货](https://www.botvs.com/strategy/13011) + - [python版 画线类库 (兼容2/3)](https://www.botvs.com/strategy/39066) + - [画线类库](https://www.botvs.com/strategy/27293) + - [BotVS 商品期货 量化 测试入门 策略](https://www.botvs.com/strategy/59120) + - [数字货币差价监控分析](https://www.botvs.com/strategy/21337) + - [bitfinex保证金交易](https://www.botvs.com/strategy/57333) + - [双平台对冲js版本(two platforms hedging-JS)](https://www.botvs.com/strategy/57556) + - [如何找出一定Bar数量的 K线前期高点、低点 及 Demo 程序](https://www.botvs.com/strategy/58179) + - [python版现货数字货币交易类库](https://www.botvs.com/strategy/21104) + - [数字货币交易类库 (期货支持OKCoin期货/BitVC)](https://www.botvs.com/strategy/30199) + - [CTP商品期货多品种海龟交易策略](https://www.botvs.com/strategy/17289) + - [一目均衡](https://www.botvs.com/strategy/55839) + - [StochRSI(和okcoin一致)](https://www.botvs.com/strategy/56119) + - [使用 BotVS 构建一个机械化策略](https://www.botvs.com/strategy/40357) + - [差价监控](https://www.botvs.com/strategy/1340) + - [布林均线突破_vnpy_botvs实现版](https://www.botvs.com/strategy/52801) + - [数字货币定投](https://www.botvs.com/strategy/54256) + - [双平台对冲 练习用 求交流求指点](https://www.botvs.com/strategy/53512) + - [仓位均衡策略](https://www.botvs.com/strategy/54182) + - [OKCoin期货跨期对冲策略](https://www.botvs.com/strategy/34878) + - [Hedge_BTC/ETH Demo](https://www.botvs.com/strategy/48536) + - [多均线策略](https://www.botvs.com/strategy/47144) + - [策略框架模板](https://www.botvs.com/strategy/30861) + - [均线MA指标使用范例](https://www.botvs.com/strategy/46484) + - [Python版 TableTemplet (测试版)](https://www.botvs.com/strategy/46031) + - [python版CTP商品期货交易类库(支持2/3 测试版)](https://www.botvs.com/strategy/24288) - [Python 精简多品种 MACD 趋势策略](https://www.botvs.com/strategy/43965) - - [转换任意K线周期管理模板(最近更新20170622)](https://www.botvs.com/strategy/41163) + - [JS版 商品期货 精简多品种 MACD 趋势策略框架](https://www.botvs.com/strategy/44593) - [TableTemplet](https://www.botvs.com/strategy/44319) - - [(13)策略框架 (Copy)](https://www.botvs.com/strategy/43579) - - [使用 BotVS 构建一个机械化策略 (Copy)](https://www.botvs.com/strategy/43422) - - [转换任意K线周期管理模板(最近更新20170531) (Copy)](https://www.botvs.com/strategy/43082) - [OKCoin跨期布林对冲](https://www.botvs.com/strategy/43049) - [Ma单均线趋势交易](https://www.botvs.com/strategy/42451) - - [策略001-szc](https://www.botvs.com/strategy/34216) - - [buy-hold 买入持有 (Copy)](https://www.botvs.com/strategy/42313) - - [KingKeltner趋势策略_低频 (Copy)](https://www.botvs.com/strategy/42312) - [KingKeltner趋势策略_低频](https://www.botvs.com/strategy/42283) - [buy-hold 买入持有](https://www.botvs.com/strategy/41786) - - [OKCoin期货跨期对冲策略](https://www.botvs.com/strategy/34878) - - [转换任意K线周期管理模板 (Copy)](https://www.botvs.com/strategy/41741) - - [使用 BotVS 构建一个机械化策略](https://www.botvs.com/strategy/40357) - [知乎专栏 实例文章策略](https://www.botvs.com/strategy/40266) - [BitMEX 简单测试](https://www.botvs.com/strategy/40289) - - [测试 默认 参数组功能](https://www.botvs.com/strategy/40155) - - [商品期货交易类库](https://www.botvs.com/strategy/12961) - - [测试](https://www.botvs.com/strategy/40045) - - [python版CTP商品期货交易类库(支持2/3 测试版)](https://www.botvs.com/strategy/24288) - [商品期货查看账户详细信息](https://www.botvs.com/strategy/37793) - - [python版 画线类库 (兼容2/3)](https://www.botvs.com/strategy/39066) - - [【Demo】速度测试 websocket vs rest (复制)5560](https://www.botvs.com/strategy/8487) + - [网格变形策略之单边网格](https://www.botvs.com/strategy/629) - [股票证券查询买卖示例](https://www.botvs.com/strategy/5541) - [测试多图表展示](https://www.botvs.com/strategy/38203) - - [震荡突破策略 (删减B值触发平仓、动态调整触发值 优化ing) (复制)ttttttttt](https://www.botvs.com/strategy/23549) - - [CTP商品期货多品种海龟交易策略](https://www.botvs.com/strategy/17289) - [商品期货结算单平仓盈亏历史查询](https://www.botvs.com/strategy/38083) - [Convert_Record_Cycle](https://www.botvs.com/strategy/37678) - - [均线-趋势_数字货币策略V0.2 (Copy)](https://www.botvs.com/strategy/37664) - - [数字货币交易类库 (期货支持OKCoin期货/BitVC) (复制)](https://www.botvs.com/strategy/30307) - - [数字货币交易类库 (期货支持OKCoin期货/BitVC)](https://www.botvs.com/strategy/30199) - [转换任意K线周期](https://www.botvs.com/strategy/35986) - [API 测试新手入门](https://www.botvs.com/strategy/4) - [实盘账户模拟器](https://www.botvs.com/strategy/35977) - [js R-Breaker](https://www.botvs.com/strategy/36195) + - [JS版本Dual Thrust](https://www.botvs.com/strategy/36100) - [图表界面信息展示实例1](https://www.botvs.com/strategy/36026) - [移植 OKCoin 韭菜收割机](https://www.botvs.com/strategy/34388) - [R-Breaker11 交易策略](https://www.botvs.com/strategy/23874) - [比特币现货阶梯差价对冲](https://www.botvs.com/strategy/30573) - - [策略框架模板](https://www.botvs.com/strategy/30861) - - [画线类库](https://www.botvs.com/strategy/27293) - - [python版 Dual Thrust OKCoin 期货](https://www.botvs.com/strategy/21856) - - [测试-布林带策略(基于策略框架) (复制)](https://www.botvs.com/strategy/31456) - - [国外知名策略R-Breaker (复制)](https://www.botvs.com/strategy/30512) - [范例-定时测试微信消息推送](https://www.botvs.com/strategy/15098) - [测试-布林带策略(基于策略框架)](https://www.botvs.com/strategy/28128) - [商品期货跨期对冲 - 单品种套利合约](https://www.botvs.com/strategy/27122) @@ -60,29 +71,20 @@ - [均线策略 30 行搞定](https://www.botvs.com/strategy/12348) - [商品期货跨期对冲 - 百行代码实现](https://www.botvs.com/strategy/23896) - [短信通知类库](https://www.botvs.com/strategy/26921) - - [全球10大交易系统之 Aberration 多品种商品期货交易系统](https://www.botvs.com/strategy/25943) - [获取和讯期货数据(Python版本)](https://www.botvs.com/strategy/26017) - [高频收割机一号](https://www.botvs.com/strategy/6237) - - [Dual Thrust (现货版)](https://www.botvs.com/strategy/21583) - [R-Breaker 交易策略](https://www.botvs.com/strategy/23531) - - [多平台对冲稳定套利 V2.1 (复制)](https://www.botvs.com/strategy/23718) - [(13)策略框架](https://www.botvs.com/strategy/20663) - - [python版现货数字货币交易类库](https://www.botvs.com/strategy/21104) - [Dual Thrust_双轨突破_策略1](https://www.botvs.com/strategy/22983) - [Python 机器学习之 SVM 预测买卖](https://www.botvs.com/strategy/21370) - - [顺势_高频_交易_测试3](https://www.botvs.com/strategy/22183) - [均线策略(python版)](https://www.botvs.com/strategy/21157) - - [顺势_高频_交易_测试2——失败](https://www.botvs.com/strategy/21938) - - [顺势_高频_交易_测试1](https://www.botvs.com/strategy/21742) - [Python 双平台对冲策略](https://www.botvs.com/strategy/21023) - [各大平台API可用率统计](https://www.botvs.com/strategy/4404) - - [Dual Thrust 商品期货](https://www.botvs.com/strategy/13011) - [均线-趋势_数字货币策略V0.2](https://www.botvs.com/strategy/21369) - [Python简单测试策略](https://www.botvs.com/strategy/20761) - - [数字货币现货交易类库](https://www.botvs.com/strategy/10989) - [图表模板(增加状态栏表格)](https://www.botvs.com/strategy/20967) - [高频交易策略之 - Penny Jump](https://www.botvs.com/strategy/358) - - [MACD低买高卖自动跟单滑动止损 (复制)](https://www.botvs.com/strategy/20266) + - [stochRSI策略 (指标框架)](https://www.botvs.com/strategy/20383) - [获取周K线](https://www.botvs.com/strategy/20226) - [对冲2.7收益率统计系统 支持多组账号统计](https://www.botvs.com/strategy/18678) - [收益率统计](https://www.botvs.com/strategy/19329) @@ -97,7 +99,6 @@ - [记录净资产变动情况2.0](https://www.botvs.com/strategy/8916) - [非常简单的策略,但是很有效](https://www.botvs.com/strategy/15085) - [单独计算收益(代码来自zero)](https://www.botvs.com/strategy/1084) - - [差价监控](https://www.botvs.com/strategy/1340) - [10行人品策略](https://www.botvs.com/strategy/14436) - [平台价格指标监控1.1](https://www.botvs.com/strategy/12442) - [窜天猴 - 移动止损版](https://www.botvs.com/strategy/13594) @@ -122,7 +123,6 @@ - [计划委托卖出](https://www.botvs.com/strategy/747) - [RSI指标买卖](https://www.botvs.com/strategy/31) - [阶梯下单 - 可设置触发价格](https://www.botvs.com/strategy/639) - - [app价格提醒](https://www.botvs.com/strategy/4987) - [单点狙击高频加仓自动反手解套算法 V1.2](https://www.botvs.com/strategy/2406) - [796期货反手加倍算法](https://www.botvs.com/strategy/3648) - [冰山委托 - 支持价格触发 BitVC期货专用](https://www.botvs.com/strategy/951) diff --git "a/StochRSI(\345\222\214okcoin\344\270\200\350\207\264).js" "b/StochRSI(\345\222\214okcoin\344\270\200\350\207\264).js" new file mode 100644 index 00000000..ded2075d --- /dev/null +++ "b/StochRSI(\345\222\214okcoin\344\270\200\350\207\264).js" @@ -0,0 +1,130 @@ +/* +策略出处: https://www.botvs.com/strategy/56119 +策略名称: StochRSI(和okcoin一致) +策略作者: fangj +策略描述: + + + +*/ + +function Stoch_RSI(records) { + /* + LC:=REF(CLOSE,1); + RSI:=SMA(MAX(CLOSE-LC,0),14,1)/SMA(ABS(CLOSE-LC),14,1)*100; + STOCH_RSI=STOCH_RSI:=MA(RSI-LLV(RSI,14),3)/MA(HHV(RSI,14)-LLV(RSI,14),3)*100; + STOCH_RSI_MA:SMA(STOCH_RSI,3); + */ + + //计算RSI + var rsi = TA.RSI(records, 14); + // STOCH_RSI:=MA(RSI-LLV(RSI,14),3)/MA(HHV(RSI,14)-LLV(RSI,14),3)*100; + //填充空白数据 + var raw_stoch_rsi = [], raw_stoch_rsi_a = [], raw_stoch_rsi_b = []; + for (var i = 0; i < 14; i++) { + raw_stoch_rsi[i] = 50; + raw_stoch_rsi_a[i] = 0.5; + raw_stoch_rsi_b[i] = 1; + } + //计算指标 + for (i = 14; i < rsi.length; i++) { + var the_next_index = i + 1; + var first_index = the_next_index - 14; + var period_data = rsi.slice(first_index, the_next_index); + var llv = _.min(period_data); + var hhv = _.max(period_data); + var current_rsi = rsi[i]; + raw_stoch_rsi_a.push(current_rsi - llv); + raw_stoch_rsi_b.push(hhv - llv); + } + //分别对分子分母滑动平均 + var raw_stoch_rsi_a_ma = TA.MA(raw_stoch_rsi_a, 3); + var raw_stoch_rsi_b_ma = TA.MA(raw_stoch_rsi_b, 3); + for (i = 0; i < rsi.length; i++) { + var v = raw_stoch_rsi_a_ma[i] / raw_stoch_rsi_b_ma[i] * 100; + v = isNaN(v) ? 50 : v; + raw_stoch_rsi[i] = v; + } + // 滑动平均 + var stoch_rsi_K = raw_stoch_rsi; + var stoch_rsi_D = TA.MA(stoch_rsi_K, 3); + stoch_rsi = [stoch_rsi_K, stoch_rsi_D]; + return stoch_rsi; +} + + +var chart = { // 这个 chart 在JS 语言中 是对象, 在使用Chart 函数之前我们需要声明一个配置图表的对象变量chart。 + __isStock: true, // 标记是否为一般图表,有兴趣的可以改成 false 运行看看。 + tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'}, // 缩放工具 + title: {text: 'K线图'}, // 标题 + 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: true + }, + xAxis: {type: 'datetime'}, // 坐标轴横轴 即:x轴, 当前设置的类型是 :时间 + yAxis: [{ // 坐标轴纵轴 即:y轴, 默认数值随数据大小调整。 + title: {text: '价格'}, // 标题 + opposite: false, + height: '60%',// 是否启用右边纵轴 + }, + { // 坐标轴纵轴 即:y轴, 默认数值随数据大小调整。 + title: {text: 'stoch_rsi'}, // 标题 + top: '65%', + height: '35%', + offset: 0, + opposite: false, // 是否启用右边纵轴 + }], + series: [ // 数据系列,该属性保存的是 各个 数据系列(线, K线图, 标签等..) + { + type: 'candlestick', + name: '价格', + id: 'primary', + data: [] + }, // 索引为0, data 数组内存放的是该索引系列的 数据 + {name: "SRSI_K", id: "SRSI_K", data: [], yAxis: 1}, // 索引为1,设置了dashStyle : 'shortdash' 即:设置 虚线。 + {name: "SRSI_D", id: "SRSI_D", dashStyle: 'shortdash', data: [], yAxis: 1}, + ] +}; + +function main() { + exchange.SetContractType("quarter"); + var ObjChart = Chart(chart); // 调用 Chart 函数,初始化 图表。 + ObjChart.reset(); // 清空 + var preBarTime = 0; + while (true) { + var nowTime = new Date().getTime(); // 获取本次轮询的 时间戳, 即一个 毫秒 的时间戳。用来确定写入到图表的X轴的位置。 + var records = exchange.GetRecords(PERIOD_H1); // 获取行情数据 + var stoch_rsi = Stoch_RSI(records); + stoch_rsi_quick = stoch_rsi[0]; + stoch_rsi_slow = stoch_rsi[1]; + + for (var i = 0; i < records.length; i++) { // 遍历records + var r_quick = stoch_rsi_quick[i]; + var r_slow = stoch_rsi_slow[i]; + if (isNaN(r_quick)) { + r_quick = 50; + } + if (isNaN(r_slow)) { + r_slow = 50; + } + if (records[i].Time == preBarTime) { + ObjChart.add(0, [records[i].Time, records[i].Open, records[i].High, records[i].Low, records[i].Close], -1); // 添加 + ObjChart.add(1, [records[i].Time, r_quick], -1); + ObjChart.add(2, [records[i].Time, r_slow], -1); + } else if (records[i].Time > preBarTime) { + preBarTime = records[i].Time; + ObjChart.add(0, [records[i].Time, records[i].Open, records[i].High, records[i].Low, records[i].Close]); // 添加 + ObjChart.add(1, [records[i].Time, r_quick]); + ObjChart.add(2, [records[i].Time, r_slow]); + } + + } + ObjChart.update(chart); // 更新图表以显示出来。 + Sleep(2000); + } +} diff --git "a/app\344\273\267\346\240\274\346\217\220\351\206\222.js" "b/app\344\273\267\346\240\274\346\217\220\351\206\222.js" deleted file mode 100644 index 37cc804b..00000000 --- "a/app\344\273\267\346\240\274\346\217\220\351\206\222.js" +++ /dev/null @@ -1,50 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/4987 -策略名称: app价格提醒 -策略作者: fxlee -策略描述: - -当前成交价格达到设定后触发,支持多平台。只保留整数,预防频繁推送 - - -参数 默认值 描述 --------- ----- ---- -Interval 60 检测间隔 -MaxPrice 2000 最大价格 -MinPrice 1000 最小价格 -*/ - - -var oldmsg=""; - -function push(){ - var msg="价格提醒:\n"; - var max=0; - var min=100000; - for(i=0;iMaxPrice||min minMoney && amount >= exchange.GetMinStock()) { - if (exchange.Buy(price, amount, "做多")) { - LastBuyPrice = LastHighPrice = price; - } - } -} - -function main() { - InitAccount = GetAccount(); - Log(exchange.GetName(), exchange.GetCurrency(), InitAccount); - LoopInterval = Math.max(LoopInterval, 1); - while (true) { - onTick(exchange); - Sleep(LoopInterval*1000); - } -} diff --git "a/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" "b/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" index d27d212d..2bebfe21 100644 --- "a/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" +++ "b/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" @@ -210,7 +210,7 @@ def main(): exchange.SetContractType(["this_week","next_week","quarter"][ContractTypeIdx]) exchange.SetMarginLevel([10,20][MarginLevelIdx]) - Log("Fee:",exchange.GetFee()) + # Log("Fee:",exchange.GetFee()) if len(exchange.GetPosition()) > 0: raise Error_AtBeginHasPosition CancelPendingOrders() diff --git "a/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" "b/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" index 86575cc2..37f20c8d 100644 --- "a/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" +++ "b/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" @@ -102,6 +102,7 @@ def PlotRecords(records, title = None): global labelIdx, series, preBarTime, chart if not chart : chart = Chart(cfg) + chart.reset() if ("candlestick" in labelIdx) == False : cfg["__isStock"] = True seriesIdx = len(series) @@ -139,6 +140,7 @@ def PlotLine(label, dot, Ntime = None): "type" : "datetime" }) chart = Chart(cfg) + chart.reset() if (label in labelIdx) == False : seriesIdx = len(series) preDotTime.setdefault(str(seriesIdx), 0) @@ -168,6 +170,7 @@ def PlotFlag(time, text, title, shape = "", color = ""): global chart, cfg, labelIdx, preFlagTime if not chart : chart = Chart(cfg) + chart.reset() label = "flag" if (label in labelIdx) == False : seriesIdx = len(series) diff --git "a/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" "b/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" index dd3bd261..51a13f6c 100644 --- "a/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" +++ "b/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" @@ -383,7 +383,7 @@ def pollTask(self, task): remain = task["amount"] - task["dealAmount"] if (remain <= 0 or task["retry"] >= task["maxRetry"]): ret = { - "price" : (pos["Cost"] - task["preCost"]) / (pos["Amount"] - task["preAmount"]), + "price" : (0 if task["dealAmount"] == 0 else (pos["Cost"] - task["preCost"]) / (pos["Amount"] - task["preAmount"])), "amount" : (pos["Amount"] - task["preAmount"]), "position" : pos } diff --git "a/python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.py" "b/python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.py" index f79451be..3d9b9ba5 100644 --- "a/python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.py" +++ "b/python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.py" @@ -7,14 +7,15 @@ 现货数字货币交易类库(python版) -参数 默认值 描述 ----------- ----- ------------------ -OpMode 0 下单方式: 吃单|挂单 -MaxSpace 0.5 挂单失效距离 -SlidePrice 0.1 下单滑动价 -MaxAmount 0.8 开仓单次最大下单量 -RetryDelay 500 失败重试毫秒 -MAType 0 均线类型: TA.EMA|TA.MA +参数 默认值 描述 +------------- ------ ------------------ +OpMode 0 下单方式: 吃单|挂单 +MaxSpace 0.5 挂单失效距离 +SlidePrice 0.1 下单滑动价 +MaxAmount 0.8 开仓单次最大下单量 +RetryDelay 500 失败重试毫秒 +MAType 0 均线类型: TA.EMA|TA.MA +_GetMinStocks 0.01 最小交易量 ''' import types # 导入类型模块 @@ -78,7 +79,7 @@ def GetAccount(e, waitFrozen = False): alreadyAlert = False while True: account = _C(e.GetAccount) - if(not waitFrozen or (account.FrozenStocks < e.GetMinStock() and account.FrozenBalance < 0.01)): + if(not waitFrozen or (account.FrozenStocks < _GetMinStocks and account.FrozenBalance < 0.01)): break if(not alreadyAlert): alreadyAlert = True @@ -138,7 +139,7 @@ def Trade(e,tradeType,tradeAmount,mode,slidePrice,maxAmount,maxSpace,retryDelay) diffMoney = _N(nowAccount.Balance - initAccount.Balance,4) dealAmount = _N(initAccount.Stocks - nowAccount.Stocks,4) doAmount = min(maxAmount,tradeAmount - dealAmount,nowAccount.Stocks) - if(doAmount < e.GetMinStock()): + if(doAmount < _GetMinStocks): break prePrice = tradePrice orderId = tradeFunc(tradePrice,doAmount,ticker) diff --git "a/stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).js" "b/stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).js" new file mode 100644 index 00000000..f0b0c879 --- /dev/null +++ "b/stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).js" @@ -0,0 +1,333 @@ +/* +策略出处: https://www.botvs.com/strategy/20383 +策略名称: stochRSI策略 (指标框架) +策略作者: 小小梦 +策略描述: + +stochRSI指标策略 + +*/ + +/*参数 +stochRSI 指标参数 数组 [14,14,3,3] +使用现货数字货币交易类库 +*/ +var stochRSI_P_arr = "[14,14,3,3]"; + + +var Interval = 500; + +var long = 1; +var free = 0; +var state = free; //每次开仓 平仓 重置 +var buyInfo = null; //每次平仓重置 +var sellInfo = null; //每次开仓重置 +var initAccount = null; //每次平仓重置 +var beginAccount = null; //不重置 +var Profit = 0; //已实现盈亏 +var prefloatProfit = 0;//上次的浮动盈亏,滑动止盈 更新 +var openBalance = 0;//开仓量 +var isCover = false; + +var NowPositionInfo = {//持仓信息, 每次平仓更新 + avgPrice: 0, + amount: 0 , + floatProfit: 0 +}; + +function openUpdate(){//开仓后的更新 + state = long; + sellInfo = null; +} +function closeUpdate(){//平仓后的更新 + state = free; + addLevel = 0; + buyInfo = null; + initAccount = _C(exchange.GetAccount); + NowPositionInfo.avgPrice = 0; + NowPositionInfo.amount = 0; + NowPositionInfo.floatProfit = 0; + isCover = true; +} + +function Calculate(nowAccount,nowDepth){//计算并更新收益 、 浮动收益 、计算 持仓均价 、持仓量 + if(typeof(nowAccount) === 'undefined' ){ + nowAccount = _C(exchange.GetAccount); + nowDepth = _C(exchange.GetDepth); + } + var diff_stocks = nowAccount.Stocks - initAccount.Stocks;//币之差 + var diff_balance = nowAccount.Balance - initAccount.Balance;//钱之差 + NowPositionInfo.avgPrice = Math.abs(diff_balance) / Math.abs(diff_stocks); + NowPositionInfo.amount = Math.abs(diff_stocks); + NowPositionInfo.floatProfit = diff_balance + diff_stocks * nowDepth.Bids[0].Price; //此次交易的浮动盈亏 + Profit = (initAccount.Stocks - beginAccount.Stocks) * nowDepth.Bids[0].Price + (initAccount.Balance - beginAccount.Balance); //实现盈亏 + + //更新入界面 +} + +function LLV(array,period){ + if(!array || array.length - period < 0){ + throw "error:" + array; + } + var min = array[array.length - period]; + for(var i = array.length - period; i < array.length; i++){ + if( array[i] < min ){ + min = array[i]; + } + } + return min; +} + +function HHV(array,period){ + if(!array || array.length - period < 0){ + throw "error:" + array; + } + var max = array[array.length - period]; + for(var i = array.length - period; i < array.length; i++){ + if( array[i] > max){ + max = array[i]; + } + } + return max; +} + +function DeleteNullEle(initArr){ + var dealArr = []; + var initArrLen = initArr.length; + for(var i = 0,j = 0 ; i < initArrLen ; i++,j++){ + if(initArr[i] === null || isNaN(initArr[i]) ){ + j--; + continue; + } + dealArr[j] = initArr[i]; + } + return dealArr; +} + +/* +LC := REF(CLOSE,1); //REF(C,1) 上一周期的收盘价 +RSI:=SMA(MAX(CLOSE-LC,0),N,1)/SMA(ABS(CLOSE-LC),N,1) *100; +%K: MA(RSI-LLV(RSI,M),P1)/MA(HHV(RSI,M)-LLV(RSI,M),P1)*100; LLV(l,60)表示:检索60天内的最低价,可适应于检索任何股票 +%D:MA(%K,P2); + +LC := REF(CLOSE,1); +RSI:=SMA(MAX(CLOSE-LC,0),N,1)/SMA(ABS(CLOSE-LC),N,1) *100; +STOCHRSI:MA(RSI-LLV(RSI,M),P1)/MA(HHV(RSI,M)-LLV(RSI,M),P1)*100; +*/ +function FstochRSI(records,n,m,p1,p2){ + var len = records.length; + //var LC = records[len-2];//上一周期收盘价 + //var rsi = TA.RSI(records,n);// RSI 数组 ,talib + var rsi = talib.RSI(records,n); + rsi = DeleteNullEle(rsi);//ceshi + //Log("rsi:",rsi) //测试 + //Log("rsi:",rsi);//ceshi + //throw "stop";//ceshi + table.e5 = "rsi :" + rsi[rsi.length-1] + "rsi[-1]:" + rsi[rsi.length-2];//ceshi + + var arr1 = []; + var arr2 = []; + var arr3 = []; + var arr4 = []; + var rsi_a = []; + var rsi_b = []; + var k = []; + var d = null; + + /*不包含当前柱 + for(var a = 0 ;a < rsi.length ; a++ ){//改造 不用 LLV + for(var aa = 0 ; aa <= a; aa++ ){ + rsi_a.push(rsi[aa]); + } + arr1.push(rsi[a] - TA.Lowest(rsi_a,m)); + } + for(var b = 0 ;b < rsi.length ; b++ ){//改造 不用 HHV + for(var bb = 0 ; bb <= b; bb++ ){ + rsi_b.push(rsi[bb]); + } + arr2.push(TA.Highest(rsi_b,m) - TA.Lowest(rsi_b,m)); + } + */ + for(var a = 0 ;a < rsi.length ; a++ ){//改造 不用 LLV + if(a < m){ + continue; + } + for(var aa = 0 ; aa <= a; aa++ ){ + rsi_a.push(rsi[aa]); + } + arr1.push(rsi[a] - LLV(rsi_a,m)); + } + for(var b = 0 ;b < rsi.length ; b++ ){//改造 不用 HHV + if(b < m){ + continue; + } + for(var bb = 0 ; bb <= b; bb++ ){ + rsi_b.push(rsi[bb]); + } + arr2.push(HHV(rsi_b,m) - LLV(rsi_b,m)); + } + + arr1 = DeleteNullEle(arr1); + arr2 = DeleteNullEle(arr2); + //Log("arr1:",arr1.length,"-",arr1);//ceshi + //Log("arr2:",arr2.length,"-",arr2);//ceshi + + arr3 = talib.MA(arr1,p1); + arr4 = talib.MA(arr2,p1); + + arr3 = DeleteNullEle(arr3); + arr4 = DeleteNullEle(arr4); + + //Log("ceshi");//ceshi + var c = 0; + var diff = 0; + if(arr3.length !== arr4.length){//实测 长度不相等 + throw "error: !=" + arr3.length + "----" + arr4.length; + diff = arr4.length - arr3.length; //example diff = 10 - 6 + }else{ + //throw "error:" + arr3.length + "----" + arr4.length; + } + + for( ;c < arr3.length ; c++ ){ + k.push(arr3[c] / arr4[c + diff] * 100); + } + + d = talib.MA(k,p2); + + return [k,d,rsi]; +} + +function Loop(){//循环主体 + /* + var go_account = exchange.Go("GetAccount"); + var go_records = exchange.Go("GetRecords"); + var go_depth = exchange.Go("GetDepth"); + + var account = go_account.wait(1000); + var records = go_records.wait(1000); + var depth = go_depth.wait(1000); + + if(account === null || records === null || depth === null){ + //显示异常 + return; + } + */ + // + var account = _C(exchange.GetAccount); + var records = _C(exchange.GetRecords); + var depth = _C(exchange.GetDepth); + //测试 + + var len = records.length - 1; + + if(records.length < array_P[0] || records.length < array_P[1] || records.length < array_P[2] || records.length < array_P[3] ){ + //输出到状态栏表格,显示K线长度不足 + msg = "K线长度不足,获取中..."; + return; + } + + //* + var records_close = []; + for(var i = 0; i <= len; i++){ + records_close.push(records[i].Close); + } + //*/ + + msg = "K line `s length:" + (len + 1); + + //var ma = TA.MA(records,3);//测试 使用 MA3 + + //var stochRSI = talib.STOCHRSI(records,array_P[0],array_P[1],array_P[2],array_P[3]); + //var stochRSI = talib.STOCHRSI(records_close,14,3,3,3); + var stochRSI = FstochRSI(records,14,14,3,3); + var fastLine = stochRSI[0]; //stochrsi + var slowLine = stochRSI[1]; // ma(k,3) + + //Log("fastLine:",fastLine);//ceshi + //Log("slowLine:",slowLine);//ceshi + //var slowLine = ma; + //var rsi = stochRSI[2]; + + $.Draw(records); + $.AddZhiBiao(fastLine,records,1); + $.AddZhiBiao(slowLine,records,2); + if(isFirst === true){ + $.SignOP((new Date()).getTime(),null,null,3,"图表显示启动!");// 测试标记 自定义信息 到图表上 + Log(array_P[0],array_P[1],array_P[2],array_P[3],typeof(array_P[3]));//ceshi + isFirst = false; + } + table.a4 = "fastLine[len]:" + _N(fastLine[fastLine.length-1],2); + table.b4 = "slowLine[len]:" + _N(slowLine[slowLine.length-1],2); + + table.a5 = "fastLine[len-1]" + _N(fastLine[fastLine.length-2],2); + table.b5 = "slowLine[len-1]" + _N(slowLine[slowLine.length-2],2); + table.c5 = "fastLine[len-2]" + _N(fastLine[fastLine.length-3],2); + table.d5 = "slowLine[len-2]" + _N(slowLine[slowLine.length-3],2); + //table.e5 = "rsi:" + rsi[rsi.length - 1] + "rsi[-2]:" + rsi[rsi.length - 2] + "rsi[-3]:" + rsi[rsi.length - 3]; + + + table.b1 = "stock:" + account.Stocks + "#ff00ff"; + table.c1 = "Fstock:" + account.FrozenStocks + "#ff00ff"; + table.d1 = "balance:" + account.Balance + "#ff00ff"; + table.e1 = "Fbalance:" + account.FrozenBalance + "#ff00ff"; + table.b2 = "open:" + records[len].Open; + table.c2 = "high:" + records[len].High; + table.d2 = "low:" + records[len].Low; + table.e2 = "close:" + records[len].Close; + table.b3 = "bids[0].price:" + depth.Bids[0].Price; + table.c3 = "bids[0].amount:" + depth.Bids[0].Amount; + table.d3 = "asks[0].price:" + depth.Asks[0].Price; + table.e3 = "asks[0].amount:" + depth.Asks[0].Amount; + + table.c4 = "avgPrice:" + NowPositionInfo.avgPrice; + table.d4 = "amount:" + NowPositionInfo.amount; + table.e4 = "floatProfit:" + NowPositionInfo.floatProfit; + + + if(isCover === true){ + LogProfit(Profit); + isCover = false; + } + Calculate();// + //Log("ceshi2");//ceshi2 + $.UpDateChart(records); + //Log("ceshi2");//ceshi2 +} + +var table = null; +var array_P = null; +var msg = "";//显示在状态栏表格头部的 消息 +var isFirst = true; + +function main(){ + //初始化 + beginAccount = _C(exchange.GetAccount);//程序开始运行时的初始账户信息 + initAccount = beginAccount;//每次开仓前的账户信息 + table = $.TableInit(5,6); + table.a1 = "account:" + "#ff00ff"; + table.a2 = "records[length-1]:"; + table.a3 = "depth.Bids[0]/Asks[0]:"; + table.a0 = "beginAccount:"; + table.b0 = "stock:" + beginAccount.Stocks; + table.c0 = "Fstock:" + beginAccount.FrozenStocks; + table.d0 = "balance:" + beginAccount.Balance; + table.e0 = "Fbalance:" + beginAccount.FrozenBalance; + + array_P = JSON.parse(stochRSI_P_arr);// 解析 stochRSI 参数 + + + while(true){ + Loop(); + $.UpDateLogStatus(msg); + msg = ""; + Sleep(Interval); + } +} + +/*任务 +1、UI界面显示完善 +2、交互模块写好 +3、交易逻辑 +4、参数设置 +5、可视图表 +*/ diff --git "a/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest (\345\244\215\345\210\266)5560.js" "b/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest (\345\244\215\345\210\266)5560.js" deleted file mode 100644 index a4c9259f..00000000 --- "a/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest (\345\244\215\345\210\266)5560.js" +++ /dev/null @@ -1,134 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/8487 -策略名称: 【Demo】速度测试 websocket vs rest (复制)5560 -策略作者: 总值约: 23938.37 元 -策略描述: - -websocket 测试,支持添加多个交易所测试,注意会短时增加你的api调用频率,请在确保不影响其他机器人运行的情况下运行。如果出现”Futures_OP 4: argument error“的错误,请更新到最新的托管者程序 - -*/ - - - -var Interval=1000; - -function _N(v, precision) { - - - - if (typeof (precision) != 'number') { - - - - precision = 4; - - - - } - - - - var d = parseFloat(v.toFixed(Math.max(10, precision + 5))); - - - - s = d.toString().split("."); - - - - if (s.length < 2 || s[1].length <= precision) { - - - - return d; - - - - } - - - var b = Math.pow(10, precision); - - - - return Math.floor(d * b) / b; - - - -} - - - - -function onexit() { - - Log("【【【系统退出】】】"); -} - - -function main() { - - - - var start=Date.now(); - - - - for (var i = 0; i < exchanges.length; i++) { - - - var ecg=exchanges[i]; - //Log(ecg); - - ecg.IO("rest");//rest 模式 - var iii=0; - var sum=0; - while (iii<=10) { //连续调用10次,取平均值 - - var account = null; - start=Date.now(); - account = ecg.GetAccount(); //测试执行的API函数,可根据需要自己修改,如 GetTick - iii=iii+1; - if(account){ - var delay=(Date.now()-start); - sum=sum+delay; - - } - - - - - Sleep(1000); - - } - Log("平均毫秒数【"+_N(sum/iii,2)+"】"+ecg.GetName()+" rest"); - - ecg.IO("websocket"); //websocket 模式 - sum=0; - iii=0; - while (iii<=10) { //连续调用10次,取平均值 - - var account = null; - start=Date.now(); - account = ecg.GetAccount(); //测试执行的API函数,可根据需要自己修改,如 GetTick - iii=iii+1; - if(account){ - var delay=(Date.now()-start); - sum=sum+delay; - - } - - - - - Sleep(1000); - - } - Log("平均毫秒数【"+_N(sum/iii,2)+"】"+ecg.GetName()+" websocket"); - } -} - - - - - diff --git "a/\344\270\200\347\233\256\345\235\207\350\241\241.js" "b/\344\270\200\347\233\256\345\235\207\350\241\241.js" new file mode 100644 index 00000000..d6d21fd4 --- /dev/null +++ "b/\344\270\200\347\233\256\345\235\207\350\241\241.js" @@ -0,0 +1,231 @@ +/* +策略出处: https://www.botvs.com/strategy/55839 +策略名称: 一目均衡 +策略作者: icesun963 +策略描述: + +一目均衡 初级版 + +小时线为基准,测一个月到两月。 +通过云层厚度,基准线和转换线为信号,进行买入卖出。 +未作判断止损。 + + +参数 默认值 描述 +------------------ ----- --------------------- +keh 12 HullMA +TenkanSenPeriods 9 TenkanSen转换值间隔 +KijunSenPeriods 24 Kijun Sen基准线 间隔 +SenkouSpanBPeriods 51 Senkou Span B 先行上限2间隔 +displacement 24 Displacement延迟线间隔 +CX 100 云层厚度 +*/ + +var diffarray = []; +var diff1array = []; +var TenkanSenArray = []; +var KijunSenArray = []; +var SenkouSpanBArray = []; +var SenkouSpanAArray = []; +var lastOrderId = null; +var absAB = []; +var closeArray = []; + + + +var cross = function(values1, values2) { + + var r1 = values1[values1.length - 1]; + var r2 = values1[values1.length - 2]; + var r21 = values2[values2.length - 1]; + var r22 = values2[values2.length - 2]; + //Log(r1 + " " + r2 + " " + r21 + " " + r22); + if (r21 > r1 && r2 > r22) { + return true; + } + if (r21 < r1 && r2 < r22) { + return true; + } + return false; +} + +function min(a, b) { + if (a < b) + return a; + else + return b; +} + +function max(a, b) { + if (a > b) + return a; + else + return b; +} + +function avg(a, b) { + return (a + b) / 2; +} + +function donchian(records, len) { + + var hig = TA.Highest(records, len, 'High'); + var low = TA.Lowest(records, len, 'Low'); + //Log("hig:" + hig + " low:" + low); + + return avg(hig, low); + //avg(lowest(len), highest(len)) + +} + +function cloudStats() { + + var a = absAB[absAB.length - 1]; + + var logx = a + " "; + for (var i = 1; i < 10; i++) { + var b = absAB[absAB.length - i]; + var x = Math.abs(b - a); + var q = x / a; + + if (x < 0.1) { + + } else { + if (a > b) { + return 1; + } else { + return -1; + } + } + logx += b + " " + + } + //Log(logx); + return 0; +} + + +function onTick(exchange) { + var records = exchange.GetRecords(); + var ticker = exchange.GetTicker(); + + //Log("onTick"); + var close = records[records.length - 1].Close; + closeArray.push(close); + + var wma = talib.WMA(records, Math.round(keh / 2)); + //Log(wma); + var n2ma = 2 * wma[records.length - 1]; + //Log(n2ma); + var wma2 = talib.WMA(records, keh); + + var nma = wma2[records.length - 1]; + var diff = n2ma - nma; + var sqn = Math.round(Math.sqrt(keh)); + + var n2ma1 = 2 * wma[records.length - 2]; + var nma1 = wma2[records.length - 2]; + var diff1 = n2ma1 - nma1; + //var sqn1 = Math.round(Math.sqrt(keh)); + diffarray.push(diff); + diff1array.push(diff1); + //Log(diff + " " + diff1); + var dwma = talib.WMA(diffarray, sqn); + var d1wma = talib.WMA(diff1array, sqn); + + var n1 = dwma[dwma.length - 1]; + var n2 = d1wma[d1wma.length - 1]; + var b = n1 > n2 ? "lime" : "red"; + var c = n1 > n2 ? "green" : "red" + var d = n1 > n2 ? "red" : "green"; + //Log(b + " " + c + " " + d); + //Log(n1 + " " + n2); + + var ttime = records[records.length - 1].Time; + //转换值=(包含今天的9日的最高价+9日的最低价)/2 + var TenkanSen = donchian(records, TenkanSenPeriods); + TenkanSenArray.push(TenkanSen); + + // 基准值=(包含今天的26日的最高价+26日最低价)/2 + var KijunSen = donchian(records, KijunSenPeriods); + KijunSenArray.push(KijunSen); + + // 先行上限1 (Span A) (转化值+基准值)/2 + var SenkouSpanA = avg(TenkanSen, KijunSen); + SenkouSpanAArray.push(SenkouSpanA); + + //先行上限2 (Span B) (52天的最高值+52天的最低值)/2 + var SenkouSpanB = donchian(records, SenkouSpanBPeriods); + SenkouSpanBArray.push(SenkouSpanB); + + var absx = Math.abs(SenkouSpanA - SenkouSpanB); + //云层由Span A和Span B组成 + + absAB.push(absx); + + var SenkouSpanH = max(SenkouSpanAArray[records.length - displacement], SenkouSpanBArray[records.length - displacement]); + var SenkouSpanL = min(SenkouSpanAArray[records.length - displacement], SenkouSpanBArray[records.length - displacement]); + //延迟线 (Chinkou Span ) ( 绿线)当天的收盘价作为26天前的延迟线 + + if(typeof(records[records.length - displacement])!="undefined"){ + var ChikouSpan = records[records.length - displacement].Close; + $.PlotLine("ChikouSpan(延迟线)", ChikouSpan, ttime, "green"); + } + + + + + //$.PlotLine("n2", n2, ttime,"yellow"); + //$.PlotLine("n1", n1, ttime,"yellow"); + $.PlotLine("k", close, ttime, "black"); + //if (records.length > displacement + 1) + // $.PlotLine("k2", records[records.length - displacement].Close, ttime); + $.PlotLine("TenkanSen(转换值)", TenkanSen, ttime, "red"); + $.PlotLine("KijunSen(基准线)", KijunSen, ttime, "blue"); + + + + $.PlotLine("SenkouSpanA(云层A)", SenkouSpanA, ttime, "gray"); + $.PlotLine("SenkouSpanB(云层B)", SenkouSpanB, ttime, "gray"); + + //$.PlotLine("Cloud(云层厚度)",absx + 3500, ttime,"lime"); + //if (n1 > n2 && close > n2 && close > ChikouSpan) { + // Log("N1:" + n1 + " n2:" + n2 + " close:" + close); + // Log(" ChikouSpan:" + ChikouSpan + " TenkanSen:" + TenkanSen + " KijunSen:" + KijunSen); + // Log("SenkouSpanH :" + SenkouSpanH + " SenkouSpanL:" + SenkouSpanL); + //} + var longCondition = (TenkanSen >= KijunSen || close > KijunSen); + var price = ticker.Last; + //Log("cloudStats"); + //Log(cloudStats()); + + if (cross(TenkanSenArray, closeArray) && cross(KijunSenArray, closeArray)) { + $.PlotFlag(ttime, "Q", "Q", "circlepin", "green"); + + if (absx < CX) { + if (close < TenkanSen) { + exchange.Buy(price, 1, "做多"); + } else { + exchange.Sell(price, 1, "做空"); + } + } else { + if (close > TenkanSen) { + exchange.Buy(price, 1, "做多2"); + } else { + exchange.Sell(price, 1, "做空2"); + } + } + + } + + + +} + +function main() { + Log(exchange.GetAccount()); + while (true) { + onTick(exchange); + Sleep(60 * 60 * 1000); + } +} diff --git "a/\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.js" "b/\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.js" new file mode 100644 index 00000000..4506145e --- /dev/null +++ "b/\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.js" @@ -0,0 +1,43 @@ +/* +策略出处: https://www.botvs.com/strategy/54182 +策略名称: 仓位均衡策略 +策略作者: 春哥 +策略描述: + + + + +参数 默认值 描述 +--------------- ----- ----- +TARGET_POSITION 0.5 固定仓位 +ACT_DIFF 0.1 仓位变化量 +*/ + +function main() { + while (true) { + Sleep(300000); + + var account = $.GetAccount(); + var ticker = exchange.GetTicker(); + var stockValue = account.Stocks * ticker.Last; + var totalValue = stockValue + account.Balance; + var position = stockValue / totalValue; + var trade_amount = 0; + if ( position > TARGET_POSITION + ACT_DIFF ) { + trade_amount = (position - TARGET_POSITION) * totalValue / ticker.Buy; + $.Sell(trade_amount); + } else if ( position < TARGET_POSITION - ACT_DIFF ) { + trade_amount = (TARGET_POSITION - position) * totalValue / ticker.Sell; + $.Buy(trade_amount); + } else { + Sleep(60000); + continue; + } + + $.CancelPendingOrders(); + account = $.GetAccount(); + stockValue = account.Stocks * ticker.Last; + LogProfit(account.Balance + stockValue); + } +} + diff --git "a/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245 (Copy).js" "b/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245 (Copy).js" deleted file mode 100644 index 519bcbf7..00000000 --- "a/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245 (Copy).js" +++ /dev/null @@ -1,142 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/43422 -策略名称: 使用 BotVS 构建一个机械化策略 (Copy) -策略作者: zhangdeli -策略描述: - -知乎专栏文章 附带策略 -使用 BotVS 构建一个机械化策略 - -*/ - -// 参数 -var ContractType = "rb1710"; -var PointAmount = 1; -var NetSize = 30; -var Interval = 500; -var SumPoints = 10; -var CoverRatio = 2; - -// 全局变量 -var Controller = { - symbol : null, - Amount : 0, - Size : 0, - BeginPrice : 0, - SumPoints : 0, - CoverRatio : 0, - Net_Long : [], - Net_Short : [], - ContractInfo : null, - isUpdateNetShow : false, // 是否要更新显示 -}; -var perBar = null; - -function loop(){ - var records = exchange.GetRecords(); - var ticker = exchange.GetTicker(); - if(!records || records.length == 0 || !ticker){ - return; - } - - if(records[records.length - 1].Time !== perBar.Time){ // 新 Bar 产生 - UpdateNet(ticker.Last); - perBar = records[records.length - 1]; - } - - // 画线 - $.PlotRecords(records, 'K线'); - - for(var i = 0; (i < Controller.Net_Long.length && Controller.isUpdateNetShow == true); i++){ // 更新显示 - $.PlotHLine(Controller.Net_Long[i].open, 'long' + i); - if(i == Controller.Net_Long.length - 1){ - for(var j = 0; j < Controller.Net_Short.length; j++){ - $.PlotHLine(Controller.Net_Short[j].open, 'short' + j, "green"); - } - $.PlotHLine(Controller.BeginPrice, 'begin', "black", "dash"); // 初始线 - Controller.isUpdateNetShow = false; - Log("更新显示!"); // ceshi - } - } - // throw "stop"; // ceshi - // Log(Controller.Net_Long); // cehsi -} - -function init(){ - Controller.symbol = ContractType; - Controller.Amount = PointAmount; - Controller.Size = NetSize; - Controller.SumPoints = SumPoints; - Controller.CoverRatio = 2; - - // 设置合约 - while(exchange.IO("status") == false || Controller.ContractInfo == null){ - Controller.ContractInfo = exchange.SetContractType(Controller.symbol); - LogStatus("时间:", new Date(), "等待连接服务器初始化。"); - Sleep(Interval); - } - - var ticker = _C(exchange.GetTicker); - var records = _C(exchange.GetRecords); - perBar = records[records.length - 1]; - // 初始更新网格 - UpdateNet(ticker.Last); -} - -function UpdateNet(price){ - // 校验网格是否没有持仓 - for(var n = 0; n < Controller.Net_Long.length; n++){ - if(Controller.Net_Long[n].hold !== 0){ - Log("Net_Long 网格仍有持仓!无法更新。"); - return false; - } - } - - for(var m = 0; m < Controller.Net_Short.length; m++){ - if(Controller.Net_Short[m].hold !== 0){ - Log("Net_Short 网格仍有持仓!无法更新。"); - return false; - } - } - - Controller.isUpdateNetShow = true; - - Controller.Net_Long = []; - Controller.Net_Short = []; - Controller.BeginPrice = price; - for(var i = 0; i < Controller.SumPoints; i++){ - var Long_point = { - open : _N(Controller.BeginPrice + (i + 1) * Controller.Size, 0), - cover : _N(Controller.BeginPrice + (i + 1) * Controller.Size + Controller.CoverRatio * Controller.Size, 0), - hold : 0, - } - Controller.Net_Long.push(Long_point); - } - for(var j = 0; j < Controller.SumPoints; j++){ - var Short_point = { - open : _N(Controller.BeginPrice - (j + 1) * Controller.Size, 0), - cover : _N(Controller.BeginPrice - (j + 1) * Controller.Size + Controller.CoverRatio * Controller.Size, 0), - hold : 0, - } - Controller.Net_Short.push(Short_point); - } -} - -function main(){ - // 入口函数初始化 - - // 主循环, 程序完成初始化后在此 循环执行,直到手动关闭。 - var LoginState = null; - var nowTimeStamp = 0; - while(true){ - nowTimeStamp = new Date().getTime(); - if(exchange.IO("status") == true){ - LoginState = true; - loop(); - }else{ - LoginState = false; - } - LogStatus("时间:", _D(nowTimeStamp), LoginState ? "已连接服务器" : "未连接服务器!"/*, 待显示的一些信息可以写在此处,如账户信息,实时行情,程序状态*/) - Sleep(Interval); // 暂停 0.5 秒, 避免轮询频率过高,访问交易所服务器过于频繁导致问题。 - } -} diff --git "a/\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.js" "b/\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.js" index fc29eaf3..16d0e29e 100644 --- "a/\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.js" +++ "b/\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.js" @@ -40,6 +40,11 @@ AutoRestore false 自动根据仓位恢复进度 Debug Log(exchange.GetAccount()) 调试 */ +/*backtest +start: 2016-01-15 09:00:00 +end: 2017-01-01 15:00:00 +period: 1d +*/ function Aberration(q, e, symbol, period, upRatio, downRatio, opAmount) { var self = {} self.q = q diff --git "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.py" "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.py" new file mode 100644 index 00000000..32216310 --- /dev/null +++ "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.py" @@ -0,0 +1,251 @@ +''' +策略出处: https://www.botvs.com/strategy/53512 +策略名称: 双平台对冲 练习用 求交流求指点 +策略作者: perseus +策略描述: + +Python 双平台对冲策略 + + +参数 默认值 描述 +------------ ----- ------------------------------- +LoopInterval 200 轮询周期(ms) +waitinterval 200 等待交易周期(ms) +r 0.95 balance decider +p true coefficient of arbitrage profit +q 0.2 balance trigger +''' + +import time +import numpy as np + +def reject_outliers(arr, m=2): + final_list = [x for x in arr if (x > np.mean(arr) - 2 * np.std(arr))] + final_list = [x for x in final_list if (x < np.mean(arr) + 2 * np.std(arr))] + return final_list + +def main(): + '''SetErrorFilter("canceled")''' + + LogReset() + LogProfitReset() + + global sellTrue + global buyTrue + sellTrue = 0 + buyTrue = 0 + initStocks = 0.0 + initBalance = 0.0 + lastTradeTime = 0 + lastTradeErrExchange = '' + accountsCache = [] + depthCache=[] + names = [] + buyPrice=0 + sellPrice=0 + dealtransactioned = False + + for e in exchanges: + names.append(e.GetName()) + account = _C(e.GetAccount) + initStocks += account.Stocks + initBalance += account.Balance + Log("Switch", e.GetLabel(), "To", e.IO("websocket")) + + Log("Total Currency:", _N(initBalance), "Total Asset", _N(initStocks), 'Python:', __import__('sys').version) + while (True): + LogStatus(_D()) + if not accountsCache: + accountsCache = [_C(e.GetAccount) for e in exchanges] + Sleep(LoopInterval) + depthA = exchanges[0].GetDepth() + depthCache.append(depthA) + if not depthA: + continue + depthB = exchanges[1].GetDepth() + depthCache.append(depthB) + if not depthB: + continue + + + '''trade part''' + + diffA = _N(depthA.Bids[0].Price - depthB.Asks[0].Price, 3) + diffB = _N(depthB.Bids[0].Price - depthA.Asks[0].Price, 3) + LogStatus("A平台币",exchanges[0].GetAccount().Stocks,"A平台钱",exchanges[0].GetAccount().Balance,"B平台币",exchanges[1].GetAccount().Stocks,"B平台钱",exchanges[1].GetAccount().Balance) + + if diffA > 0: + buytarget = depthB.Asks[0] + opAmount=min(depthA.Bids[0].Amount,buytarget.Amount) + buyAmount=min(opAmount,exchanges[1].GetAccount().Balance/buytarget.Price) + sellAmount=min(buyAmount,exchanges[0].GetAccount().Stocks) + + if diffA > (buyAmount*depthB.Asks[0].Price*0.2/100+sellAmount*depthA.Bids[0].Price*0.2/100)*p: + Log('buy from B sell at A') + Log("A平台币",exchanges[0].GetAccount().Stocks,"A平台钱",exchanges[0].GetAccount().Balance,"B平台币",exchanges[1].GetAccount().Stocks,"B平台钱",exchanges[1].GetAccount().Balance) + tradeAmount=min(buyAmount,sellAmount) + buyorder =exchanges[1].Buy(buytarget.Price,tradeAmount) + sellorder = exchanges[0].Sell(depthA.Bids[0].Price,tradeAmount) + canceller = 0 + + + while True: + + + + if (exchanges[1].GetOrder(buyorder).Status == 2) and (exchanges[0].GetOrder(sellorder).Status == 2): + Log('deal transactioned') + buyPrice = exchanges[1].GetOrder(buyorder).Price + sellPrice = exchanges[0].GetOrder(sellorder).Price + LogProfit(exchanges[0].GetOrder(sellorder).Amount*exchanges[0].GetOrder(sellorder).Price-exchanges[1].GetOrder(buyorder).Amount*exchanges[1].GetOrder(buyorder).Price) + dealtransactioned = True + break + elif ((exchanges[1].GetOrder(buyorder).Status == 1) or (exchanges[0].GetOrder(sellorder).Status == 1)): + buyPrice = exchanges[1].GetOrder(buyorder).Price + sellPrice = exchanges[0].GetOrder(sellorder).Price + canceller += 1 + dealtransactioned = True + Sleep(200) + elif ((exchanges[1].GetOrder(buyorder).Status == 0) and (exchanges[0].GetOrder(sellorder).Status == 0)): + Sleep(200) + canceller += 1 + if canceller == 5: + exchanges[1].CancelOrder(buyorder) + exchanges[0].CancelOrder(sellorder) + Log('deal cancelled') + break + + + + elif diffB > 0: + + opAmount=min(depthB.Bids[0].Amount,depthA.Asks[0].Amount) + buyAmount=min(opAmount,exchanges[0].GetAccount().Balance/depthA.Asks[0].Price) + sellAmount=min(buyAmount,exchanges[1].GetAccount().Stocks) + canceller = 0 + if diffB > (buyAmount*depthA.Asks[0].Price*0.2/100+sellAmount*depthB.Bids[0].Price*0.2/100)*p: + Log('buy from A sell at B') + + tradeAmount=min(buyAmount,sellAmount) + buyorder=exchanges[0].Buy(depthA.Asks[0].Price,tradeAmount) + sellorder=exchanges[1].Sell(depthB.Bids[0].Price,tradeAmount) + canceller =0 + + while True: + + if (exchanges[0].GetOrder(buyorder).Status == 2) and (exchanges[1].GetOrder(sellorder).Status == 2): + Log('deal transactioned') + buyPrice=exchanges[0].GetOrder(buyorder).Price + sellPrice=exchanges[1].GetOrder(sellorder).Price + LogProfit(exchanges[1].GetOrder(sellorder).Amount*exchanges[1].GetOrder(sellorder).Price-exchanges[0].GetOrder(buyorder).Amount*exchanges[0].GetOrder(buyorder).Price) + dealtransactioned = True + break + elif ((exchanges[0].GetOrder(buyorder).Status == 1) or (exchanges[1].GetOrder(sellorder).Status == 1)): + + buyPrice=exchanges[0].GetOrder(buyorder).Price + sellPrice=exchanges[1].GetOrder(sellorder).Price + canceller += 1 + dealtransactioned = True + Sleep(200) + elif ((exchanges[0].GetOrder(buyorder).Status == 0) and (exchanges[1].GetOrder(sellorder).Status == 0)): + Sleep(200) + canceller += 1 + if canceller == 5: + exchanges[0].CancelOrder(buyorder) + exchanges[1].CancelOrder(sellorder) + Log('deal cancelled') + break + + '''balance part''' + for i in [0,1]: + if dealtransactioned: + if(exchanges[i].GetAccount().Stocks > (initStocks/2)* q and exchanges[i].GetAccount().Balance < (initBalance/2)*q): + sellwait = 1 + Log('ready to sell') + loopbreaker = 0 + while (sellwait): + + if (_N(depthCache[i].Bids[0].Price,3)> buyPrice*r): + sellwait = 0 + + break + else: + Sleep(1000) + Log('sellwait') + loopbreaker += 1 + if loopbreaker == 600: + '''break''' + + + + sellTrue = 1 + + while(sellTrue): + dealprice = depthCache[i].Bids[0].Price + Log('insufficient money, sell some') + idealamount = initBalance/8 + availamount = exchanges[i].GetAccount().Stocks/2 + dealamount = min(idealamount,availamount) + balancesell = exchanges[i].Sell(depthCache[i].Bids[0].Price, dealamount) + Sleep(200) + while( exchanges[i].GetOrder(balancesell).Status not in [1,2] ): + exchanges[i].CancelOrder(balancesell) + if( dealprice > buyPrice): + dealprice -= 1 + balancesell = exchanges[i].Sell(dealprice,dealamount) + Sleep(200) + '''buyPrice=[]''' + Log("Sell Balance finished") + sellTrue=0 + + + if(exchanges[i].GetAccount().Balance > (initBalance/2)*q and exchanges[i].GetAccount().Stocks < (initStocks/2)*q): + buywait = 1 + loopbreaker = 0 + while (buywait): + + if(_N(depthCache[i].Asks[0].Price,3)< sellPrice*r): + + buywait=0 + + break + else: + Sleep(1000) + Log(_N(depthCache[i].Asks[0].Price,3),sellPrice*r) + loopbreaker +=1 + if loopbreaker == 600: + '''break + break''' + + + + + buyTrue = 1 + while(buyTrue): + Log('buyTrue started') + dealprice = depthCache[i].Asks[0].Price + Log('insufficient stocks, buy some') + idealamount = initStocks/8 + availamount = exchanges[i].GetAccount().Balance/dealprice/2 + dealamount = min(idealamount,availamount) + balancebuy = exchanges[i].Buy(dealprice,dealamount) + Sleep(200) + while(exchanges[i].GetOrder(balancebuy).Status not in [1,2]): + + exchanges[i].CancelOrder(balancebuy) + if (dealprice < sellPrice): + dealprice += 1 + balancebuy = exchanges[i].Buy(dealprice,dealamount) + Sleep(200) + '''sellPrice=[]''' + Log("Buy Balance finished") + buyTrue = 0 + break + else: + continue + break + else: + break + + + diff --git "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" new file mode 100644 index 00000000..63f826b2 --- /dev/null +++ "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" @@ -0,0 +1,225 @@ +/* +策略出处: https://www.botvs.com/strategy/57556 +策略名称: 双平台对冲js版本(two platforms hedging-JS) +策略作者: 7meter +策略描述: + + + + +参数 默认值 描述 +------------ ------ -------- +MinSpreadA 0.51 A->B差价 +MinSpreadB 0.52 B->A差价 +MaxAmount 0.3 最大操作量 +BalanceTime 10 平衡周期(秒) +LoopInterval 200 轮询周期(ms) + +按钮 默认值 描述 +---- ----- ---------- +A->B 0.51 更改价差(A->B) +B->A 0.52 更改价差(B->A) +*/ + +function cancelAll(){ + var ref = false; + for(var e in exchanges){ + while(true){ + var n = 0; + var my_orders = _C(exchanges[e].GetOrders); + for(var order1 in my_orders){ + ref = true; + e.CancelOrder(my_orders[order1].Id); + n += 1; + } + if(n==0){ + break; + } + } + } + return ret +} + +function main(){ + if(exchanges.length != 2){ + throw("Only two exchanges are supported"); + } + + LogReset(); + LogProfitReset(); + cancelAll(); + + var initStocks = 0.0; + var initBalance = 0.0; + var minAmount = 0.1; + var lastTradeTime = 0; + var lastTradeErrExchange = ''; + var accountsCache = []; + var hedgeNum = [0, 0]; + var names = []; + var baseCurrency = exchange.GetCurrency(); + for(var e in exchanges){ + if(exchanges[e].GetCurrency() != baseCurrency){ + throw("It has to be the same currency to hedge:"+baseCurrency); + } + names.push(exchanges[e].GetName()); + var account = _C(exchanges[e].GetAccount); + accountsCache.push(account); + initStocks += account.Stocks; + initBalance += account.Balance; + } + if(baseCurrency == "BTC"){ + minAmount = 0.01 + } else { + minAmount = 0.1 + } + + Log("all balance:", _N(initBalance), "all stocks", _N(initStocks)) + while(true){ + if(accountsCache.length <= 0){ + for(var e in exchanges){ + var account1 = _C(exchanges[e].GetAccount); + accountsCache.push(account1); + } + } + Sleep(LoopInterval); + cmd = GetCommand(); + if(cmd){ + Log("CMD", cmd); + var arr = cmd.split(":"); + if(arr[0]=="A->B"){ + MinSpreadA = parseFloat(arr[1]); + } else if(arr[0]=="B->A"){ + MinSpreadB = parseFloat(arr[1]); + } + } + var depthA = exchanges[0].GetDepth(); + if (!depthA){ + continue; + } + var depthB = exchanges[1].GetDepth(); + if (!depthB){ + continue; + } + var time = new Date(); + if(lastTradeTime > 0 && time.getTime() - lastTradeTime > BalanceTime){ + var needUpdate = cancelAll(); + if (!needUpdate){ + for(var account2 in accountsCache){ + if(accountsCache[account2].FrozenBalance >= 0.1 || accountsCache[account2].FrozenStocks >= 0.001){ + needUpdate = true; + break; + } + } + } + if (needUpdate){ + for(var k in exchanges){ + account3 = _C(exchanges[k].GetAccount); + accountsCache.push(account3); + } + } + var nowStocks = 0.0; + var nowBalance = 0.0; + for(var account4 in accountsCache){ + nowBalance += accountsCache[account4].Balance; + nowStocks += accountsCache[account4].Stocks; + } + var diff = _N(nowStocks-initStocks, 5); + var isReverse; + if(Math.abs(diff) < minAmount){ + LogProfit(_N(nowBalance-initBalance, 3), "all balance", _N(nowBalance), "all stocks", _N(nowStocks), "stock offset:", diff); + lastTradeTime = 0; + } else if(diff > minAmount){ + isReverse = depthA.Bids[0].Price < depthB.Bids[0].Price; + } else if(-diff > minAmount){ + isReverse = depthA.Asks[0].Price > depthB.Asks[0].Price; + } + if(isReverse != null){ + var depths = [depthA, depthB]; + var opAmount; + var kk; + if(isReverse){ + kk = [1, 0]; + } else{ + kk = [0, 1]; + } + for(var pos in kk){ + if(diff > minAmount){ + opAmount = Math.min(diff, accountsCache[pos].Stocks, depths[pos].Bids[0].Amount + depths[pos].Bids[1].Amount); + diff = -opAmount; + if(opAmount >= minAmount){ + exchanges[pos].Sell(depths[pos].Bids[1].Price, opAmount); + } + } else if(-diff >= minAmount){ + opAmount = Math.min(-diff, _N(accountsCache[pos].Balance / depths[pos].Asks[1].Price, 3), depths[pos].Asks[0].Amount + depths[pos].Asks[1].Amount); + diff += opAmount; + if (opAmount >= minAmount){ + exchanges[pos].Buy(depths[pos].Asks[1].Price, opAmount); + } + } + } + if (opAmount != undefined){ + var time1 = new Date(); + lastTradeTime = time1.getTime(); + accountsCache = []; + } + } + continue; + } + var diffA = _N(depthA.Bids[0].Price - depthB.Asks[0].Price, 3) + var diffB = _N(depthB.Bids[0].Price - depthA.Asks[0].Price, 3) + LogStatus(JSON.stringify({type: 'table', title: 'status', cols: ['name', 'money', 'frozenmoney', 'stock', 'frozenstock', 'buyone', 'sellone', 'threshold', 'offset', 'num of times'], rows: [[names[0], accountsCache[0].Balance, accountsCache[0].FrozenBalance, accountsCache[0].Stocks, accountsCache[0].FrozenStocks, depthA.Bids[0].Price, depthA.Asks[0].Price, MinSpreadA, diffA, hedgeNum[0]], [names[1], accountsCache[1].Balance, accountsCache[1].FrozenBalance, accountsCache[1].Stocks, accountsCache[1].FrozenStocks, depthB.Bids[0].Price, depthB.Asks[0].Price, MinSpreadB, diffB, hedgeNum[0]]]})); + HPos = 0; + if (diffA >= MinSpreadA){ + orderH = depthA.Bids[0]; + orderL = depthB.Asks[0]; + exchangeH = 0; + exchangeL = 1; + accountH = accountsCache[0]; + accountL = accountsCache[1]; + } + else if (diffB >= MinSpreadB){ + HPos = 1; + orderH = depthB.Bids[0]; + orderL = depthA.Asks[0]; + exchangeH = 1; + exchangeL = 0; + accountH = accountsCache[1]; + accountL = accountsCache[0]; + } + else{ + continue; + } + + var opPrice = _N((orderH.Price + orderL.Price) / 2.0, 2); + var opAmount = Math.min(MaxAmount, orderH.Amount, orderL.Amount, accountH.Stocks, _N(accountL.Balance / opPrice, 3)); + if(opAmount >= minAmount){ + var tasks = [[exchangeH, "H"], [exchangeL, "L"]]; + if(lastTradeErrExchange == "L"){ + tasks.reverse(); + } + lastTradeErrExchange = ""; + for(var task in tasks){ + if(tasks[task][1] == "H"){ + var id = exchanges[tasks[task][0]].Sell(opPrice, opAmount); + if(id == undefined){ + lastTradeErrExchange = tasks[task][1]; + break; + } + } + if(tasks[task][1] == "L"){ + var id = exchanges[tasks[task][0]].Buy(opPrice, opAmount); + if(id == undefined){ + lastTradeErrExchange = tasks[task][1]; + break; + } + } + } + + var time = new Date(); + lastTradeTime = time.getTime(); + accountsCache = [] + hedgeNum[HPos] += 1 + } + } +} diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" index 8a48d650..74627562 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" @@ -4,42 +4,77 @@ 策略作者: Zero 策略描述: -商品期货交易类库 -``` -function main() { - var p = $.NewPositionManager(); - p.OpenShort("MA609", 1); - p.OpenShort("MA701", 1); - Log(p.GetPosition("MA609", PD_SHORT)); - Log(p.GetAccount()); - Log(p.Account()); - Sleep(60000 * 10); - p.CoverAll("MA609"); - LogProfit(p.Profit()); - Log($.IsTrading("MA609")); - // 多品种时使用交易队列来完成非阻塞的交易任务 - var q = $.NewTaskQueue(); - q.pushTask(exchange, "MA701", "buy", 3, function(task, ret) { - Log(task.desc, ret) - }) - while (true) { - // 在空闲时调用poll来完成未完成的任务 - q.poll() - Sleep(1000) - } -} -``` - -`不断完善中...` - - -参数 默认值 描述 --------------- ----- ----------- -Interval 500 失败重试间隔(毫秒) -SlideTick true 滑价点数(整数) -RiskControl false 开启风控 -MaxTrade 100 工作日最多交易交易次数 -MaxTradeAmount 1000 单笔最多下单量 +商品期货交易类库 + + +> CTA库 +* 实盘会自动把指数映射到主力连续 +* 会自动处理移仓 +* 回测可以指定映射比如 rb000/rb888 就是把rb指数交易映射到主力连续 +* 也可以映射到别的合约, 比如rb000/MA888 就是看rb指数的K线来交易MA主力连续 + +``` +function main() { + $.CTA("rb000,M000", function(r, mp) { + if (r.length < 20) { + return + } + var emaSlow = TA.EMA(r, 20) + var emaFast = TA.EMA(r, 5) + var cross = $.Cross(emaFast, emaSlow); + if (mp <= 0 && cross > 2) { + Log("金叉周期", cross, "当前持仓", mp); + return 1 + } else if (mp >= 0 && cross < -2) { + Log("死叉周期", cross, "当前持仓", mp); + return -1 + } + }); +} +``` + +> 类库调用举例 +``` +function main() { + var p = $.NewPositionManager(); + p.OpenShort("MA609", 1); + p.OpenShort("MA701", 1); + Log(p.GetPosition("MA609", PD_SHORT)); + Log(p.GetAccount()); + Log(p.Account()); + Sleep(60000 * 10); + p.CoverAll("MA609"); + LogProfit(p.Profit()); + Log($.IsTrading("MA609")); + // 多品种时使用交易队列来完成非阻塞的交易任务 + var q = $.NewTaskQueue(); + q.pushTask(exchange, "MA701", "buy", 3, function(task, ret) { + Log(task.desc, ret) + }) + while (true) { + // 在空闲时调用poll来完成未完成的任务 + q.poll() + Sleep(1000) + } +} +``` + + +参数 默认值 描述 +--------------- ----- ------------ +Interval 500 失败重试间隔(毫秒) +SlideTick true 滑价点数(整数) +RiskControl false 开启风控 +MaxTrade 100 工作日最多交易交易次数 +MaxTradeAmount 1000 单笔最多下单量 +CTAShowPosition true 在状态栏显示持仓信息 +SyncInterval 5 账户与持仓同步周期(秒) +*/ + +/*backtest +start: 2017-08-01 00:00:00 +end: 2017-10-10 00:00:00 +period: 1d */ var __orderCount = 0 @@ -180,40 +215,69 @@ function Open(e, contractType, direction, opAmount) { return ret; } -function Cover(e, contractType) { +function Cover(e, contractType, lots) { var insDetail = _C(e.SetContractType, contractType); if (insDetail.MaxLimitOrderVolume == 0) { insDetail.MaxLimitOrderVolume = 50 } + var initAmount = 0; + var firstLoop = true; while (true) { var n = 0; - var opAmount = 0; + var total = 0; var positions = _C(e.GetPosition); + var nowAmount = 0; + for (var i = 0; i < positions.length; i++) { + if (positions[i].ContractType != contractType) { + continue; + } + nowAmount += positions[i].Amount; + } + if (firstLoop) { + initAmount = nowAmount; + firstLoop = false; + } + var amountChange = initAmount - nowAmount; + if (typeof(lots) == 'number' && amountChange >= lots) { + break; + } + for (var i = 0; i < positions.length; i++) { if (positions[i].ContractType != contractType) { continue; } var amount = Math.min(insDetail.MaxLimitOrderVolume, positions[i].Amount); var depth; + var opAmount = 0; + var opPrice = 0; if (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) { depth = _C(e.GetDepth); opAmount = Math.min(amount, depth.Bids[0].Amount); - if (!CanTrade(opAmount)) { - return; - } - e.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy"); - - e.Sell(depth.Bids[0].Price - (insDetail.PriceTick * SlideTick), opAmount, contractType, positions[i].Type == PD_LONG ? "平今" : "平昨", 'Bid', depth.Bids[0]); - n++; + opPrice = depth.Bids[0].Price - (insDetail.PriceTick * SlideTick); } else if (positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD) { depth = _C(e.GetDepth); opAmount = Math.min(amount, depth.Asks[0].Amount); + opPrice = depth.Asks[0].Price + (insDetail.PriceTick * SlideTick); + } + if (typeof(lots) === 'number') { + opAmount = Math.min(opAmount, lots - (initAmount - nowAmount)); + } + if (opAmount > 0) { if (!CanTrade(opAmount)) { return; } - e.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell"); - e.Buy(depth.Asks[0].Price + (insDetail.PriceTick * SlideTick), opAmount, contractType, positions[i].Type == PD_SHORT ? "平今" : "平昨", 'Ask', depth.Asks[0]); - n++; + if (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) { + e.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy"); + e.Sell(opPrice, opAmount, contractType, positions[i].Type == PD_LONG ? "平今" : "平昨", 'Bid', depth.Bids[0]); + } else { + e.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell"); + e.Buy(opPrice, opAmount, contractType, positions[i].Type == PD_SHORT ? "平今" : "平昨", 'Ask', depth.Asks[0]); + } + n++ + } + // break to check always + if (typeof(lots) === 'number') { + break; } } if (n === 0) { @@ -295,7 +359,10 @@ function AccountToTable(jsStr, title) { rows: [] }; try { - var fields = JSON.parse(jsStr); + var files = null; + if (typeof(jsStr) === 'string') { + fields = JSON.parse(jsStr); + } for (var k in fields) { if (k == 'AccountID' || k == 'BrokerID') { continue @@ -355,11 +422,11 @@ var PositionManager = (function() { return Open(this.e, contractType, PD_SHORT, shares); }; - PositionManager.prototype.Cover = function(contractType) { + PositionManager.prototype.Cover = function(contractType, lots) { if (!this.account) { this.account = _C(this.e.GetAccount); } - return Cover(this.e, contractType); + return Cover(this.e, contractType, lots); }; PositionManager.prototype.CoverAll = function() { if (!this.account) { @@ -399,6 +466,19 @@ $.NewPositionManager = function(e) { return new PositionManager(e); }; +function ins2product(symbol) { + symbol = symbol.replace('SPD ', '').replace('SP ', ''); + var shortName = ""; + for (var i = 0; i < symbol.length; i++) { + var ch = symbol.charCodeAt(i); + if (ch >= 48 && ch <= 57) { + break; + } + shortName += symbol[i].toUpperCase(); + } + return shortName +} + // Via: http://mt.sohu.com/20160429/n446860150.shtml $.IsTrading = function(symbol) { var now = new Date(); @@ -409,15 +489,8 @@ $.IsTrading = function(symbol) { if (day === 0 || (day === 6 && (hour > 2 || hour == 2 && minute > 30))) { return false; } - symbol = symbol.replace('SPD ', '').replace('SP ', ''); - var p, i, shortName = ""; - for (i = 0; i < symbol.length; i++) { - var ch = symbol.charCodeAt(i); - if (ch >= 48 && ch <= 57) { - break; - } - shortName += symbol[i].toUpperCase(); - } + var shortName = ins2product(symbol); + var p = null; var period = [ [9, 0, 10, 15], @@ -629,7 +702,7 @@ $.NewTaskQueue = function(onTaskFinish) { remain = parseInt(task.amount - task.dealAmount); if (remain <= 0 || task.retry >= task.maxRetry) { ret = { - price: (pos.Cost - task.preCost) / (pos.Amount - task.preAmount), + price: task.dealAmount == 0 ? 0 : ((pos.Cost - task.preCost) / (pos.Amount - task.preAmount)), amount: (pos.Amount - task.preAmount), position: pos }; @@ -702,18 +775,36 @@ $.NewTaskQueue = function(onTaskFinish) { self.poll = function() { var processed = 0 - _.each(self.tasks, function(task) { - if (!task.finished) { - processed++ - self.pollTask(task) + if (self.tasks.length > 0) { + _.each(self.tasks, function(task) { + if (!task.finished) { + processed++ + self.pollTask(task) + } + }) + if (processed == 0) { + self.tasks = [] } - }) - if (processed == 0) { - self.tasks = [] + } else { + // wait for master market update + exchange.IO("wait") } return processed } + self.hasTask = function(symbol) { + if (typeof(symbol) !== 'string') { + return self.tasks.length > 0 + } + + for (var i = 0; i < self.tasks.length; i++) { + if (self.tasks[i].symbol == symbol && !self.tasks[i].finished) { + return true + } + } + return false + } + self.size = function() { return self.tasks.length } @@ -723,7 +814,266 @@ $.NewTaskQueue = function(onTaskFinish) { $.AccountToTable = AccountToTable; +// 返回上穿的周期数. 正数为上穿周数, 负数表示下穿的周数, 0指当前价格一样 +$.Cross = function(arr1, arr2) { + if (arr1.length !== arr2.length) { + throw "array length not equal"; + } + var n = 0; + for (var i = arr1.length-1; i >= 0; i--) { + if (typeof(arr1[i]) !== 'number' || typeof(arr2[i]) !== 'number') { + break; + } + if (arr1[i] < arr2[i]) { + if (n > 0) { + break; + } + n--; + } else if (arr1[i] > arr2[i]) { + if (n < 0) { + break; + } + n++; + } else { + break; + } + } + return n; +}; + +/* +onTick(r, mp, symbol): + r为K线, mp为当前品种持仓数量, 正数指多仓, 负数指空仓, 0则不持仓, symbol指品种名称 + 返回值如为n: + n = 0 : 指全部平仓(不管当前持多持空) + n > 0 : 如果当前持多仓,则加n个多仓, 如果当前为空仓则平n个空仓,如果n大于当前持仓, 则反手开多仓 + n < 0 : 如果当前持空仓,则加n个空仓, 如果当前为多仓则平n个多仓,如果-n大于当前持仓, 则反手开空仓 + 无返回值表示什么也不做 +*/ +$.CTA = function(contractType, onTick, interval) { + SetErrorFilter("login") + if (typeof(interval) !== 'number') { + interval = 500 + } + exchange.IO("mode", 0) + var lastUpdate = 0 + var e = exchange + var symbols = contractType.split(','); + var holds = {} + var tblAccount = {}; + var findChartSymbol = function(ct) { + var product = ins2product(ct) + for (var i = 0; i < symbols.length; i++) { + var tmp = symbols[i].split('/') + if (ins2product(tmp[tmp.length-1]) == product) { + return tmp[0] + } + } + return null + } + var refreshHold = function() { + while (!e.IO("status")) { + Sleep(1000) + } + + _.each(symbols, function(ins) { + var tmp = ins.split('/') + if (tmp.length == 2) { + holds[tmp[0]] = {price:0, value:0, amount:0, profit: 0, symbol: tmp[1]} + } else { + holds[ins] = {price:0, value:0, amount:0, profit: 0, symbol: ins} + } + }); + var positions = _C(e.GetPosition); + _.each(positions, function(pos) { + var mapCT = findChartSymbol(pos.ContractType) + if (!mapCT) { + return + } + var hold = holds[mapCT] + if (typeof(hold) == 'undefined') { + return + } + if (pos.Type == PD_LONG || pos.Type == PD_LONG_YD) { + if (hold.amount < 0) { + throw "不能同时持有多仓空仓" + } + hold.amount += pos.Amount + } else { + if (hold.amount > 0) { + throw "不能同时持有多仓空仓" + } + hold.amount -= pos.Amount + } + hold.value += pos.Price * pos.Amount + hold.profit += pos.Profit + if (hold.amount != 0) { + hold.price = _N(hold.value / Math.abs(hold.amount)) + } + }) + var account = _C(exchange.GetAccount) + if (CTAShowPosition) { + var tblPosition = { + type: 'table', + title: '持仓状态', + cols: ['品种', '方向', '均价', '数量', '浮动盈亏'], + rows: [] + }; + _.each(positions, function(pos) { + tblPosition.rows.push([pos.ContractType, ((pos.Type == PD_LONG || pos.Type == PD_LONG_YD) ? '多#0000ff' : '空#ff0000'), pos.Price, pos.Amount, pos.Profit]) + }); + tblAccount = $.AccountToTable(exchange.GetRawJSON(), "资金信息") + LogStatus('`' + JSON.stringify([tblPosition, tblAccount]) + '`\n', '更新于: ' + _D()) + } + lastUpdate = new Date().getTime() + return account + } + + var account = refreshHold() + var q = $.NewTaskQueue(function(task, ret) { + Log("任务结束", task.desc) + account = refreshHold() + }) + var mainCache = [] + while (true) { + var ts = new Date().getTime() + _.each(symbols, function(ins) { + var ctChart = ins + var ctTrade = ins + var tmp = ins.split('/') + if (tmp.length == 2) { + ctChart = tmp[0] + ctTrade = tmp[1] + } + + if (!e.IO("status") || !$.IsTrading(ctChart) || !$.IsTrading(ctTrade) || q.hasTask(ctTrade)) { + return + } + if (typeof(mainCache[ctTrade]) !== 'undefined' && (q.hasTask(mainCache[ctTrade][0]) || q.hasTask(mainCache[ctTrade][0]))) { + // 正在移仓 + return + } + + // 先获取行情 + var c = e.SetContractType(ctChart) + if (!c) { + return + } + var r = e.GetRecords() + if (!r || r.length == 0) { + return + } + + // 切换到需要交易的合约上来 + var insDetail = e.SetContractType(ctTrade) + if (!insDetail) { + return + } + var tradeSymbol = insDetail.InstrumentID + + // 处理主力合约切换, 指数合约在交易时也默认映射到主力合约上 + if (ctTrade.indexOf('888') !== -1 || ctTrade.indexOf('000') !== -1) { + var preMain = '' + var isSwitch = false + if (typeof(mainCache[ctTrade]) === 'undefined') { + if (!IsVirtual()) { + Log(ctTrade, "当前主力合约为:", tradeSymbol) + } + } else if (mainCache[ctTrade][0] != tradeSymbol) { + preMain = mainCache[ctTrade][0] + // 开始切换 + var positions = e.GetPosition() + if (!positions) { + return + } + Log(ctTrade, "主力合约切换为:", tradeSymbol, "之前为:", preMain, "#ff0000") + _.each(positions, function(p) { + if (p.contractType == preMain) { + var isLong = p.Type == PD_LONG || p.Type == PD_LONG_YD + q.pushTask(e, p.contractType, (isLong ? "closebuy" : "closesell"), p.Amount, function(task, ret) { + Log("切换合约平仓成功", task.desc, ret) + }) + q.pushTask(e, tradeSymbol, (isLong ? "buy" : "sell"), p.Amount, function(task, ret) { + Log("切换合约开仓成功", task.desc, ret) + }) + isSwitch = true + } + }) + } + mainCache[ctTrade] = [tradeSymbol, preMain] + if (isSwitch) { + // Wait switch compeleted + Log("开始移仓", preMain, "移到", tradeSymbol) + return + } + } + + var hold = holds[ctChart]; + var n = onTick({records: r, symbol: tradeSymbol, account: account, position: hold, positions: holds}) + var callBack = null + if (typeof(n) == 'object' && typeof(n.length) == 'number' && n.length > 1) { + if (typeof(n[1]) == 'function') { + callBack = n[1] + } + n = n[0] + } + if (typeof(n) !== 'number') { + return + } + var ret = null + if (n > 0) { + if (hold.amount < 0) { + q.pushTask(e, tradeSymbol, 'closesell', Math.min(-hold.amount, n), callBack) + n += hold.amount + } + if (n > 0) { + q.pushTask(e, tradeSymbol, 'buy', n, callBack) + } + } else if (n < 0) { + if (hold.amount > 0) { + q.pushTask(e, tradeSymbol, 'closebuy', Math.min(hold.amount, -n), callBack) + n += hold.amount + } + if (n < 0) { + q.pushTask(e, tradeSymbol, 'sell', -n, callBack) + } + } else if (n == 0 && hold.amount != 0) { + q.pushTask(e, tradeSymbol, (hold.amount > 0 ? 'closebuy' : 'closesell'), Math.abs(hold.amount), callBack) + } + }) + q.poll() + + var now = new Date().getTime() + if ((now - lastUpdate) > (SyncInterval*1000)) { + account = refreshHold() + } + var delay = interval - (now - ts) + if (delay > 0) { + Sleep(delay) + } + } +} + function main() { + // CTA策略框架例子 MA000/rb888 指K线信息看MA000, 下单映射到MA888主力连续上 + $.CTA("MA000/MA888", function(st) { + if (st.records.length < 20) { + return + } + var emaSlow = TA.EMA(st.records, 20) + var emaFast = TA.EMA(st.records, 5) + var cross = $.Cross(emaFast, emaSlow); + LogStatus('可用保证金:', st.account.Balance) + if (st.position.amount <= 0 && cross > 2) { + Log("金叉周期", cross, "当前持仓", st.position); + return st.position.amount < 0 ? 2 : 1 + } else if (st.position.amount >= 0 && cross < -2) { + Log("死叉周期", cross, "当前持仓", st.position); + return st.position.amount > 0 ? -2 : -1 + } + }); + + /* var p = $.NewPositionManager(); p.OpenShort("MA701", 1); p.OpenShort("MA705", 1); @@ -749,4 +1099,5 @@ function main() { q.poll() Sleep(1000) } + */ } diff --git "a/\345\233\275\345\244\226\347\237\245\345\220\215\347\255\226\347\225\245R-Breaker (\345\244\215\345\210\266).js" "b/\345\233\275\345\244\226\347\237\245\345\220\215\347\255\226\347\225\245R-Breaker (\345\244\215\345\210\266).js" deleted file mode 100644 index 7079b1e4..00000000 --- "a/\345\233\275\345\244\226\347\237\245\345\220\215\347\255\226\347\225\245R-Breaker (\345\244\215\345\210\266).js" +++ /dev/null @@ -1,106 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/30512 -策略名称: 国外知名策略R-Breaker (复制) -策略作者: dillonchen -策略描述: - -根据国外知名策略R-Breaker改写,当天收盘时不平仓。默认K线周期选择1天效果最佳。 - - -参数 默认值 描述 -------- ----- ---------- -NPeriod true 计算周期 -f1 0.47 中轨上下顶部区间系数 -f2 0.07 中轨上下区间系数 -f3 0.25 上下轨系数 -Gain false 上次或初始收益 -*/ - -function onTick() { - var records = _C(exchange.GetRecords); - var ticker = _C(exchange.GetTicker); - var account = _C(exchange.GetAccount); - - var H = TA.Highest(records, NPeriod, 'High'); - var C = TA.Lowest(records, 1, 'Close'); - var L = TA.Lowest(records, NPeriod, 'Low'); - - - var ssetup = H + f1 * (C - L); - var senter = ((1 + f2) / 2) * (H + C) - f2 * L; - var benter = ((1 + f2) / 2) * (L + C) - f2 * H; - var bsetup = L - f1 * (H - C); - var bbreak = ssetup + f3 * (ssetup - bsetup); - var sbreak = bsetup - f3 * (ssetup - bsetup); - - - LogStatus('账户信息:', account, '\n最新价: ', ticker.Last, '状态:', state, '\n上轨: ', bbreak, '中轨顶', ssetup, '中轨上:', senter, '中轨下:', benter, '中轨底', bsetup, '下轨: ', sbreak); - - income = (account.Balance + account.FrozenBalance) + (account.Stocks + account.FrozenStocks) * ticker.Last - initBalance - initStocks * initticker + Gain; - - if (ticker.Last > ssetup) { - state = 1; - } else if (ticker.Last >= bsetup && ticker.Last <= ssetup) { - state = 0; - } else if (ticker.Last < bsetup && account.Stocks < 0.01) { - state = -1; - } - - //做多 - if (ticker.Last > bbreak && account.Balance / ticker.Last >= 0.01) { - Log('开始做多'); - $.Buy(account.Balance / ticker.Last); - Log('保持多仓'); -// LogProfit(income); - state = 1; - } - - //做空 - else if (state === 1 && ticker.Last < senter && account.Stocks >= 0.01) { - Log('开始做空'); - $.Sell(account.Stocks); - Log('保持空仓'); - LogProfit(income); - } - - - //做多 - if (state === -1 && ticker.Last > benter && account.Balance / ticker.Last >= 0.01) { - Log('开始做多'); - $.Buy(account.Balance / ticker.Last); - Log('保持多仓'); -// LogProfit(income); - } - - //做空 - else if (ticker.Last < sbreak && account.Stocks >= 0.01) { - Log('开始做空'); - $.Sell(account.Stocks); - Log('保持空仓'); - LogProfit(income); - state = -1; - } - -} - -function main() { - var account = _C(exchange.GetAccount); - var ticker = _C(exchange.GetTicker); - initticker = ticker.Last; - initBalance = account.Balance; - initStocks = account.Stocks; - state = 0; - biaoji = 0; - - if (initStocks < 0.01 || (initBalance / initticker < 0.01)) { - Log('账户必须有钱又有币,请重新设置!#ff0000'); - onexit(); - } - LogProfit(Gain); - Log('上次或初始收益'); - - while (true) { - onTick(); - Sleep(1000); - } -} diff --git "a/\345\235\207\347\272\277MA\346\214\207\346\240\207\344\275\277\347\224\250\350\214\203\344\276\213.js" "b/\345\235\207\347\272\277MA\346\214\207\346\240\207\344\275\277\347\224\250\350\214\203\344\276\213.js" new file mode 100644 index 00000000..f1a0af7a --- /dev/null +++ "b/\345\235\207\347\272\277MA\346\214\207\346\240\207\344\275\277\347\224\250\350\214\203\344\276\213.js" @@ -0,0 +1,28 @@ +/* +策略出处: https://www.botvs.com/strategy/46484 +策略名称: 均线MA指标使用范例 +策略作者: yilidalei +策略描述: + + + +*/ + +function main(){ + while(true){ + var records = exchange.GetRecords(PERIOD_D1) + if(!records || records.length < 60){ + continue + } + + $.PlotRecords(records, 'K线 - MA60') + + var MA60 = TA.MA(records, 60) + + $.PlotLine('MA60', MA60[MA60.length - 1], records[records.length - 1].Time) + + LogStatus(_D(), '\n', "当前K线bar", records[records.length - 1], '\n', "当前MA60指标:", MA60[MA60.length - 1]) + + Sleep(500) + } +} diff --git "a/\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.js" "b/\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.js" new file mode 100644 index 00000000..6c7e750e --- /dev/null +++ "b/\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.js" @@ -0,0 +1,120 @@ +/* +策略出处: https://www.botvs.com/strategy/47144 +策略名称: 多均线策略 +策略作者: 小小梦 +策略描述: + + + + +参数 默认值 描述 +---- ----- ----- +ma60 60 60日均线 +ma10 10 10日均线 +ma5 5 5日均线 +*/ + +// 以下是测试代码 +/*- 状态 在使用 模板时需要在 主策略内声明 +var TASK_IDLE = 0; +var TASK_OPEN_LONG = 1; +var TASK_OPEN_SHORT = 2; +var TASK_ADD = 3; +var TASK_ST = 4; +var TASK_COVER = 5; +*/ + +// 全局变量 +var currency0 = exchanges[0].GetCurrency(); +var ChartObj = null; +var TASK_IDLE = 0; +var TASK_OPEN_LONG = 1; +var TASK_OPEN_SHORT = 2; +var TASK_ADD = 3; +var TASK_ST = 4; +var TASK_COVER = 5; +var IDLE = 11; +var LONG = 22; +var SHORT = 33; +var perRecordsTime = 0; + +function onTick1() { + // 获取K线数据 + var nowTime = new Date().getTime(); + var records = _C(exchanges[0].GetRecords); + if(records.length < Math.abs(ma60, ma10, ma5)){ + return $.TaskCmd(TASK_IDLE); + } + + var ma60_line = TA.MA(records, ma60); + var ma10_line = TA.MA(records, ma10); + var ma5_line = TA.MA(records, ma5); + + // $.AddData = function(index, dataKey, dataValue) + + // 画图表 + $.PlotRecords(records, currency0); + $.PlotLine('ma' + ma60, ma60_line[ma60_line.length - 1], records[records.length - 1].Time); + $.PlotLine('ma' + ma10, ma10_line[ma10_line.length - 1], records[records.length - 1].Time); + $.PlotLine('ma' + ma5, ma5_line[ma5_line.length - 1], records[records.length - 1].Time); + + if(records[records.length - 1].Time !== perRecordsTime){ + isTradeonThieBar = false; + perRecordsTime = records[records.length - 1].Time; + } + + if($.GetTaskState(exchanges[0].GetName(), exchanges[0].GetLabel()) == IDLE && records[records.length - 2].Close > ma60_line[ma60_line.length - 2] && ma10_line[ma10_line.length - 2] > ma60_line[ma60_line.length - 2] && ma5_line[ma5_line.length - 2] > ma60_line[ma60_line.length - 2] && + ma10_line[ma10_line.length - 3] > ma5_line[ma5_line.length - 3] && ma10_line[ma10_line.length - 2] < ma5_line[ma5_line.length - 2]){ + // 标记 + return $.TaskCmd(TASK_OPEN_LONG, 0.5); + }else if($.GetTaskState(exchanges[0].GetName(), exchanges[0].GetLabel()) == IDLE && records[records.length - 2].Close < ma60_line[ma60_line.length - 2] && ma10_line[ma10_line.length - 2] < ma60_line[ma60_line.length - 2] && ma5_line[ma5_line.length - 2] < ma60_line[ma60_line.length - 2] && + ma10_line[ma10_line.length - 3] < ma5_line[ma5_line.length - 3] && ma10_line[ma10_line.length - 2] > ma5_line[ma5_line.length - 2]){ + // 标记 + isTradeonThieBar = true; + return $.TaskCmd(TASK_OPEN_SHORT, 0.5); + } + + if (($.GetTaskState(exchanges[0].GetName(), exchanges[0].GetLabel()) == LONG && records[records.length - 2].Close < ma5_line[ma5_line.length - 2]) || ($.GetTaskState(exchanges[0].GetName(), exchanges[0].GetLabel()) == SHORT && records[records.length - 2].Close > ma5_line[ma5_line.length - 2])) { + // 标记 + isTradeonThieBar = true; + return $.TaskCmd(TASK_COVER); + } + + return $.TaskCmd(TASK_IDLE); +} + +function main() { + LogReset(1); + ChartObj = Chart(null); + ChartObj.reset(); + ChartObj = $.GetCfg(); + // 处理 指标轴------------------------ + ChartObj.yAxis = [{ + title: {text: 'K线'},//标题 + style: {color: '#4572A7'},//样式 + opposite: false //生成右边Y轴 + }, + { + title:{text: "指标轴"}, + opposite: true, //生成右边Y轴 ceshi + } + ]; + // 初始化指标线 + var records = null; + while(!records || records.length < 60){ + records = _C(exchange.GetRecords); + LogStatus("records.length:", records.length); + Sleep(1000); + } + + $.PlotRecords(records, currency0); + $.PlotLine('ma' + ma60, 0, records[records.length - 1].Time); + $.PlotLine('ma' + ma10, 0, records[records.length - 1].Time); + var chart = $.PlotLine('ma' + ma5, 0, records[records.length - 1].Time); + + chart.update(ChartObj); + chart.reset(); + + $.Relation_Exchange_onTick(exchanges[0], onTick1); + $.Trend(); // 不用传参数。 +} diff --git "a/\345\244\232\345\271\263\345\217\260\345\257\271\345\206\262\347\250\263\345\256\232\345\245\227\345\210\251 V2.1 (\345\244\215\345\210\266).js" "b/\345\244\232\345\271\263\345\217\260\345\257\271\345\206\262\347\250\263\345\256\232\345\245\227\345\210\251 V2.1 (\345\244\215\345\210\266).js" deleted file mode 100644 index 0ac1f3b6..00000000 --- "a/\345\244\232\345\271\263\345\217\260\345\257\271\345\206\262\347\250\263\345\256\232\345\245\227\345\210\251 V2.1 (\345\244\215\345\210\266).js" +++ /dev/null @@ -1,305 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/23718 -策略名称: 多平台对冲稳定套利 V2.1 (复制) -策略作者: zhuzhu -策略描述: - -程序自动换算汇率,手续费,下单参考买一卖一的价,注意这个不是搬砖,是对冲! 不需要人工转钱或者币,一个存钱,一个存币,一个买,一个卖,高级对冲模式. -这种对冲模式不管币的价格是涨还是跌,只赚差价。 -建仓需要一个放钱,一个放币,比如BTC现在价格4000吧,一个交易所放2000元,一个放0.5个币就行了,或者都加倍 -MaxDiff指最低平台差价, SlidePrice指下单时的滑动价, 买单就加上这个价, 卖单就减去这个价, TickIntervalS 指检测周期 -跌停值指的时虚拟币跌到这个价格了就不操作,涨停值指虚拟币高于这个价格也不操作,防止平台恶意给机器人下套. -要求系统版本1.7以上 - - -参数 默认值 描述 --------------- ------- ---------- -Interval 500 出错重试间隔(毫秒) -TickInterval 300 检测频率(毫秒) -MaxDiff 3 最低差价(元) -SlidePrice 0.1 止损滑动价(元) -SlideRatio 2 对冲滑动价系数 -StopPriceL 1000 跌停值(元) -StopPriceH 9000 涨停值(元) -optFeeTimeout 30 手续费更新周期(分) -AmountOnce 0.2 单笔交易数量 -UseMarketOrder false 使用市价单止损 -StopWhenLoss false 亏损时停止 -MaxLoss 50 最大亏损限度(元) -SMSAPI http:// 短信通知接口 -*/ - -var initState; -var isBalance = true; -var feeCache = new Array(); -var feeTimeout = optFeeTimeout * 60000; -var lastProfit = 0; -var lastAvgPrice = 0; -var lastSpread = 0; -var lastOpAmount = 0; -function adjustFloat(v) { - return Math.floor(v*1000)/1000; -} - -function isPriceNormal(v) { - return (v >= StopPriceL) && (v <= StopPriceH); -} - -function stripTicker(t) { - return 'Buy: ' + adjustFloat(t.Buy) + ' Sell: ' + adjustFloat(t.Sell); -} - -function updateStatePrice(state) { - var now = (new Date()).getTime(); - for (var i = 0; i < state.details.length; i++) { - var ticker = null; - var key = state.details[i].exchange.GetName() + state.details[i].exchange.GetCurrency(); - var fee = null; - while (!(ticker = state.details[i].exchange.GetTicker())) { - Sleep(Interval); - } - - if (key in feeCache) { - var v = feeCache[key]; - if ((now - v.time) > feeTimeout) { - delete feeCache[key]; - } else { - fee = v.fee; - } - } - if (!fee) { - while (!(fee = state.details[i].exchange.GetFee())) { - Sleep(Interval); - } - feeCache[key] = {fee: fee, time: now}; - } - // Buy-=fee Sell+=fee - state.details[i].ticker = {Buy: ticker.Buy * (1-(fee.Sell/100)), Sell: ticker.Sell * (1+(fee.Buy/100))}; - state.details[i].realTicker = ticker; - state.details[i].fee = fee; - } -} - -function getProfit(stateInit, stateNow, coinPrice) { - var netNow = stateNow.allBalance + (stateNow.allStocks * coinPrice); - var netInit = stateInit.allBalance + (stateInit.allStocks * coinPrice); - return adjustFloat(netNow - netInit); -} - -function getExchangesState() { - var allStocks = 0; - var allBalance = 0; - var minStock = 0; - var details = []; - for (var i = 0; i < exchanges.length; i++) { - var account = null; - while (!(account = exchanges[i].GetAccount())) { - Sleep(Interval); - } - allStocks += account.Stocks + account.FrozenStocks; - allBalance += account.Balance + account.FrozenBalance; - minStock = Math.max(minStock, exchanges[i].GetMinStock()); - details.push({exchange: exchanges[i], account: account}); - } - return {allStocks: adjustFloat(allStocks), allBalance: adjustFloat(allBalance), minStock: minStock, details: details}; -} - -function cancelAllOrders() { - for (var i = 0; i < exchanges.length; i++) { - while (true) { - var orders = null; - while (!(orders = exchanges[i].GetOrders())) { - Sleep(Interval); - } - - if (orders.length == 0) { - break; - } - - for (var j = 0; j < orders.length; j++) { - exchanges[i].CancelOrder(orders[j].Id, orders[j]); - } - } - } -} - -function balanceAccounts() { - // already balance - if (isBalance) { - return; - } - - cancelAllOrders(); - - var state = getExchangesState(); - var diff = state.allStocks - initState.allStocks; - var adjustDiff = adjustFloat(Math.abs(diff)); - if (adjustDiff < state.minStock) { - isBalance = true; - } else { - Log('初始币总数量:', initState.allStocks, '现在币总数量: ', state.allStocks, '差额:', adjustDiff); - // other ways, diff is 0.012, bug A only has 0.006 B only has 0.006, all less then minstock - // we try to statistical orders count to recognition this situation - updateStatePrice(state); - var details = state.details; - var ordersCount = 0; - if (diff > 0) { - var attr = 'Sell'; - if (UseMarketOrder) { - attr = 'Buy'; - } - // Sell adjustDiff, sort by price high to low - details.sort(function(a, b) {return b.ticker[attr] - a.ticker[attr];}); - for (var i = 0; i < details.length && adjustDiff >= state.minStock; i++) { - if (isPriceNormal(details[i].ticker[attr]) && (details[i].account.Stocks >= state.minStock)) { - var orderAmount = adjustFloat(Math.min(AmountOnce, adjustDiff, details[i].account.Stocks)); - var orderPrice = details[i].realTicker[attr] - SlidePrice; - if ((orderPrice * orderAmount) < details[i].exchange.GetMinPrice()) { - continue; - } - ordersCount++; - if (details[i].exchange.Sell(orderPrice, orderAmount, stripTicker(details[i].ticker))) { - adjustDiff = adjustFloat(adjustDiff - orderAmount); - } - // only operate one platform - break; - } - } - } else { - var attr = 'Buy'; - if (UseMarketOrder) { - attr = 'Sell'; - } - // Buy adjustDiff, sort by sell-price low to high - details.sort(function(a, b) {return a.ticker[attr] - b.ticker[attr];}); - for (var i = 0; i < details.length && adjustDiff >= state.minStock; i++) { - if (isPriceNormal(details[i].ticker[attr])) { - var canRealBuy = adjustFloat(details[i].account.Balance / (details[i].ticker[attr] + SlidePrice)); - var needRealBuy = Math.min(AmountOnce, adjustDiff, canRealBuy); - var orderAmount = adjustFloat(needRealBuy * (1+(details[i].fee.Buy/100))); - var orderPrice = details[i].realTicker[attr] + SlidePrice; - if ((orderAmount < details[i].exchange.GetMinStock()) || - ((orderPrice * orderAmount) < details[i].exchange.GetMinPrice())) { - continue; - } - ordersCount++; - if (details[i].exchange.Buy(orderPrice, orderAmount, stripTicker(details[i].ticker))) { - adjustDiff = adjustFloat(adjustDiff - needRealBuy); - } - // only operate one platform - break; - } - } - } - isBalance = (ordersCount == 0); - } - - if (isBalance) { - var currentProfit = getProfit(initState, state, lastAvgPrice); - LogProfit(currentProfit, "Spread: ", adjustFloat((currentProfit - lastProfit) / lastOpAmount), "Balance: ", adjustFloat(state.allBalance), "Stocks: ", adjustFloat(state.allStocks)); - - if (StopWhenLoss && currentProfit < 0 && Math.abs(currentProfit) > MaxLoss) { - Log('交易亏损超过最大限度, 程序取消所有订单后退出.'); - cancelAllOrders(); - if (SMSAPI.length > 10 && SMSAPI.indexOf('http') == 0) { - HttpQuery(SMSAPI); - Log('已经短信通知'); - } - throw '已停止'; - } - lastProfit = currentProfit; - } -} - -function onTick() { - if (!isBalance) { - balanceAccounts(); - return; - } - - var state = getExchangesState(); - // We also need details of price - updateStatePrice(state); - - var details = state.details; - var maxPair = null; - var minPair = null; - for (var i = 0; i < details.length; i++) { - var sellOrderPrice = details[i].account.Stocks * (details[i].realTicker.Buy - SlidePrice); - if (((!maxPair) || (details[i].ticker.Buy > maxPair.ticker.Buy)) && (details[i].account.Stocks >= state.minStock) && - (sellOrderPrice > details[i].exchange.GetMinPrice())) { - details[i].canSell = details[i].account.Stocks; - maxPair = details[i]; - } - - var canBuy = adjustFloat(details[i].account.Balance / (details[i].realTicker.Sell + SlidePrice)); - var buyOrderPrice = canBuy * (details[i].realTicker.Sell + SlidePrice); - if (((!minPair) || (details[i].ticker.Sell < minPair.ticker.Sell)) && (canBuy >= state.minStock) && - (buyOrderPrice > details[i].exchange.GetMinPrice())) { - details[i].canBuy = canBuy; - // how much coins we real got with fee - details[i].realBuy = adjustFloat(details[i].account.Balance / (details[i].ticker.Sell + SlidePrice)); - minPair = details[i]; - } - } - - if ((!maxPair) || (!minPair) || ((maxPair.ticker.Buy - minPair.ticker.Sell) < MaxDiff) || - !isPriceNormal(maxPair.ticker.Buy) || !isPriceNormal(minPair.ticker.Sell)) { - return; - } - - // filter invalid price - if (minPair.realTicker.Sell <= minPair.realTicker.Buy || maxPair.realTicker.Sell <= maxPair.realTicker.Buy) { - return; - } - - // what a fuck... - if (maxPair.exchange.GetName() == minPair.exchange.GetName()) { - return; - } - - lastAvgPrice = adjustFloat((minPair.realTicker.Buy + maxPair.realTicker.Buy) / 2); - lastSpread = adjustFloat((maxPair.realTicker.Sell - minPair.realTicker.Buy) / 2); - - // compute amount - var amount = Math.min(AmountOnce, maxPair.canSell, minPair.realBuy); - lastOpAmount = amount; - var hedgePrice = adjustFloat((maxPair.realTicker.Buy - minPair.realTicker.Sell) / Math.max(SlideRatio, 2)) - if (minPair.exchange.Buy(minPair.realTicker.Sell + hedgePrice, amount * (1+(minPair.fee.Buy/100)), stripTicker(minPair.realTicker))) { - maxPair.exchange.Sell(maxPair.realTicker.Buy - hedgePrice, amount, stripTicker(maxPair.realTicker)); - } - - isBalance = false; -} - -function main() { - if (exchanges.length < 2) { - throw "交易所数量最少得两个才能完成对冲"; - } - - TickInterval = Math.max(TickInterval, 50); - Interval = Math.max(Interval, 50); - - cancelAllOrders(); - - initState = getExchangesState(); - if (initState.allStocks == 0) { - throw "所有交易所货币数量总和为空, 必须先在任一交易所建仓才可以完成对冲"; - } - if (initState.allBalance == 0) { - throw "所有交易所CNY数量总和为空, 无法继续对冲"; - } - - for (var i = 0; i < initState.details.length; i++) { - var e = initState.details[i]; - Log(e.exchange.GetName(), e.exchange.GetCurrency(), e.account); - } - - Log("ALL: Balance: ", initState.allBalance, "Stocks: ", initState.allStocks, "Ver:", Version()); - - - while (true) { - onTick(); - Sleep(parseInt(TickInterval)); - } -} diff --git "a/\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.js" "b/\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.js" new file mode 100644 index 00000000..b22c7130 --- /dev/null +++ "b/\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.js" @@ -0,0 +1,106 @@ +/* +策略出处: https://www.botvs.com/strategy/58179 +策略名称: 如何找出一定Bar数量的 K线前期高点、低点 及 Demo 程序 +策略作者: 小小梦 +策略描述: + + + +*/ + +function FindLastHighestPoint(Records, NumOfBars){ + var RecordsLen = Records.length + if(RecordsLen < 2){ + return false + } + if(typeof(NumOfBars) == "undefined"){ + NumOfBars = 0 + } + var highPrice = TA.Highest(Records, NumOfBars, "High") + // find the bar + var bar = null + for(var i = 0; i < RecordsLen; i++){ + if(Records[i].High == highPrice){ + bar = {} + bar.record = Records[i] + bar.index = i + bar.range = NumOfBars + break + } + } + + // compare current bar + if(bar && Records[RecordsLen - 1].High >= bar.record.High){ + bar.record = Records[RecordsLen - 1] + bar.index = RecordsLen - 1 + bar.range = NumOfBars + } + + if(!bar || !Records[bar.index - 1]){ + return false + } + + return bar +} + +function FindLastLowestPoint(Records, NumOfBars){ + var RecordsLen = Records.length + if(RecordsLen < 2){ + return false + } + if(typeof(NumOfBars) == "undefined"){ + NumOfBars = 0 + } + var lowPrice = TA.Lowest(Records, NumOfBars, "Low") + // find the bar + var bar = null + for(var i = 0; i < RecordsLen; i++){ + if(Records[i].Low == lowPrice){ + bar = {} + bar.record = Records[i] + bar.index = i + bar.range = NumOfBars + break + } + } + + // compare current bar + if(bar && Records[RecordsLen - 1].Low <= bar.record.Low){ + bar.record = Records[RecordsLen - 1] + bar.index = RecordsLen - 1 + bar.range = NumOfBars + } + + if(!bar || !Records[bar.index - 1]){ + return false + } + + return bar +} + +function main(){ + LogReset(1) + var chart_obj = Chart({}) + chart_obj.reset() + while(true){ + var records = exchange.GetRecords() + if(!records){ + continue + } + var bar = FindLastHighestPoint(records) + var bar2 = FindLastLowestPoint(records) + $.PlotRecords(records) + if(bar){ + $.PlotHLine(bar.record.High, "高点", "red") + }else{ + Log("K线数据不足,最高点为初始K线bar!") + } + if(bar2){ + $.PlotHLine(bar2.record.Low, "低点", "green") + }else{ + Log("K线数据不足,最低点为初始K线bar!") + } + LogStatus(_D(), '\n', bar, '\n', bar2) + Sleep(1000) + } +} diff --git "a/\345\267\256\344\273\267\347\233\221\346\216\247.js" "b/\345\267\256\344\273\267\347\233\221\346\216\247.js" index 6ff472ce..c1ec183a 100644 --- "a/\345\267\256\344\273\267\347\233\221\346\216\247.js" +++ "b/\345\267\256\344\273\267\347\233\221\346\216\247.js" @@ -132,7 +132,7 @@ function main() { if (EnableCR) { for (var i = 0; i < exchanges.length; i++) { var rate = exchanges[i].GetRate(); - if (rate != 1) { + if (exchanges[i].GetBaseCurrency() != 'CNY') { exchanges[i].SetRate(USDCNY); Log("更改", exchanges[i].GetName(), "汇率", rate, "为", USDCNY); } diff --git "a/\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.py" "b/\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.py" new file mode 100644 index 00000000..25686e0d --- /dev/null +++ "b/\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.py" @@ -0,0 +1,630 @@ +''' +策略出处: https://www.botvs.com/strategy/52801 +策略名称: 布林均线突破_vnpy_botvs实现版 +策略作者: ipqhjjybj +策略描述: + +这是将 botvs的接口用 Vnpy 的写法 方式简单封装掉,便于后期的调用! + 这本来是期货的 策略, 直接改参数套在 比特币上。 + 期货上要切换到分钟级别, 比特币期货则用小时级别的 + 实盘时需要调整参数。 + 如有策略改进,请多多与本人交流 250657661 + + bar.minute.hour 代表是小时级别 + bar.minute.minute 代表是分钟级别 + + +参数 默认值 描述 +--------------- ----- -------------- +ContractTypeIdx 0 期货类型: 当周|次周|季度 +MarginLevelIdx 0 杠杠大小: 10|20 +LoopInterval true 轮询间隔(秒) +minute_use 12 分钟级别 +''' + +''' +策略名称: BollingBreaker趋势策略 +策略作者: ipqhjjybj +策略描述: + 这是将 botvs的接口用 Vnpy 的写法 方式简单封装掉,便于后期的调用! + 这本来是期货的 策略, 直接改参数套在 比特币上。 + 期货上要切换到分钟级别, 比特币期货则用小时级别的 + 实盘时需要调整参数。 + 如有策略改进,请多多与本人交流 250657661 + + bar.minute.hour 代表是小时级别 + bar.minute.minute 代表是分钟级别 + + +------------------------------------------------------------------ + + 当前只支持 比特币OKCOIN 期货, 如果要弄到 CTP期货,需要微调 + +趋势跟踪策略 +''' +import time +from datetime import datetime +import numpy as np +import talib + +EMPTY_STRING = "" +EMPTY_INT = 0 +EMPTY_FLOAT = 0.0 +EMPTY_UNICODE = u'' + +DIRECTION_LONG = u'long' +DIRECTION_SHORT = u'short' + +OFFSET_OPEN = u'kaicang' +OFFSET_CLOSE = u'pingcang' + +# CTA引擎中涉及到的交易方向类型 +CTAORDER_BUY = "buy" +CTAORDER_SELL = "closebuy" +CTAORDER_SHORT = "sell" +CTAORDER_COVER = "closesell" + + +# 本地停止单状态 +STOPORDER_WAITING = u'waiting' +STOPORDER_CANCELLED = u'canceled' +STOPORDER_TRIGGERED = u'touched' + +# 本地停止单前缀 +STOPORDERPREFIX = 'CtaStopOrder' + + + +######################################################################## +class VtBarData: + """K线数据""" + + #---------------------------------------------------------------------- + def __init__(self): + """Constructor""" + + self.vtSymbol = EMPTY_STRING # vt系统代码 + self.symbol = EMPTY_STRING # 代码 + self.exchange = EMPTY_STRING # 交易所 + + self.open = EMPTY_FLOAT # OHLC + self.high = EMPTY_FLOAT + self.low = EMPTY_FLOAT + self.close = EMPTY_FLOAT + + self.date = EMPTY_STRING # bar开始的时间,日期 + self.time = EMPTY_STRING # 时间 + self.datetime = None # python的datetime时间对象 + + self.volume = EMPTY_INT # 成交量 + self.openInterest = EMPTY_INT # 持仓量 + +######################################################################## +class VtTickData: + """Tick行情数据类""" + + #---------------------------------------------------------------------- + def __init__(self): + """Constructor""" + + # 代码相关 + self.exchange = EMPTY_STRING # 交易所代码 + self.vtSymbol = EMPTY_STRING # 合约在vt系统中的唯一代码,通常是 合约代码.交易所代码 + + # 成交数据 + self.lastPrice = EMPTY_FLOAT # 最新成交价 + self.lastVolume = EMPTY_INT # 最新成交量 + self.volume = EMPTY_INT # 今天总成交量 + self.openInterest = EMPTY_INT # 持仓量 + self.time = EMPTY_STRING # 时间 11:20:56.5 + self.date = EMPTY_STRING # 日期 20151009 + self.datetime = None # python的datetime时间对象 + + # 常规行情 + self.openPrice = EMPTY_FLOAT # 今日开盘价 + self.highPrice = EMPTY_FLOAT # 今日最高价 + self.lowPrice = EMPTY_FLOAT # 今日最低价 + self.preClosePrice = EMPTY_FLOAT + + self.upperLimit = EMPTY_FLOAT # 涨停价 + self.lowerLimit = EMPTY_FLOAT # 跌停价 + + # 五档行情 + self.bidPrice1 = EMPTY_FLOAT + self.bidPrice2 = EMPTY_FLOAT + self.bidPrice3 = EMPTY_FLOAT + self.bidPrice4 = EMPTY_FLOAT + self.bidPrice5 = EMPTY_FLOAT + + self.askPrice1 = EMPTY_FLOAT + self.askPrice2 = EMPTY_FLOAT + self.askPrice3 = EMPTY_FLOAT + self.askPrice4 = EMPTY_FLOAT + self.askPrice5 = EMPTY_FLOAT + + self.bidVolume1 = EMPTY_INT + self.bidVolume2 = EMPTY_INT + self.bidVolume3 = EMPTY_INT + self.bidVolume4 = EMPTY_INT + self.bidVolume5 = EMPTY_INT + + self.askVolume1 = EMPTY_INT + self.askVolume2 = EMPTY_INT + self.askVolume3 = EMPTY_INT + self.askVolume4 = EMPTY_INT + self.askVolume5 = EMPTY_INT + + +######################################################################## +class StopOrder(object): + """本地停止单""" + + #---------------------------------------------------------------------- + def __init__(self): + """Constructor""" + self.vtSymbol = EMPTY_STRING + self.orderType = EMPTY_UNICODE + self.direction = EMPTY_UNICODE + self.offset = EMPTY_UNICODE + self.price = EMPTY_FLOAT + self.volume = EMPTY_INT + + self.strategy = None # 下停止单的策略对象 + self.stopOrderID = EMPTY_STRING # 停止单的本地编号 + self.status = EMPTY_STRING # 停止单状态 + + +class BollingerBreakerStrategy: + #品种属性 + vtSymbol = EMPTY_STRING # 是什么品种 + + # 策略参数 + minute_use = 6 # 多少分钟级别的K线 + + bar = None # 1分钟K线对象 + fiveBar = None # 1分钟K线对象 + + # 策略参数 + bollLength = 20 # 通道窗口数 + topDev = 1.3 # 开仓偏差 + trailingPrcnt = 2 # 移动止损百分比 + use_range = 10 # use_range天内有突破最高价 + N = 10 # 多少天突破 + + bufferSize = 40 # 需要缓存的数据的大小 + bufferCount = 0 # 目前已经缓存了的数据的计数 + + + realBuyCond = 0 # 买卖的状态 + realSellCond = 0 # 买卖的状态 + + bollMid = 0 # 布林带中轨 + bollStd = 0 # 布林带宽度 + entryUp = 0 # 开仓上轨 + + barMinute = EMPTY_STRING # K线当前的分钟 + + fixedSize = 1 + + stopOrderCount = 0 # 记录停止单的数量 + + pos = 0 # 仓位 + + LastBarTime = None # python 上一根Tick + + currency = EMPTY_STRING + + def __init__(self, _exchange , setting ): + self.exchange = _exchange + for key in setting.keys(): + if key == "vtSymbol": + self.vtSymbol = setting[key] + if key == "currency": + self.currency = setting[key] + if key == 'minute_use': + self.minute_use = setting[key] + if key == "bollLength": + self.bollLength = setting[key] + if key == "topDev": + self.topDev = setting[key] + if key == "trailingPrcnt": + self.trailingPrcnt = setting[key] + if key == "use_range": + self.use_range = setting[key] + if key == "N": + self.N = setting[key] + Log(setting) + + self.pos = 0 + self.order_PreUse = {} # vtPreID , pushDealAmount 已经推送过的成交数据 + self.workingStopOrderDict = {} + self.stopOrderDict = {} + self.orderList = [] # 保存委托代码的列表 + self.fixedSize = 1 + ################## + self.bufferSize = 40 + ################# + self.highArray = np.zeros(self.bufferSize) + self.lowArray = np.zeros(self.bufferSize) + self.closeArray = np.zeros(self.bufferSize) + + self.buyValue = np.zeros(self.bufferSize) + + + def onCall(self): + try: + #self.exchange.IO("currency" , self.currency) + need_remove = [] + for orderId in self.orderList: + # 订单状态, 参考常量里的订单状态,以下是此键值的常量。 + # ORDER_STATE_PENDING :未完成 + # ORDER_STATE_CLOSED :已关闭 已完成 + # ORDER_STATE_CANCELED :已取消 + # STOPORDERPREFIX 是否是 系统内部的 停止单 + if orderId != None and type(orderId) != type(1) and STOPORDERPREFIX in orderId: + continue + botvsOrder = self.exchange.GetOrder(orderId) + preAmount = 0.0 + if botvsOrder != None: + if botvsOrder["Status"] in [ORDER_STATE_CLOSED,ORDER_STATE_CANCELED]: + try: + preAmount = self.order_PreUse[orderId] + except Exception,ex: + Log("Error in preAmount",ex) + preAmount = 0.0 + Log("preAmount:" , preAmount) + incAmount = botvsOrder["DealAmount"] - preAmount + if incAmount > 0: + self.order_PreUse[orderId] = botvsOrder["DealAmount"] + botvsOrder["preAmount"] = preAmount + botvsOrder["incAmount"] = incAmount + self.onTrade( botvsOrder ) + + + if botvsOrder["Status"] == ORDER_STATE_CLOSED: + need_remove.append(orderId) + else: + Log("None order!") + + for orderId in need_remove: + Log("remove order:" , orderId) + self.orderList.remove(orderId) + + + # Log("currency",self.currency) + botvsTick = self.exchange.GetTicker() + + + if self.LastBarTime != botvsTick["Time"]: + newTick = VtTickData() + newTick.datetime = datetime.fromtimestamp(botvsTick["Time"] / 1000.0) + newTick.vtSymbol = self.vtSymbol + newTick.lastPrice = float(botvsTick["Last"]) + newTick.lastVolume = float(botvsTick["Volume"]) + newTick.volume = float(botvsTick["Volume"]) + newTick.highPrice = float(botvsTick["High"]) + newTick.lowPrice = float(botvsTick["Low"]) + + newTick.upperLimit = newTick.highPrice * 1.03 + newTick.lowerLimit = newTick.lowPrice * 0.97 + + newTick.exchange = self.exchange.GetName() + + newTick.date = newTick.datetime.strftime("%Y%m%d") + newTick.time = newTick.datetime.strftime("%Y:%m:%d") + + self.onTick(newTick) + + self.processStopOrder(newTick) + except Exception,ex: + Log(ex , "error in onCall , maybe getTicker wrong!") + + #---------------------------------------------------------------------- + def onTrade(self, trade): + # 发出状态更新事件 + #'Type': 0 # 订单类型, 参考常量里的订单类型,以下是此键值的常量。 + # ORDER_TYPE_BUY :买单 + # ORDER_TYPE_SELL :卖单 + try: + Log("trade:",trade) + newPos = 0.0 + if trade["Type"] == ORDER_TYPE_BUY: + newPos += trade["incAmount"] + elif trade["Type"] == ORDER_TYPE_SELL: + newPos -= trade["incAmount"] + else: + Log("What ? trade Type error!") + self.pos += newPos + except Exception,ex: + print ex + #---------------------------------------------------------------------- + def processStopOrder(self, tick): + """收到行情后处理本地停止单(检查是否要立即发出)""" + vtSymbol = tick.vtSymbol + + # 遍历等待中的停止单,检查是否会被触发 + for so in self.workingStopOrderDict.values(): + if so.vtSymbol == vtSymbol: + longTriggered = so.direction==DIRECTION_LONG and tick.lastPrice>=so.price # 多头停止单被触发 + shortTriggered = so.direction==DIRECTION_SHORT and tick.lastPrice<=so.price # 空头停止单被触发 + + if longTriggered or shortTriggered: + # 买入和卖出分别以涨停跌停价发单(模拟市价单) + if so.direction==DIRECTION_LONG: + price = tick.upperLimit + else: + price = tick.lowerLimit + + so.status = STOPORDER_TRIGGERED + orderIDList = self.sendOrder(so.vtSymbol, so.orderType, price, so.volume, False ,so.strategy) + for orderID in orderIDList: + self.orderList.append(orderID) + del self.workingStopOrderDict[so.stopOrderID] + so.strategy.onStopOrder(so) + + def onStopOrder(self, vtStopOrder): + Log("stopOrder Deal ID:", vtStopOrder.stopOrderID , vtStopOrder.status ) + + def sendStopOrder(self, vtSymbol, orderType, price, volume, strategy ): + """发停止单(本地实现)""" + self.stopOrderCount += 1 + stopOrderID = STOPORDERPREFIX + str(self.vtSymbol) + str(self.stopOrderCount) + + so = StopOrder() + so.vtSymbol = vtSymbol + so.orderType = orderType + so.price = price + so.volume = volume + so.strategy = strategy + so.stopOrderID = stopOrderID + so.status = STOPORDER_WAITING + + if orderType == CTAORDER_BUY: + so.direction = DIRECTION_LONG + so.offset = OFFSET_OPEN + elif orderType == CTAORDER_SELL: + so.direction = DIRECTION_SHORT + so.offset = OFFSET_CLOSE + elif orderType == CTAORDER_SHORT: + so.direction = DIRECTION_SHORT + so.offset = OFFSET_OPEN + elif orderType == CTAORDER_COVER: + so.direction = DIRECTION_LONG + so.offset = OFFSET_CLOSE + + # 保存stopOrder对象到字典中 + self.stopOrderDict[stopOrderID] = so + self.workingStopOrderDict[stopOrderID] = so + + # 推送停止单状态 + strategy.onStopOrder(so) + return stopOrderID + + def sendOrder(self , vtSymbol , orderType , price, volume , stop , strategy ): + # id1 = exchange.Buy(4300,1) # 日期 平台 类型 价格 数量 信息 + # # 2016-10-21 00:00:00 OKCoin 买入 4300 1 + # id2 = exchange.Buy(-1, 8000) # 市价单 的第二个参数的意义是 购买8000金额的 币数。 + # id1 = exchange.Sell(4300,1) # 日期 平台 类型 价格 数量 信息 + # # 2016-10-21 00:00:00 OKCoin 卖出 市价单 1 + # id2 = exchange.Sell(-1, 1) # 日期 平台 类型 价格 数量 信息 + # 2016-10-21 00:00:00 OKCoin 卖出 4300 1 + # 一般错误提示: 小于允许的最小交易单位,大部分是这个原因(参数1是1块钱而不是1个币)。 + if stop == True: + vtOrderID = self.sendStopOrder(self.vtSymbol, orderType, price, volume, self) + return vtOrderID + else: + ret_order_list = [] + self.exchange.SetDirection( orderType ) + if orderType in [ CTAORDER_BUY , CTAORDER_COVER]: + ret_order_list.append( self.exchange.Buy( price , volume )) + elif orderType in [CTAORDER_SELL , CTAORDER_SHORT]: + ret_order_list.append( self.exchange.Sell( price , volume )) + return ret_order_list + + def buy(self , price , volume , stop = False): + Log(CTAORDER_BUY,price,volume) + return self.sendOrder( self.vtSymbol , CTAORDER_BUY , price , volume , stop , self) + def sell(self , price , volume , stop = False): + Log(CTAORDER_SELL,price,volume) + return self.sendOrder( self.vtSymbol , CTAORDER_SELL , price , volume , stop , self) + def short(self , price , volume , stop = False): + Log(CTAORDER_SELL,price,volume) + return self.sendOrder( self.vtSymbol , CTAORDER_SHORT , price , volume , stop , self) + def cover(self , price , volume , stop = False): + Log("cover",price,volume) + return self.sendOrder( self.vtSymbol , CTAORDER_COVER , price , volume , stop , self) + + #---------------------------------------------------------------------- + def cancelStopOrder(self, stopOrderID): + """撤销停止单""" + # 检查停止单是否存在 + if stopOrderID in self.workingStopOrderDict: + so = self.workingStopOrderDict[stopOrderID] + so.status = STOPORDER_CANCELLED + del self.workingStopOrderDict[stopOrderID] + so.strategy.onStopOrder(so) + + if stopOrderID in self.orderList: + self.orderList.remove(stopOrderID) + + def cancelOrder(self , vtOrderId): + Log("cancelOrder:",vtOrderId) + if STOPORDERPREFIX in vtOrderId: + self.cancelStopOrder(vtOrderId) + else: + self.exchange.CancelOrder(vtOrderId) + + def onTick(self, tick): + + # self.orderList = [] + # orderIDList = self.buy(tick.lastPrice , abs(self.fixedSize)) + # #Log( str(self.vtSymbol) + " cover 0 1 " + str(self.fixedSize) +" " +str(','.join(orderIDList)) + "\n") + # #print str(self.vtSymbol) , "cover 0 1" , self.fixedSize , orderID + # for orderID in orderIDList: + # self.orderList.append(orderID) + + # 聚合为1分钟K线 + tickMinute = tick.datetime.hour + + if tickMinute != self.barMinute: + if self.bar: + self.onBar(self.bar) + + bar = VtBarData() + bar.vtSymbol = tick.vtSymbol + bar.exchange = tick.exchange + + bar.open = tick.lastPrice + bar.high = tick.lastPrice + bar.low = tick.lastPrice + bar.close = tick.lastPrice + + bar.date = tick.date + bar.time = tick.time + bar.datetime = tick.datetime # K线的时间设为第一个Tick的时间 + + self.bar = bar # 这种写法为了减少一层访问,加快速度 + self.barMinute = tickMinute # 更新当前的分钟 + else: # 否则继续累加新的K线 + bar = self.bar # 写法同样为了加快速度 + + bar.high = max(bar.high, tick.lastPrice) + bar.low = min(bar.low, tick.lastPrice) + bar.close = tick.lastPrice + + def onBar(self , bar): + + if bar.datetime.hour % self.minute_use == 0: # bar.datetime.minute 则切换成分钟级别 + # 如果已经有聚合5分钟K线 + if self.fiveBar: + # 将最新分钟的数据更新到目前5分钟线中 + fiveBar = self.fiveBar + fiveBar.high = max(fiveBar.high, bar.high) + fiveBar.low = min(fiveBar.low, bar.low) + fiveBar.close = bar.close + + # 推送5分钟线数据 + self.onFiveBar(fiveBar) + + # 清空5分钟线数据缓存 + self.fiveBar = None + else: + # 如果没有缓存则新建 + if not self.fiveBar: + fiveBar = VtBarData() + + fiveBar.vtSymbol = bar.vtSymbol + fiveBar.symbol = bar.symbol + fiveBar.exchange = bar.exchange + + fiveBar.open = bar.open + fiveBar.high = bar.high + fiveBar.low = bar.low + fiveBar.close = bar.close + + fiveBar.date = bar.date + fiveBar.time = bar.time + fiveBar.datetime = bar.datetime + + self.fiveBar = fiveBar + else: + fiveBar = self.fiveBar + fiveBar.high = max(fiveBar.high, bar.high) + fiveBar.low = min(fiveBar.low, bar.low) + fiveBar.close = bar.close + + + def onFiveBar(self , bar): + #Log( self.currency , bar.close , self.pos , self.orderList) + + for orderID in self.orderList: + self.cancelOrder(orderID) + self.orderList = [] + + # 保存K线数据 + self.closeArray[0:self.bufferSize-1] = self.closeArray[1:self.bufferSize] + self.highArray[0:self.bufferSize-1] = self.highArray[1:self.bufferSize] + self.lowArray[0:self.bufferSize-1] = self.lowArray[1:self.bufferSize] + self.buyValue[0:self.bufferSize-1] = self.buyValue[1:self.bufferSize] + + self.closeArray[-1] = bar.close + self.highArray[-1] = bar.high + self.lowArray[-1] = bar.low + + # 计算指标数值 + self.bollMid = talib.MA(self.closeArray, self.bollLength)[-1] + self.bollStd = talib.STDDEV(self.closeArray, self.bollLength)[-1] + self.entryUp = self.bollMid + self.bollStd * self.topDev + + self.buyValue[-1] = self.entryUp + + self.bufferCount += 1 + if self.bufferCount < self.bufferSize: + return + + # 判断是否要进行交易 + cond1 = 0 + for i in range(1 , self.use_range + 1): + if self.highArray[-i] > self.buyValue[-i]: + cond1 = 1 + cond2 = 0 + + # newHigh = [float(x) for x in self.highArray] + # if bar.high >= max(newHigh[-self.N : ]) and self.highArray[-2] >= max(newHigh[-self.N-1 : -1]): + # cond2 = 1 + if self.pos == 0 and cond1 > 0: + self.intraTradeHigh = bar.high + newHigh = [float(x) for x in self.highArray] + entryBuyPrice = max(newHigh[-self.N:]) + orderID = self.buy( entryBuyPrice, self.fixedSize , stop=True) + self.orderList.append(orderID) + + elif self.pos > 0: + self.intraTradeHigh = max(bar.high , self.intraTradeHigh) + exitPrice = self.intraTradeHigh * (1 - self.trailingPrcnt / 100.0) + orderID = self.sell( exitPrice , self.fixedSize , stop=True) + self.orderList.append(orderID) + +''' +bollLength = 20 # 通道窗口数 +topDev = 1.3 # 开仓偏差 +trailingPrcnt = 2 # 移动止损百分比 +use_range = 10 # use_range天内有突破最高价 +N = 10 # 多少天突破 +''' +running_key = { + "BTC":{ "bollLength":20 , "topDev":1.3 , "trailingPrcnt": 2 , "use_range": 10 , "N":10 , "minute_use": 6}, + "LTC":{ "bollLength":20 , "topDev":1.3 , "trailingPrcnt": 2 , "use_range": 10 , "N":10 , "minute_use": 6} +} + +def main(): + global LoopInterval + + objs = [] + for e in exchanges: + if e.GetName() != 'Futures_OKCoin': + raise Error_noSupport + e.SetRate(1) + use_symbol = ["this_week","next_week","quarter"][ContractTypeIdx] + e.SetContractType(use_symbol) + e.SetMarginLevel([10,20][MarginLevelIdx]) + + e_currency = e.GetCurrency().upper() + Log(e_currency) + st = BollingerBreakerStrategy(e , { + "vtSymbol":e.GetName() + "_" + use_symbol + "_" + e.GetCurrency(), + "currency":e_currency, + "minute_use":running_key[e_currency]["minute_use"], + "bollLength":running_key[e_currency]["bollLength"], + "topDev": running_key[e_currency]["topDev"], + "trailingPrcnt": running_key[e_currency]["trailingPrcnt"], + "use_range": running_key[e_currency]["use_range"], + "N": running_key[e_currency]["N"] + }) + + objs.append(st) + + while True: + for st in objs: + st.onCall() + Sleep(LoopInterval * 1000) diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC).js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC).js" index 9d9d1621..0e068d0d 100644 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC).js" +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC).js" @@ -7,19 +7,20 @@ 数字货币交易类库 (期货支持OKCoin期货/BitVC) 目前测试阶段,使用请留意,如有问题 ,请联系作者 ,十分感谢! -参数 默认值 描述 ------------- ----- -------------------------- -OpMode 0 现货-下单方式: 吃单|挂单 -MaxSpace 0.5 现货-挂单失效距离 -SlidePrice 0.1 现货-下单滑动价(元) -MaxAmount 0.8 现货-开仓最大单次下单量 -RetryDelay 500 现货-失败重试(毫秒) -MAType 0 现货-均线算法: EMA|MA|AMA(自适应均线) -Interval 300 期货—失败重试间隔(毫秒) -F_SlidePrice 2 期货—下单滑价(元) -lv 0.5 期货—滑价增长率 -max_open_lv true 期货—开仓滑价最大增长率 -max_cover_lv true 期货—平仓滑价最大增长率 +参数 默认值 描述 +------------- ----- -------------------------- +OpMode 0 现货-下单方式: 吃单|挂单 +MaxSpace 0.5 现货-挂单失效距离 +SlidePrice 0.1 现货-下单滑动价(元) +MaxAmount 0.8 现货-开仓最大单次下单量 +RetryDelay 500 现货-失败重试(毫秒) +MAType 0 现货-均线算法: EMA|MA|AMA(自适应均线) +Interval 300 期货—失败重试间隔(毫秒) +F_SlidePrice 2 期货—下单滑价(元) +lv 0.5 期货—滑价增长率 +max_open_lv true 期货—开仓滑价最大增长率 +max_cover_lv true 期货—平仓滑价最大增长率 +_GetMinStocks 0.01 现货最小交易量 */ // 现货部分 @@ -55,7 +56,7 @@ function GetAccount(e, waitFrozen) { var alreadyAlert = false; while (true) { account = _C(e.GetAccount); - if (!waitFrozen || (account.FrozenStocks < e.GetMinStock() && account.FrozenBalance < 0.01)) { + if (!waitFrozen || (account.FrozenStocks < _GetMinStocks && account.FrozenBalance < 0.01)) { // _GetMinStocks break; } if (!alreadyAlert) { @@ -133,7 +134,7 @@ function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 8); doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); } - if (doAmount < e.GetMinStock()) { + if (doAmount < _GetMinStocks) { break; } prePrice = tradePrice; @@ -293,7 +294,7 @@ function Open(e, contractType, direction, opAmount, price) { needOpen = opAmount - (positionNow.Amount - initAmount); } } - if (needOpen < e.GetMinStock()) { + if (needOpen < 1) { break; } if (step > max_open_lv) { diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC) (\345\244\215\345\210\266).js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" similarity index 63% rename from "\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC) (\345\244\215\345\210\266).js" rename to "\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" index 4770d405..a1c5f50a 100644 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC) (\345\244\215\345\210\266).js" +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" @@ -1,25 +1,58 @@ /* -策略出处: https://www.botvs.com/strategy/30307 -策略名称: 数字货币交易类库 (期货支持OKCoin期货-BitVC) (复制) -策略作者: ucfyao +策略出处: https://www.botvs.com/strategy/57267 +策略名称: 数字货币交易类库 (期货支持OKCoin期货-BitVC, 支持$.CTA函数) +策略作者: 小小梦 策略描述: 数字货币交易类库 (期货支持OKCoin期货/BitVC) 目前测试阶段,使用请留意,如有问题 ,请联系作者 ,十分感谢! +- ### 新增了 $.CTA 函数 -参数 默认值 描述 ------------- ----- -------------------------- -OpMode 0 现货-下单方式: 吃单|挂单 -MaxSpace 0.5 现货-挂单失效距离 -SlidePrice 0.1 现货-下单滑动价(元) -MaxAmount 0.8 现货-开仓最大单次下单量 -RetryDelay 500 现货-失败重试(毫秒) -MAType 0 现货-均线算法: EMA|MA|AMA(自适应均线) -Interval 300 期货—失败重试间隔(毫秒) -F_SlidePrice 2 期货—下单滑价(元) -lv 0.5 期货—滑价增长率 -max_open_lv true 期货—开仓滑价最大增长率 -max_cover_lv true 期货—平仓滑价最大增长率 + 可以用 $.CTA 函数 快速构建 均线等 类型的策略 + 使用模板的 $.CTA 函数 构建的 策略代码如下(很精简): + 文章 参看 商品期货交易类库 的 $.CTA 函数 使用 (使用、架构是类似的) : https://zhuanlan.zhihu.com/p/30016518 +``` +function main() { + $.CTA(exchanges[0], 0.01, function(r, mp, pair){ // 第一个参数 是 要做的 交易所对象, 第二个参数 0.01 是交易所 要求的 最小下单数量, 第三个 匿名函数 function(){...} + // 是 回调函数, 交易逻辑 就写在这个函数中, 该回调函数 第一个参数 r 接收最新的 K线数据, 第二个参数 接收 持仓数, 第 + // 三个参数 接收 交易对 名称 + if (r.length < 20) { // 判断 K线柱数量 + return + } + var emaSlow = TA.EMA(r, 20) + var emaFast = TA.EMA(r, 5) + var cross = _Cross(emaFast, emaSlow); // 判断指标 相交状态, _Cross 参看 : https://www.botvs.com/bbs-topic/1140 + if (mp <= 0 && cross > 1) { + Log(pair, "买, 金叉周期", cross, "mp:", mp); + return 0.1 * (mp < 0 ? 2 : 1) // 返回的数值 就是 要开仓的 数量, 正数是 开多 ,负数是 开空, 0 是 全部平掉。 + } else if (mp >= 0 && cross < -1) { + Log(pair, "卖, 死叉周期", cross, "mp:", mp); + return -0.1 * (mp > 0 ? 2 : 1) + } + }) +} +``` + +https://dn-filebox.qbox.me/c230753d3fd584c15ad3e39e33f970aafffe722f.png +https://dn-filebox.qbox.me/a74f74b34e32897868086e6b771f81fd1468306e.png +https://dn-filebox.qbox.me/1671268eba20870c7820542448dc0ef541d65a5b.png + + +参数 默认值 描述 +-------------- ----- -------------------------- +OpMode 0 现货-下单方式: 吃单|挂单 +MaxSpace 0.5 现货-挂单失效距离 +SlidePrice 0.1 现货-下单滑动价(元) +MaxAmount 0.8 现货-开仓最大单次下单量 +RetryDelay 500 现货-失败重试(毫秒) +MAType 0 现货-均线算法: EMA|MA|AMA(自适应均线) +Interval 300 期货—失败重试间隔(毫秒) +F_SlidePrice 2 期货—下单滑价(元) +lv 0.5 期货—滑价增长率 +max_open_lv true 期货—开仓滑价最大增长率 +max_cover_lv true 期货—平仓滑价最大增长率 +_GetMinStocks 0.01 最小交易数量 +isCTAshowTable false 是否显示 模板生成状态栏表格 */ // 现货部分 @@ -55,7 +88,7 @@ function GetAccount(e, waitFrozen) { var alreadyAlert = false; while (true) { account = _C(e.GetAccount); - if (!waitFrozen || (account.FrozenStocks < e.GetMinStock() && account.FrozenBalance < 0.01)) { + if (!waitFrozen || (account.FrozenStocks < _GetMinStocks && account.FrozenBalance < 0.01)) { break; } if (!alreadyAlert) { @@ -126,14 +159,14 @@ function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, var doAmount = 0; if (isBuy) { diffMoney = _N(initAccount.Balance - nowAccount.Balance, 4); - dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 4); - doAmount = Math.min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance - 10) / tradePrice, 4)); + dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 8); // 如果保留小数过少,会引起在小交易量交易时,计算出的成交价格误差较大。 + doAmount = Math.min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance * 0.95) / tradePrice, 4)); } else { diffMoney = _N(nowAccount.Balance - initAccount.Balance, 4); - dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); + dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 8); doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); } - if (doAmount < e.GetMinStock()) { + if (doAmount < _GetMinStocks) { break; } prePrice = tradePrice; @@ -293,7 +326,7 @@ function Open(e, contractType, direction, opAmount, price) { needOpen = opAmount - (positionNow.Amount - initAmount); } } - if (needOpen < e.GetMinStock()) { + if (needOpen < 1) { break; } if (step > max_open_lv) { @@ -456,76 +489,147 @@ $.NewPositionManager = function(e) { return new PositionManager(e); }; +// $.CTA 函数 +$.CTA = function(Exchange, MinStock, onTick, interval){ + if(typeof(interval) !== "number"){ + interval = 500 + } + + var lastUpdate = 0 + var e = Exchange + var pair = e.GetCurrency() + var hold = 0 + var tradeInfo = null + var initAccount = _C(e.GetAccount) + var nowAccount = initAccount + + var CTAshowTable = function(r){ + var tbl = { + type : "table", + title : "策略信息,交易对" + pair, + cols : ["变量", "值"], + rows : [], + } + tbl.rows.push(["初始账户:", initAccount]) + tbl.rows.push(["当前账户:", nowAccount]) + tbl.rows.push(["上次交易信息:", tradeInfo]) + tbl.rows.push(["持仓:", hold]) + tbl.rows.push(["最新K线柱:", r[r.length - 1]]) + tbl.rows.push(["Bar 数量:", r.length]) + LogStatus(_D() + '\n`' + JSON.stringify([tbl]) + '`') + } + + Log("$.CTA 初始化 完成。") + + while(true){ + var ts = new Date().getTime() + + var r = e.GetRecords() + if(!r || r.length == 0){ + continue + } + + hold = nowAccount.Stocks - initAccount.Stocks + if(Math.abs(hold) < MinStock){ + hold = 0 + } + var n = onTick(r, hold, pair) + var callBack = null + if (typeof(n) == 'object' && typeof(n.length) == 'number' && n.length > 1) { + if (typeof(n[1]) == 'function') { + callBack = n[1] + } + n = n[0] + } + if(typeof(n) !== "number"){ + if(isCTAshowTable){ + CTAshowTable(r) + } + continue + } + + if(n > 0){ // buy + if(hold < 0){ + Log("平仓") // 测试 + tradeInfo = $.Buy(e, Math.min(-hold, n)) + if(typeof(callBack) == 'function'){ + callBack(tradeInfo) + } + n += hold + } + if(n > 0){ + Log("开仓 或 反手") // 测试 + tradeInfo = $.Buy(e, n) + if(typeof(callBack) == 'function'){ + callBack(tradeInfo) + } + } + nowAccount = _C(e.GetAccount) + }else if(n < 0){ // sell + if(hold > 0){ + Log("平仓") // 测试 + tradeInfo = $.Sell(e, Math.min(hold, -n)) + if(typeof(callBack) == 'function'){ + callBack(tradeInfo) + } + n += hold + } + if(n < 0){ + Log("开仓 或 反手") // 测试 + tradeInfo = $.Sell(e, -n) + if(typeof(callBack) == 'function'){ + callBack(tradeInfo) + } + } + nowAccount = _C(e.GetAccount) + }else{ // keep balance + // nowAccount = _C(e.GetAccount) + if(hold > 0){ + tradeInfo = $.Sell(e, hold) + if(typeof(callBack) == 'function'){ + callBack(tradeInfo) + } + nowAccount = _C(e.GetAccount) + }else if(hold < 0){ + tradeInfo = $.Buy(e, -hold) + if(typeof(callBack) == 'function'){ + callBack(tradeInfo) + } + nowAccount = _C(e.GetAccount) + } + } + + if(isCTAshowTable){ + CTAshowTable(r) + } + + Sleep(interval) + } +} + + // 测试代码 +/* +2017.5.1 - 2017.10.11 , K线 天, 模拟级别, OK国际 , BTC +*/ function main() { - if (exchange.GetName() === 'Futures_OKCoin') { - var info = exchange.SetContractType("this_week"); - Log("info 返回值:", info); - Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); - var depth = exchange.GetDepth(); - var p = $.NewPositionManager(); - p.OpenShort("this_week", 10, depth.Bids[0].Price - 2); - Log(exchange.GetPosition()); - Sleep(500 * 1000); - depth = exchange.GetDepth(); - var ret = p.Cover("this_week", depth.Bids[0].Price + 2, 5); - Log("cover ret:", ret); - //LogProfit(p.Profit()); - Log(exchange.GetPosition()); - Log("-----------------------------测试分割线----------------------------------------"); - var depth = exchange.GetDepth(); - p.OpenLong("this_week", 20, depth.Bids[0].Price + 2); - Log(exchange.GetPosition()); - Sleep(500 * 1000); - depth = exchange.GetDepth(); - var ret = p.Cover("this_week", depth.Bids[0].Price - 2, 10, PD_LONG); - Log("cover ret:", ret); - Log(exchange.GetPosition()); - Log("-----------------------------测试分割线----------------------------------------"); - var ret = p.Cover("this_week", depth.Bids[0].Price - 3, 10, PD_LONG); - Log("cover ret:", ret); - var ret = p.Cover("this_week", depth.Bids[0].Price + 3, 5, PD_SHORT); - Log("cover ret:", ret); - Log(exchange.GetPosition()); - } else if (exchange.GetName() === 'Futures_BitVC') { - var info = exchange.SetContractType("week"); - Log("info 返回值:", info); - Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); - var depth = exchange.GetDepth(); - var p = $.NewPositionManager(); - p.OpenLong("week", 500, depth.Bids[0].Price + 2); - Log(exchange.GetPosition()); - Sleep(500 * 1000); - depth = exchange.GetDepth(); - var ret = p.Cover("week", depth.Bids[0].Price - 2, 500); - Log("cover ret:", ret); - Log(exchange.GetPosition()); - Log("-----------------------------测试分割线----------------------------------------"); - var info = exchange.SetContractType("week"); - Log("info 返回值:", info); - Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); - var depth = exchange.GetDepth(); - p.OpenShort("week", 600, depth.Bids[0].Price - 2); - Log(exchange.GetPosition()); - Sleep(500 * 1000); - depth = exchange.GetDepth(); - var ret = p.Cover("week", depth.Bids[0].Price + 2, 500, PD_SHORT); - Log("cover ret:", ret); - Log(exchange.GetPosition()); - Log("-----------------------------测试分割线----------------------------------------"); - var ret = p.Cover("week", depth.Bids[0].Price + 3, 100, PD_SHORT); - Log("cover ret:", ret); - //p.Cover("week", depth.Asks[0].Price - 3, 300, PD_LONG); - Log(exchange.GetPosition()); - } else if(exchange.GetName() === 'huobi' || exchange.GetName() === 'OKCoin'){ - Log($.GetAccount()); - Log($.Buy(0.5)); - Log($.Sell(0.5)); - exchange.Buy(1000, 3); - $.CancelPendingOrders(exchanges[0]); - Log($.Cross(30, 7)); - Log($.Cross([1,2,3,2.8,3.5], [3,1.9,2,5,0.6])); - } + $.CTA(exchanges[0], 0.01, function(r, mp, pair){ // $.CTA = function(Exchange, MinStock, onTick, interval) + // Log(r.length) // 测试 + if (r.length < 20) { + return + } + var emaSlow = TA.EMA(r, 20) + var emaFast = TA.EMA(r, 5) + var cross = _Cross(emaFast, emaSlow); + + if (mp <= 0 && cross > 1) { + Log(pair, "买, 金叉周期", cross, "mp:", mp); + return 0.1 * (mp < 0 ? 2 : 1) + } else if (mp >= 0 && cross < -1) { + Log(pair, "卖, 死叉周期", cross, "mp:", mp); + return -0.1 * (mp > 0 ? 2 : 1) + } + }) } diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.py" "b/\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.py" new file mode 100644 index 00000000..7098101c --- /dev/null +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.py" @@ -0,0 +1,53 @@ +''' +策略出处: https://www.botvs.com/strategy/54256 +策略名称: 数字货币定投 +策略作者: ankye +策略描述: + +数字货币通用定投策略,支持多交易所同时定投 + +# 参数说明 +orderAmount #定投金额 BTCCNY和BCCCNY 单位 CNY, BCCBTC 单位 BTC 等等 + +accountLimitMoney #账户限额,保留一部分钱,账户达到最低限额就停止定投 + + +orderTimeInterval #定投间隔,单位秒, 每分钟=60 每小时= 3600 每天=86400 每周=604800 + +maxBidPrice #最大交易价格,超过价格就跳过,等待下次交易机会出现 + + +参数 默认值 描述 +----------------- ----- ------------------- +orderAmount true order amount +maxBidPrice false max bid price +accountLimitMoney false account limit money +orderTimeInterval 60 Order Time Interval +''' + +def onTick(): + + exchange_count = len(exchanges) + for i in range(exchange_count): + account = exchanges[i].GetAccount() + + marketName = exchanges[i].GetName() + depth = exchanges[i].GetDepth() + Log("Market ",marketName,exchanges[i].GetCurrency(),"Account Balance [",account["Balance"],"] Stocks[",account["Stocks"],"]") + if account and depth and account["Balance"] > accountLimitMoney : + bidPrice = depth["Asks"][0]["Price"] + if bidPrice < maxBidPrice : + amount = orderAmount + if amount <= account["Balance"]: + exchanges[i].Buy(amount) + else: + Log("Account Balance is less than bid Amount") + else: + Log("Bid Price >= maxBidPrice, not process") + else: + Log("Account Balance <= accountLimitMoney") +def main() : + while 1: + + onTick() + time.sleep(orderTimeInterval) diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\345\267\256\344\273\267\347\233\221\346\216\247\345\210\206\346\236\220.js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\345\267\256\344\273\267\347\233\221\346\216\247\345\210\206\346\236\220.js" new file mode 100644 index 00000000..777918b4 --- /dev/null +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\345\267\256\344\273\267\347\233\221\346\216\247\345\210\206\346\236\220.js" @@ -0,0 +1,471 @@ +/* +策略出处: https://www.botvs.com/strategy/21337 +策略名称: 数字货币差价监控分析 +策略作者: 小小梦 +策略描述: + +只支持两个交易所, 可自定义差价的类型, 支持2.77托管者的自定义图表功能 + + +参数 默认值 描述 +------------ --------------------------------------------------------------------------- -------- +TickInterval 500 检测频率(毫秒) +StrOnePair spot:Huobi:spot;spot:OKCoin:spot;false;60;5;0;0 组合1 +StrTwoPair future:Futures_OKCoin:this_week;spot:OKCoin:spot;false;60;5;0;0 组合2 +StrThreePair future:Futures_OKCoin:this_week;future:Futures_OKCoin:quarter;true;60;5;0;0 组合3 +StrFourPair null 组合4 +StrSixPair null 组合6 +StrFivePair null 组合5 +ResetChart false 是否清除上次图表 +*/ + +/* +1、初步设计为4个组合 +2、计算 对冲空间 +3、多线程 +*/ +// 参数 +// var StrOnePair = "spot:Huobi:spot;spot:OKCoin:spot;false;60"; +// var StrTwoPair = "future:Futures_OKCoin:this_week;spot:OKCoin:spot;false;60"; +// var StrThreePair = "future:Futures_OKCoin:this_week;future:Futures_OKCoin:quarter;true;60"; +// var StrFourPair = "future:Futures_BitMEX:XBTUSD;future:Futures_OKCoin:this_week;true;60"; + +// 全局变量 +var NotEnable = "null"; +var ArrayPairs = []; +var ArrayStrPairs = [StrOnePair, StrTwoPair, StrThreePair, StrFourPair, StrFivePair, StrSixPair]; +var isFirst = true; +var ChartObj = null; +var chart = null; +var OK_futureRate = 0; +var IsCheckDelivery = false; +var checkTime = 0; +var residualTime = 0; +var checkPreTime = 0; +var strDelivery = ""; +var JGHoursCorrect = 8; // 检测交割剩余小时,在实盘中需要修正 8小时。 模拟时该值设置为0 +var tbls = null; + +// 函数实现 +function CheckDelivery(nowTime, Symbol) { + var contractInfo = null; + if(checkTime <= 0){ + var contractName = ""; + var ContractIndex = 0; + if(Symbol === "this_week"){ + ContractIndex = 0; + }else if(Symbol === "next_week"){ + ContractIndex = 1; + }else if(Symbol === "quarter"){ + ContractIndex = 2; + } + + // 更新汇率 + for(var exchangeIndex = 0; exchangeIndex < exchanges.length; exchangeIndex++){ + var e_name = exchanges[exchangeIndex].GetName(); + if(e_name == "Futures_OKCoin"){ + OK_futureRate = _C(exchanges[exchangeIndex].GetUSDCNY); // 每次交割后 更新汇率 + } + } + + while (contractName == "") { + //var contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=this_week"); //只是检测this_week ,避免重复调用提高效率 + switch(ContractIndex){ + case 0: contractInfo = HttpQuery("https://www.okex.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=this_week"); // 原地址修改为: www.okex.com + break; + case 1: contractInfo = HttpQuery("https://www.okex.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=next_week"); + break; + case 2: contractInfo = HttpQuery("https://www.okex.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=quarter"); + break; + default: Log("contractInfo:", contractInfo); + //throw "switch NumContractType Error!"; + } //根据 contractType 类型 选择读取合约交割日期 + if (!contractInfo || contractInfo.length === 0) { + Sleep(100); + continue; + } + try { + contractName = (JSON.parse(contractInfo))[0].contract_name; + } catch (e) { + Log("CheckDelivery Error",contractInfo, e); + return 0; + } + } + var nowDateTime = new Date(); + contractName = contractName.split("BTC")[1]; //抽取BTC后的字符串 重新赋值 + var strMonth = contractName[0] + contractName[1]; + var strDay = contractName[2] + contractName[3]; + var strYear = nowDateTime.getFullYear() + ""; //获取 年份字符串 + + // 处理跨年问题 + var nowMonth = nowDateTime.getMonth(); // 获取月份 + if(strMonth < nowMonth){ + strYear = (strYear - 0) + 1; + strYear = strYear + ""; + } + + var strDate = strYear + '-' + strMonth + '-' + strDay + ' ' + "16:00:00"; + var deliveryTime = (new Date(strDate)).getTime(); // + 16 * 60 * 60 * 1000; + nowTime = nowDateTime.getTime(); + residualTime = (deliveryTime - nowTime) / 1000 / 60 / 60 - JGHoursCorrect; //单位是小时 + checkTime = (deliveryTime - nowTime) - JGHoursCorrect * 1000 * 60 * 60; //还差多少毫秒交割 + checkPreTime = nowTime; //记录开始的时间 + Log("合约", Symbol, "交割日期获取:", strDate); + }else{ + checkTime -= nowTime - checkPreTime; //减去消耗的时间 + checkPreTime = nowTime; + residualTime = checkTime / 1000 / 60 / 60; // 计算距离交割多少小时 + } + + return _N(residualTime, 3); +} + + +function FindExchange(StrExchangeName){ + for(var i = 0; i < exchanges.length; i++){ + if(StrExchangeName == exchanges[i].GetName()){ + return exchanges[i]; + } + if(i == exchanges.length){ + throw "没有找到 名称为:" + StrExchangeName + "的交易所对象"; + } + } +} + +function CalcAvgDiff(pair){ + var nowTime = new Date().getTime(); + if(nowTime - pair.AvgDiffUpdateTime > 1000 * pair.UpdateCycle){ + // 更新返回值 + var AvgPlus = _N(pair.SamplePlus.sum / pair.SamplePlus.count, 2); + var AvgMinus = _N(pair.SampleMinus.sum / pair.SampleMinus.count, 2); + + // 重置 + pair.AvgDiffUpdateTime = nowTime; + pair.SamplePlus.sum = 0; + pair.SamplePlus.count = 0; + pair.SampleMinus.sum = 0; + pair.SampleMinus.count = 0; + return {APlus : AvgPlus, AMinus : AvgMinus}; + }else{ + // 累计数值 + pair.SamplePlus.sum += pair.Plus; + pair.SamplePlus.count += 1; + pair.SampleMinus.sum += pair.Minus; + pair.SampleMinus.count += 1; + return false; + } +} + +function init(){ + for(var i = 0; i < ArrayStrPairs.length; i++){ + // Log(ArrayStrPairs[i]) // 测试 + if(ArrayStrPairs[i] == NotEnable){ // 过滤 + continue; + } + var pair = {}; + var exchangeOfPair = ArrayStrPairs[i].split(";"); + + if(exchangeOfPair.length !== 7){ + throw "参数错误:" + ArrayStrPairs[i]; + } + pair.exchangeA = FindExchange((exchangeOfPair[0].split(":"))[1]); // 设置 组合对象的 交易所属性 + pair.exchangeB = FindExchange((exchangeOfPair[1].split(":"))[1]); + + pair.NameA = (exchangeOfPair[0].split(":"))[1]; + pair.NameB = (exchangeOfPair[1].split(":"))[1]; + + if(pair.NameA == "Futures_OKCoin"){ + OK_futureRate = _C(pair.exchangeA.GetUSDCNY); + IsCheckDelivery = true; + } + if(pair.NameB == "Futures_OKCoin"){ + OK_futureRate = _C(pair.exchangeB.GetUSDCNY); + IsCheckDelivery = true; + } + + pair.SymbolA = (exchangeOfPair[0].split(":"))[2]; + pair.SymbolB = (exchangeOfPair[1].split(":"))[2]; + + pair.TypeA = (exchangeOfPair[0].split(":"))[0]; + pair.TypeB = (exchangeOfPair[1].split(":"))[0]; + + pair.DepthA = null; + pair.DepthB = null; + + pair.Plus = null; + pair.Minus = null; + + pair.AvgDiff = null; + pair.ID = i; + + pair.AvgDiffUpdateTime = new Date().getTime(); // 计算 均值更新时间 + pair.SamplePlus = {sum : 0, count : 0}; // 储存样本数据 + pair.SampleMinus = {sum : 0, count : 0}; // 储存样本数据 + pair.UpdateCycle = parseInt(exchangeOfPair[3]); // 更新周期秒数 + pair.GetDepthCycle = parseInt(exchangeOfPair[4]); // 获取深度 GetDepth 调用周期 2017.10.12新增 + pair.GetDepthUpdateTime = 0; // 记录 深度 更新时间 2017.10.12新增 + pair.plusAvg = 0; + pair.minusAvg = 0; + pair.Plus_count = 0; + pair.Minux_count = 0; + pair.max = null; + pair.min = null; + + pair.customRate = parseInt(exchangeOfPair[5]) // spot:OKCoin_EN:spot;future:Futures_OKCoin:this_week;true;60;5;0 默认 0 是 不启动 自定义现货汇率, 现货 汇率 + pair.customRate_futures = parseInt(exchangeOfPair[6]) // 期货 汇率 + + pair.isUseUSDRate = null; + if(exchangeOfPair[2] == "false"){ + pair.isUseUSDRate = false; + }else if(exchangeOfPair[2] == "true"){ + pair.isUseUSDRate = true; + }else{ + throw "error isUseUSDRate : " + pair.isUseUSDRate; + } + + /* + if(pair.TypeA == "future" || pair.isUseUSDRate == true){ + pair.PreRate = pair.exchangeA.GetUSDCNY(); + }else if(pair.TypeB == "future" || pair.isUseUSDRate == true){ + pair.PreRate = pair.exchangeB.GetUSDCNY(); + }else{ + pair.PreRate = pair.exchangeA.SetRate(); + } + */ + + ArrayPairs.push(pair); + Log("组合 pair: ", pair.exchangeA.GetName(), pair.exchangeB.GetName(), "#FF0000"); // ceshi + } + // 测试 + // Log(ArrayPairs); // ceshi +} + +function ToTables(time){ + // 处理图表数据 + var tbl_base = { + type : "table", + title : "pair基础数据", + cols : ["ID", "NameA - NameB", "SymbolA - SymbolB", "UpdCycle", "isUSD", "Collect"], + rows : [], + }; + + var tbl_value = { + type : "table", + title : "pair行情数据", + cols : ["ID", "NameA - NameB", "SymbolA - SymbolB", "A_Bids1", "B_Asks1", "Plus", "A_Asks1", "B_Bids1", "Minus"], + rows : [], + }; + + var tbl_Statistics = { + type : "table", + title : "pair统计数据", + cols : ["ID", "NameA - NameB", "SymbolA - SymbolB", "最大差价", "最小差价", "正溢价均值", "负溢价均值"], + rows : [], + } + + // 写入数据 迭代 写入 : NameA , SymbolA , TypeA , DepthA , Plus , Minus , time - AvgDiffUpdateTime ,UpdateCycle, isUseUSDRate + _.each(ArrayPairs, function(pair){ + var col1 = [pair.ID + " ", pair.NameA + "/" + pair.NameB, pair.SymbolA + "/" + pair.SymbolB, pair.UpdateCycle, pair.isUseUSDRate, (time - pair.AvgDiffUpdateTime) + "ms"]; + tbl_base.rows.push(col1); + + var col2 = [pair.ID + " ", pair.NameA + "/" + pair.NameB, pair.SymbolA + "/" + pair.SymbolB, pair.DepthA.Bids[0].Price, pair.DepthB.Asks[0].Price, pair.Plus, pair.DepthA.Asks[0].Price, pair.DepthB.Bids[0].Price, pair.Minus]; + tbl_value.rows.push(col2); + + var col3 = [pair.ID + " ", pair.NameA + "/" + pair.NameB, pair.SymbolA + "/" + pair.SymbolB, pair.max, pair.min, pair.plusAvg, pair.minusAvg] + tbl_Statistics.rows.push(col3); + }); + + return [tbl_base, tbl_value, tbl_Statistics]; +} + +function loop(beginTime){ + _.each(ArrayPairs, function(pair){ + var DepthA = null; // 临时储存 + var DepthB = null; // 临时储存 + + // 判断是否需要更新 + if(new Date().getTime() - pair.GetDepthUpdateTime < 1000 * pair.GetDepthCycle){ + return + }else{ + pair.GetDepthUpdateTime = new Date().getTime() // 记录 更新时间 + } + + if(pair.TypeA == "spot" && pair.isUseUSDRate == false){ // 如果当前组合 A 为现货 并且 不使用美元计价,直接获取数据 + if(pair.customRate !== 0){ + // Log("切换韩元汇率:", pair.customRate, pair.exchangeA.GetRate(), typeof(pair.customRate)) // ceshi + pair.exchangeA.SetRate(pair.customRate) + // Log(pair.exchangeA.SetRate(1/1115), "#FF0000") // ceshi + } + DepthA = pair.exchangeA.GetDepth(); + }else if(pair.TypeA == "future" && pair.isUseUSDRate == false){ // 如果当前组合 A 为期货 并且 不使用美元计价,需要判断是否为OKEX ,使用OKEX自己的汇率转换为RMB计价 + if(pair.NameA !== "Futures_OKCoin"){ + if(pair.customRate_futures !== 0){ + pair.exchangeA.SetRate(pair.customRate_futures) + } + pair.exchangeA.SetContractType(pair.SymbolA); + DepthA = pair.exchangeA.GetDepth(); + }else{ + if(pair.customRate_futures == 0){ + pair.PreRate = pair.exchangeA.SetRate(OK_futureRate); + }else{ + pair.PreRate = pair.exchangeA.SetRate(pair.customRate_futures) + } + pair.exchangeA.SetContractType(pair.SymbolA); + DepthA = pair.exchangeA.GetDepth(); + pair.exchangeA.SetRate(pair.PreRate); + } + }else if(pair.TypeA == "spot" && pair.isUseUSDRate == true){ // 如果当前组合 A 为现货 并且 使用美元计价, 切换禁用底层转换, 获取数据后,恢复。 + pair.PreRate = pair.exchangeA.SetRate(1); + DepthA = pair.exchangeA.GetDepth(); + pair.exchangeA.SetRate(pair.PreRate); + }else if(pair.TypeA == "future" && pair.isUseUSDRate == true){ // 如果当前组合 A 为期货 并且 使用美元计价, 切换禁用底层转换, 获取数据后,恢复。 + pair.PreRate = pair.exchangeA.SetRate(1); + pair.exchangeA.SetContractType(pair.SymbolA); + DepthA = pair.exchangeA.GetDepth(); + pair.exchangeA.SetRate(pair.PreRate); + } + + if(pair.TypeB == "spot" && pair.isUseUSDRate == false){ + if(pair.customRate !== 0){ + // Log("切换韩元汇率:", pair.customRate, pair.exchangeB.GetRate(), typeof(pair.customRate)) // ceshi 切换韩元汇率: 1115 1000 number + pair.exchangeB.SetRate(pair.customRate) + // Log(pair.exchangeB.SetRate(1/1115), "#FF0000") // ceshi undefined + } + DepthB = pair.exchangeB.GetDepth(); + }else if(pair.TypeB == "future" && pair.isUseUSDRate == false){ + if(pair.NameB !== "Futures_OKCoin"){ + if(pair.customRate_futures !== 0){ + pair.exchangeB.SetRate(pair.customRate_futures) + } + pair.exchangeB.SetContractType(pair.SymbolB); + DepthB = pair.exchangeB.GetDepth(); + }else{ + if(pair.customRate_futures == 0){ + pair.PreRate = pair.exchangeB.SetRate(OK_futureRate); + }else{ + pair.PreRate = pair.exchangeB.SetRate(pair.customRate_futures) + } + pair.exchangeB.SetContractType(pair.SymbolB); + DepthB = pair.exchangeB.GetDepth(); + pair.exchangeB.SetRate(pair.PreRate); + } + }else if(pair.TypeB == "spot" && pair.isUseUSDRate == true){ + pair.PreRate = pair.exchangeB.SetRate(1); + DepthB = pair.exchangeB.GetDepth(); + pair.exchangeB.SetRate(pair.PreRate); + }else if(pair.TypeB == "future" && pair.isUseUSDRate == true){ + pair.PreRate = pair.exchangeB.SetRate(1); + pair.exchangeB.SetContractType(pair.SymbolB); + DepthB = pair.exchangeB.GetDepth(); + pair.exchangeB.SetRate(pair.PreRate); + } + + // 过滤 数据,确定数据没有问题再赋值给 对象持久化。 + if(!DepthA || !DepthB || DepthA.Asks.length == 0 || DepthA.Bids.length == 0 || + DepthB.Asks.length == 0 || DepthB.Bids.length == 0){ + return; + } + + // 过滤后给数据赋值 + pair.DepthA = DepthA; + pair.DepthB = DepthB; + + pair.Plus = _N(pair.DepthA.Bids[0].Price - pair.DepthB.Asks[0].Price, 2); + pair.Minus = _N(pair.DepthA.Asks[0].Price - pair.DepthB.Bids[0].Price, 2); + + // 统计 平均、最大、最小 + if(pair.min == null){ + pair.min = pair.Minus + }else{ + pair.min = Math.min(pair.min, pair.Minus) + } + if(pair.max == null){ + pair.max = pair.Plus + }else{ + pair.max = Math.max(pair.max, pair.Plus) + } + + if(pair.Plus > 0){ + pair.plusAvg = ((pair.plusAvg * pair.Plus_count) + pair.Plus) / (pair.Plus_count + 1) + pair.Plus_count++ + } + + if(pair.Minus < 0){ + pair.minusAvg = ((pair.minusAvg * pair.Minux_count) + pair.Minus) / (pair.Minux_count + 1) + pair.Minux_count++ + } + + + + // 调用计算函数 计算均值,间隔时间输出 + var AvgDiff = CalcAvgDiff(pair); + + if(AvgDiff !== false){ // 根据周期 设置 更新图像 + $.PlotLine("pairID:" + pair.ID + " : Plus" /*pair.NameA + "/" + pair.NameB + ":Plus"*/, AvgDiff.APlus, beginTime); + $.PlotLine("pairID:" + pair.ID + " : Minus" /*pair.NameA + "/" + pair.NameB + ":Minus"*/, AvgDiff.AMinus, beginTime); + } + + // 首次执行一些操作 + if(isFirst){ + chart = $.PlotLine("pairID:" + pair.ID + " : Plus" /*pair.NameA + "/" + pair.NameB + ":Plus"*/, pair.Plus); + chart = $.PlotLine("pairID:" + pair.ID + " : Minus" /*pair.NameA + "/" + pair.NameB + ":Minus"*/, pair.Minus); + if(pair.isUseUSDRate){ + for(var key in ChartObj.series){ + if(ChartObj.series[key].name == pair.NameA + "/" + pair.NameB + ":Plus" || ChartObj.series[key].name == pair.NameA + "/" + pair.NameB + ":Minus"){ + ChartObj.series[key].yAxis = 1; + } + } + } + } + }); + + // 结束首次 + if(isFirst){ + chart.update(ChartObj); + if(ResetChart){ + chart.reset(); + } + isFirst = false; + } + tbls = ToTables(beginTime); +} + + +function main(){ + // 图标初始设置 + ChartObj = $.GetCfg(); + // 处理 指标轴 + ChartObj.yAxis = [{ + title: {text: 'RMB计价'},//标题 + style: {color: '#4572A7'},//样式 + opposite: false, //生成右边Y轴 + }, + { + title:{text: "美元计价"}, + opposite: true, //生成右边Y轴 ceshi + } + ]; + + while(true){ + var beginTime = new Date().getTime(); + loop(beginTime); + Sleep(TickInterval); + if(IsCheckDelivery && (!IsVirtual())){ + var numDelivery = CheckDelivery(beginTime, "this_week"); + strDelivery = "距离当周合约交割剩余:" + numDelivery + " 小时! OK期货汇率:" + OK_futureRate; + } + var endTime = new Date().getTime(); + LogStatus("轮询耗时:" + (endTime - beginTime) + "ms" + '\n`' + JSON.stringify(tbls) + '`' + '\n' + strDelivery); + } +} + + + + + + + + + + + diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" index 6c8d5613..9c8fbf3a 100644 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" @@ -4,57 +4,166 @@ 策略作者: Zero 策略描述: -暂时封装了以下几个函数 - -> $.GetAccount(e) - -``` -Log($.GetAccount()); // 获取账户信息, 带容错功能 -Log($.GetAcccount(exchanges[1])); -``` - -> $.Buy/Sell(e, amount) - -``` -$.Buy(0.3); // 主交易所买入0.3个币 -$.Sell(0.2); // 主交易所卖出0.2个币 -$.Sell(exchanges[1], 0.1); // 次交易所卖出0.1个币 -``` -> $.CancelPendingOrders(e, orderType) - -``` -$.CancelPendingOrders(); // 取消主交易所所有委托单 -$.CancelPendingOrders(ORDER_TYPE_BUY); // 取消主交易所所有的买单 -$.CancelPendingOrders(exchanges[1]); // 取消第二个交易所所有订单 -$.CancelPendingOrders(exchanges[1], ORDER_TYPE_SELL); // 取消第二个交易所所有的卖单 -``` - -> $.Cross(periodA, periodB) / $.Cross(arr1, arr2); - -``` -var n = $.Cross(15, 30); -var m = $.Cross([1,2,3,2.8,3.5], [3,1.9,2,5,0.6]) -``` - -``` text -如果 n 等于 0, 指刚好15周期的EMA与30周期的EMA当前价格相等 -如果 n 大于 0, 比如 5, 指15周期的EMA上穿了30周期的EMA 5个周期(Bar) -如果 n 小于 0, 比如 -12, 指15周期的EMA下穿了30周期的EMA 12个周期(Bar) -如果传给Cross不是数组, 则函数自动获取K线进行均线计算 -如果传给Cross的是数组, 则直接进行比较 +暂时封装了以下几个函数 + +> $.GetAccount(e) + +``` +Log($.GetAccount()); // 获取账户信息, 带容错功能 +Log($.GetAcccount(exchanges[1])); +``` + +> $.Buy/Sell(e, amount) + +``` +$.Buy(0.3); // 主交易所买入0.3个币 +$.Sell(0.2); // 主交易所卖出0.2个币 +$.Sell(exchanges[1], 0.1); // 次交易所卖出0.1个币 +``` +> $.CancelPendingOrders(e, orderType) + +``` +$.CancelPendingOrders(); // 取消主交易所所有委托单 +$.CancelPendingOrders(ORDER_TYPE_BUY); // 取消主交易所所有的买单 +$.CancelPendingOrders(exchanges[1]); // 取消第二个交易所所有订单 +$.CancelPendingOrders(exchanges[1], ORDER_TYPE_SELL); // 取消第二个交易所所有的卖单 ``` +> $.Cross(periodA, periodB) / $.Cross(arr1, arr2); -参数 默认值 描述 ----------- ----- ----------------------- -OpMode 0 下单方式: 吃单|挂单 -MaxSpace 0.5 挂单失效距离 -SlidePrice 0.1 下单滑动价(元) -MaxAmount 0.8 开仓最大单次下单量 -RetryDelay 500 失败重试(毫秒) -MAType 0 均线算法: EMA|MA|AMA(自适应均线) +``` +var n = $.Cross(15, 30); +var m = $.Cross([1,2,3,2.8,3.5], [3,1.9,2,5,0.6]) +``` + +``` text +如果 n 等于 0, 指刚好15周期的EMA与30周期的EMA当前价格相等 +如果 n 大于 0, 比如 5, 指15周期的EMA上穿了30周期的EMA 5个周期(Bar) +如果 n 小于 0, 比如 -12, 指15周期的EMA下穿了30周期的EMA 12个周期(Bar) +如果传给Cross不是数组, 则函数自动获取K线进行均线计算 +如果传给Cross的是数组, 则直接进行比较 +``` + +> $.withdraw(e, currency, address, amount, fee, password) 提现函数 + +``` +$.withdraw(exchange, "btc", "0x.........", 1.0, 0.0001, "***") +``` + + +参数 默认值 描述 +---------- ------- ----------------------- +OpMode 0 下单方式: 吃单|挂单 +MaxSpace 0.5 挂单失效距离 +SlidePrice 0.1 下单滑动价(元) +MaxAmount 0.8 开仓最大单次下单量 +RetryDelay 500 失败重试(毫秒) +MAType 0 均线算法: EMA|MA|AMA(自适应均线) +MinStock 0.001 最小交易量 */ +$.withdraw = function(e, currency, address, amount, fee, password) { + var withdraw_id = null; + var ret = null; + currency = currency.toLowerCase() + switch (e.GetName()) { + case "OKCoin_EN": + ret = e.IO("api", "POST", "/api/v1/withdraw.do", "symbol="+currency.toLowerCase()+"_usd&chargefee=" + fee + "&trade_pwd=" + password + "&withdraw_address=" + address + "&withdraw_amount=" + amount); + if (ret && typeof(ret.withdraw_id) !== 'undefined') { + withdraw_id = ret.withdraw_id; + } else { + var err = GetLastError(); + if (err && err.indexOf('10031') !== -1) { + Log("OKCoin_EN 需6个网络确认后方能提现"); + } + } + break; + case "Huobi": + if (currency == "bch") { + currency = "bcc" + } + ret = e.IO("api", "POST", "/v1/dw/withdraw-virtual/create", "currency="+currency+"&fee=" + fee + "&address=" + address + "&amount=" + amount); + if (ret && typeof(ret.withdraw_id) !== 'undefined') { + withdraw_id = ret.data; + } + break; + case "Bithumb": + ret = e.IO("api", "POST", "/trade/btc_withdrawal", "currency="+currency.toUpperCase()+"&address=" + address + "&units=" + amount); + if (ret && parseInt(ret.status) == 0) { + withdraw_id = 9999; + } + break; + case "GateIO": + ret = e.IO("api", "POST", "/api2/1/private/withdraw", "currency="+currency+"&address=" + address + "&amount=" + amount); + if (ret && parseInt(ret.code) == 0) { + withdraw_id = 9999; + } + break; + case "ZB": + ret = e.IO("api", "POST", "/api/withdraw", "method=withdraw&itransfer=0¤cy="+currency+"&receiveAddr=" + address + "&amount=" + amount+"&fees="+fee+"&safePwd="+password); + if (ret && parseInt(ret.code) == 0) { + withdraw_id = ret.id; + } + break; + case "Bitfinex": + var cMap = { + "btc": "bitcoin", + "ltc": "litecoin", + "eth": "ethereum", + "etc": "ethereumc", + "zec": "zcash", + "xmr": "monero", + "omni": "mastercoin", + "usd": "wire", + "dash": "dash", + "xrp": "ripple", + "eos": "eos"}; + if (typeof(cMap[currency]) == 'undefined') { + throw "bitfinex not support " + currency; + } + var withdraw_type = cMap[currency]; + ret = e.IO("api", "POST", "/v1/withdraw", "withdraw_type=" + withdraw_type + "&walletselected=exchange&address=" + address + "&amount=" + amount); + if (ret && ret.length == 1 && typeof(ret[0].withdrawal_id) !== 'undefined') { + withdraw_id = ret[0].withdrawal_id; + } + break; + case "Poloniex": + var ext = ""; + if (currency == 'xrp') { + //ext = '&paymentId=' + PXRPLabel; + } + if (currency.toLowerCase() == 'bts' && address.indexOf('_') == -1) { + address = "poloniexwallet_" + address; + } + ret = e.IO("api", "POST", "withdraw", "amount=" + amount + "¤cy="+currency.toUpperCase()+"&address=" + address+ext); + if (ret && ret.response.indexOf('With') !== -1) { + withdraw_id = 9999; + } + break + case "Bittrex": + ret = e.IO("api", "GET", "/api/v1.1/account/withdraw", "quantity=" + amount + "¤cy="+currency.toUpperCase()+"&address=" + address); + if (ret && ret.success) { + withdraw_id = ret.result.uuid; + } + break + case "Binance": + ret = e.IO("api", "POST", "/wapi/v1/withdraw.html", "amount=" + amount + "&asset=" + currency + "&address=" + address); + if (ret && ret.success) { + withdraw_id = 9999; + } + break + case "OKEX": + ret = e.IO("api", "POST", "/api/v1/withdraw.do", "target=address&withdraw_amount=" + amount + "&symbol="+currency+"_usd&withdraw_address=" + address+"&chargefee="+fee+"&trade_pwd="+password); + if (ret && ret.result) { + withdraw_id = ret.withdraw_id; + } + break + default: + throw "不支持的操作"; + } + return {info: ret, withdraw_id: withdraw_id} +} + function CancelPendingOrders(e, orderType) { while (true) { var orders = e.GetOrders(); @@ -87,7 +196,7 @@ function GetAccount(e, waitFrozen) { var alreadyAlert = false; while (true) { account = _C(e.GetAccount); - if (!waitFrozen || (account.FrozenStocks < e.GetMinStock() && account.FrozenBalance < 0.01)) { + if (!waitFrozen || (account.FrozenStocks < MinStock && account.FrozenBalance < 0.01)) { break; } if (!alreadyAlert) { @@ -165,7 +274,7 @@ function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); } - if (doAmount < e.GetMinStock()) { + if (doAmount < MinStock) { break; } prePrice = tradePrice; @@ -230,10 +339,10 @@ $.GetAccount = function(e) { return _C(e.GetAccount); }; -var _MACalcMethod = [TA.EMA, TA.MA, talib.KAMA][MAType]; // 返回上穿的周期数. 正数为上穿周数, 负数表示下穿的周数, 0指当前价格一样 $.Cross = function(a, b) { + var pfnMA = [TA.EMA, TA.MA, talib.KAMA][MAType]; var crossNum = 0; var arr1 = []; var arr2 = []; @@ -249,8 +358,8 @@ $.Cross = function(a, b) { } Sleep(RetryDelay); } - arr1 = _MACalcMethod(records, a); - arr2 = _MACalcMethod(records, b); + arr1 = pfnMA(records, a); + arr2 = pfnMA(records, b); } if (arr1.length !== arr2.length) { throw "array length not equal"; diff --git "a/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" "b/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" index 5f355a53..0a79d3ca 100644 --- "a/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" +++ "b/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" @@ -24,7 +24,7 @@ period: 15 mode: 1 */ -/*args +/*defaults number : 0 bool: false string: Hello BotVS! @@ -34,6 +34,6 @@ comboBox : 2 function main(){ while(true){ LogStatus("测试默认参数!"); - Sleep(); + Sleep(1000); } } diff --git "a/\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211 (\345\244\215\345\210\266).js" "b/\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211 (\345\244\215\345\210\266).js" deleted file mode 100644 index 47107331..00000000 --- "a/\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211 (\345\244\215\345\210\266).js" +++ /dev/null @@ -1,274 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/31456 -策略名称: 测试-布林带策略(基于策略框架) (复制) -策略作者: ylbjabc -策略描述: - -策略框架 - - -参数 默认值 描述 ----------- ----- --------- -isLogReset true 启动时是否清除日志 - -按钮 默认值 描述 ------------- ---------- ------- -upDateAmount true 更新开仓量按钮 -cmdOpen __button__ 开仓命令 -cmdCover __button__ 平仓命令 -*/ - -var Interval = 500; -var _long = 1; -var free = 0; -var state = free; //每次开仓 平仓 重置 -var buyInfo = null; //每次平仓重置 -var sellInfo = null; //每次开仓重置 -var initAccount = null; //每次平仓重置 -var beginAccount = null; //不重置 -var Profit = 0; //已实现盈亏 -var prefloatProfit = 0;//上次的浮动盈亏,滑动止盈 更新 -var openBalance = 0;//开仓量 -var isCover = false; - -var tiaojian = 0; //这里可以设置 触发条件,比如 自定义的指标函数 发出开仓信号(比如返回了 数值 1 ), 比如 0 时 是等待, 等于 2 时 是平仓 - //也可能 触发了平仓条件 -var Amount = 1; //这里可以把 交易的量(币数) 写在程序里 自动控制(比如,根据盘口量), 也可以设置在界面上做成界面上的参数,在程序运行的时候传进来。 - -var NowPositionInfo = {//持仓信息, 每次平仓更新 - avgPrice: 0, - amount: 0 , - floatProfit: 0 -}; - -function openUpdate(){//开仓后的更新 - state = _long; - sellInfo = null; - tiaojian = 0;//重置条件 -} -function closeUpdate(){//平仓后的更新 - state = free; - addLevel = 0; - buyInfo = null; - initAccount = _C(exchange.GetAccount); - NowPositionInfo.avgPrice = 0; - NowPositionInfo.amount = 0; - NowPositionInfo.floatProfit = 0; - isCover = true; - tiaojian = 0;//重置条件 -} - -function Calculate(nowAccount,nowDepth){//计算并更新收益 、 浮动收益 、计算 持仓均价 、持仓量 - if(typeof(nowAccount) === 'undefined' ){ - nowAccount = _C(exchange.GetAccount); - nowDepth = _C(exchange.GetDepth); - } - var diff_stocks = nowAccount.Stocks - initAccount.Stocks;//币之差 - var diff_balance = nowAccount.Balance - initAccount.Balance;//钱之差 - NowPositionInfo.avgPrice = Math.abs(diff_balance) / Math.abs(diff_stocks); - NowPositionInfo.amount = Math.abs(diff_stocks); - NowPositionInfo.floatProfit = diff_balance + diff_stocks * nowDepth.Bids[0].Price; //此次交易的浮动盈亏 - Profit = (initAccount.Stocks - beginAccount.Stocks) * nowDepth.Bids[0].Price + (initAccount.Balance - beginAccount.Balance); //实现盈亏 - - //更新入界面 -} - -function get_Command(){//负责交互的函数,交互及时更新 相关数值 ,熟悉的用户可以自行扩展 - var keyValue = 0;// 命令传来的参数 数值 - var way = null; //路由 - var cmd = GetCommand(); //获取 交互命令API - if (cmd) { - Log("按下了按钮:",cmd);//日志显示 - arrStr = cmd.split(":"); // GetCommand 函数返回的 是一个字符串,这里我处理的麻烦了,因为想熟悉一下JSON ,所以先对字符串做出处理,把函数返回的字符串以 : 号分割成2个字符串。储存在字符串数组中。 - - if(arrStr.length === 2){//接受的不是 数值型的,是按钮型的。 - jsonObjStr = '{' + '"' + arrStr[0] + '"' + ':' + arrStr[1] + '}'; // 把 字符串数组中的元素重新 拼接 ,拼接成 JSON 字符串 用于转换为JSON 对象。 - jsonObj = JSON.parse(jsonObjStr); // 转换为JSON 对象 - - for(var key in jsonObj){ // 遍历对象中的 成员名 - keyValue = jsonObj[key]; //取出成员名对应的 值 , 就是交互按钮的值 - } - - if(arrStr[0] == "upDateAmount"){// 此处为 数字型 。这里处理分为 按钮 和 数字型 。 详见 策略参数 设置界面 下的 交互设置 - way = 1; - } - if(arrStr[0] == "扩展1"){ - way = 2; - } - if(arrStr[0] == "扩展2"){ - way = 3; - } - if(arrStr[0] == "扩展3"){ - way = 4; - } - }else if(arrStr.length === 1){// 此处为 按钮型 - //路由 - if(cmd == "cmdOpen"){ - way = 0; - } - if(cmd == "cmdCover"){ - way = 5; - } - }else{ - throw "error:" + cmd + "--" + arrStr; - } - switch(way){ // 分支选择 操作 - case 0://处理 发出开仓信号 - tiaojian = 1; - break; - case 1://处理 - Amount = keyValue;//把交互界面设置的 数值 传递给 Amount - Log("开仓量修改为:",Amount);//提示信息 - break; - case 2://处理 - - break; - case 3://处理 - - break; - case 4://处理 - - break; - case 5://处理 发出平仓信号 - tiaojian = 2; - break; - default: break; - } - } -} - -function Loop(){//循环主体 - //获取 行情、账户等信息 - var account = _C(exchange.GetAccount); - var records = _C(exchange.GetRecords); - var depth = _C(exchange.GetDepth); - var len = records.length - 1; - - //对获取的数据 容错处理 - if(records.length < 10 ){//这里可以对 API 获取的数据 容错处理,这里举个例子 就是 获取的K线长度 必须大于10,小于10了 就返回 不做处理并在界面显示提示信息。 - //输出到状态栏表格,显示K线长度不足 - msg = "K线长度不足,获取中..."; - return; - } - msg = "K line `s length:" + (len + 1); - - //图表模板的使用--------------- - $.Draw(records); - //--------------------------- - - - //第一次启动 处理的内容--------- - if(isFirst === true){ - $.SignOP((new Date()).getTime(),null,null,3,"图表显示启动!");// 测试标记 自定义信息 到图表上 - Log("程序启动!"); - isFirst = false; - } - //-------------------------- - - //策略运行时状态栏表格上的显示数据 table.b1 就是往 b1 这个格子里 写入 "stock:" + account.Stocks + "#ff00ff"; 这些数据,可以对比截图,自己动手试试。 - table.b1 = "stock:" + account.Stocks + "#ff00ff"; - table.c1 = "Fstock:" + account.FrozenStocks + "#ff00ff"; - table.d1 = "balance:" + account.Balance + "#ff00ff"; - table.e1 = "Fbalance:" + account.FrozenBalance + "#ff00ff"; - table.b2 = "open:" + records[len].Open; - table.c2 = "high:" + records[len].High; - table.d2 = "low:" + records[len].Low; - table.e2 = "close:" + records[len].Close; - table.b3 = "bids[0].price:" + depth.Bids[0].Price; - table.c3 = "bids[0].amount:" + depth.Bids[0].Amount; - table.d3 = "asks[0].price:" + depth.Asks[0].Price; - table.e3 = "asks[0].amount:" + depth.Asks[0].Amount; - table.c4 = "avgPrice:" + NowPositionInfo.avgPrice; - table.d4 = "amount:" + NowPositionInfo.amount; - table.e4 = "floatProfit:" + NowPositionInfo.floatProfit; - //------------------------------------------------------------------------- - - //处理 策略交互 - get_Command();//获取 并处理交互 - - - //这里可以自定义 触发 操作的代码,比如 指标交叉了(当然这是你自定义的), 就可以给 tiaojian 这个变量赋值 1, 即: tiaojian = 1; 这样下面满足条件就执行相应操作。 - var boll = TA.BOLL(records, 20, 2); // 调用布林指标 - var up = boll[0]; - var down = boll[2]; - $.AddZhiBiao(up, records, 1); - $.AddZhiBiao(down, records, 2); - /* - 求一个简单的策略,哪位大神出手帮助一下 - okcoin现货btc,1小时布林线,价格上穿布林线下轨买入,价格上穿布林线上轨卖出 - 止损:现价低于买入价2%止损. - 哪位大神可以帮忙呢? - */ - // cross down - if(records[records.length - 1].Close > down[down.length - 1] && records[records.length - 2].Close < down[down.length - 2]){ - tiaojian = 1; - }else if(records[records.length - 1].Close > up[up.length - 1] && records[records.length - 2].Close < up[up.length - 2]){ - tiaojian = 2; - } - - - - if(state === free && tiaojian === 1 ){//开仓条件,可以自行扩展,指标形态、差价、交易量 等等 - //触发了上面的if括号内的条件,这个里面就是执行具体的开仓操作了,举个例子是用 数字货币交易类库 这个模板处理开仓。 - buyInfo = $.Buy(Amount); - if(buyInfo === null){// $.Buy这个函数 返回 null 说明有原因导致 没有买到(即没有开仓成功,原因有多个可能。) - return; - } - $.SignOP((new Date()).getTime(),buyInfo.price,buyInfo.amount,1);// 把操作标记 到图表上 . 图表模板 用法可以看论坛上的帖子 - openUpdate(); - }else if(state === _long && tiaojian === 2 ){ - sellInfo = $.Sell(NowPositionInfo.amount); - if(buyInfo === null){ - return; - } - $.SignOP((new Date()).getTime(),sellInfo.price,sellInfo.amount,0);// 把操作标记 到图表上 - closeUpdate(); - } - - - //如果平仓了,更新收益----------------------- - Calculate();//计算收益,更新持仓状态 - if(isCover === true){ - LogProfit(Profit); - isCover = false; - } - //---------------------------------------- - - //更新图表--------------------------- - $.UpDateChart(records); - //--------------------------------- -} - -var table = null; -var msg = "";//显示在状态栏表格头部的 消息 -var isFirst = true; - -function main(){ - //初始化 - if(isLogReset === true){ - LogReset(); - } - beginAccount = _C(exchange.GetAccount);//程序开始运行时的初始账户信息 - initAccount = beginAccount;//每次开仓前的账户信息 - table = $.TableInit(5,6); - //初始化表格 5,代表 表格生成5列 分别是 a b c d e , 6代表表格生成 6行 分别是 0 1 2 3 4 5 6 。 这样最左上角的表格单元的坐标就是 a0 , table.a0 = 3; 此时就会显示到相应的表格 - - //给表格写上不许要变动的内容------------------ - table.a1 = "account:" + "#ff00ff"; - table.a2 = "records[length-1]:"; - table.a3 = "depth.Bids[0]/Asks[0]:"; - table.a0 = "beginAccount:"; - table.b0 = "stock:" + beginAccount.Stocks; - table.c0 = "Fstock:" + beginAccount.FrozenStocks; - table.d0 = "balance:" + beginAccount.Balance; - table.e0 = "Fbalance:" + beginAccount.FrozenBalance; - //---------------------------------------------------- - - while(true){ - Loop();//循环函数 - $.UpDateLogStatus(msg);//更新表格 数据 - msg = ""; - Sleep(Interval); - } -} - diff --git "a/\347\224\273\347\272\277\347\261\273\345\272\223.js" "b/\347\224\273\347\272\277\347\261\273\345\272\223.js" index f9606d41..386f1867 100644 --- "a/\347\224\273\347\272\277\347\261\273\345\272\223.js" +++ "b/\347\224\273\347\272\277\347\261\273\345\272\223.js" @@ -135,6 +135,7 @@ $.PlotRecords = function(records, title) { var seriesIdx = labelIdx["candlestick"]; if (!chart) { chart = Chart(cfg) + chart.reset() } if (typeof(seriesIdx) == 'undefined') { cfg.__isStock = true @@ -175,6 +176,7 @@ $.PlotLine = function(label, dot, time) { type: 'datetime' } chart = Chart(cfg) + chart.reset() } var seriesIdx = labelIdx[label] if (typeof(seriesIdx) === 'undefined') { @@ -211,6 +213,7 @@ $.PlotLine = function(label, dot, time) { $.PlotFlag = function(time, text, title, shape, color) { if (!chart) { chart = Chart(cfg) + chart.reset() } label = "flag"; var seriesIdx = labelIdx[label] diff --git "a/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" "b/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" index 7fe796d2..4df890e3 100644 --- "a/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" +++ "b/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" @@ -402,6 +402,16 @@ $.TaskCmd = function(cmd, amount, lastPrice){ } } +$.GetTaskState = function(Name, Label){ + var ret = null; + _.each(Tasks, function(task){ + if(task.Name == Name && task.Label == Label){ + ret = task.STATE; + } + }); + return ret; +} + // 模板导出函数 var usedTime = 0; $.Trend = function() { diff --git "a/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.js" "b/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.js" new file mode 100644 index 00000000..556be227 --- /dev/null +++ "b/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.js" @@ -0,0 +1,52 @@ +/* +策略出处: https://www.botvs.com/strategy/57029 +策略名称: 简单多品种商品期货均线策略 +策略作者: Zero +策略描述: + +商品期货类库实现了$.CTA函数的策略框架,借助该策略框架, 可以短短几十行实现一个并发稳定可实盘的多品种策略 + + https://dn-filebox.qbox.me/21384f4e53937bc1dd252ff478ff08e5b4d52e71.png + + +参数 默认值 描述 +------------- ----------- ---- +Symbols rb000,MA000 操作品种 +FastPeriod 5 快线周期 +SlowPeriod 20 慢线周期 +ConfirmPeriod 2 确认周期 +Lots true 开仓手数 +*/ + +/*backtest +start: 2017-06-01 00:00:00 +end: 2017-10-01 00:00:00 +period: 1d +*/ +function main() { + // 使用了商品期货类库的CTA策略框架 + $.CTA(Symbols, function(st) { + var r = st.records + var mp = st.position.amount + var symbol = st.symbol + /* + r为K线, mp为当前品种持仓数量, 正数指多仓, 负数指空仓, 0则不持仓, symbol指品种名称 + 返回值如为n: + n = 0 : 指全部平仓(不管当前持多持空) + n > 0 : 如果当前持多仓,则加n个多仓, 如果当前为空仓则平n个空仓,如果n大于当前持仓, 则反手开多仓 + n < 0 : 如果当前持空仓,则加n个空仓, 如果当前为多仓则平n个多仓,如果-n大于当前持仓, 则反手开空仓 + 无返回值表示什么也不做 + */ + if (r.length < SlowPeriod) { + return + } + var cross = _Cross(TA.EMA(r, FastPeriod), TA.EMA(r, SlowPeriod)); + if (mp <= 0 && cross > ConfirmPeriod) { + Log(symbol, "金叉周期", cross, "当前持仓", mp); + return Lots * (mp < 0 ? 2 : 1) + } else if (mp >= 0 && cross < -ConfirmPeriod) { + Log(symbol, "死叉周期", cross, "当前持仓", mp); + return -Lots * (mp > 0 ? 2 : 1) + } + }); +} diff --git "a/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" new file mode 100644 index 00000000..90d6e1e3 --- /dev/null +++ "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" @@ -0,0 +1,650 @@ +/* +策略出处: https://www.botvs.com/strategy/629 +策略名称: 网格变形策略之单边网格 +策略作者: Zero +策略描述: + +网格可以自定义方向 +先买后卖: +网格会从首价格开始向下挂买单, 每个买单间隔 "价格间隔" 这个参数, 挂单数量为"单笔数量", 挂够 "总数量" 个买单, 有任意买单成交以后, 程序会在买价基础上加 "价差(元)" 这个参数的的值的价格挂出卖单, 卖出, 卖出以后,重新按原来这个网格的价格挂买入单 +先卖后买: +操作刚好相反 + +策略最大的风险就是单边行情, 价格波动超出网格范围. + +网格带有自动止损和移动功能 + + +参数 默认值 描述 +------------------ ----- ------------------ +OpType 0 网格方向: 先买后卖|先卖后买 +FirstPriceAuto true 首价格自动 +FirstPrice 100 首价格 +AllNum 10 总数量 +PriceGrid true 价格间隔 +PriceDiff 2 价差(元) +AmountType 0 订单大小: 买卖同量|自定义量 +AmountOnce 0.1 单笔数量 +BAmountOnce 0.1 买单大小 +SAmountOnce 0.1 卖单大小 +AmountCoefficient *1 量差 +AmountDot 3 量小数点最长位数 +EnableProtectDiff false 开启价差保护 +ProtectDiff 20 入市价差保护 +CancelAllWS true 停止时取消所有挂单 +CheckInterval 2000 轮询间隔 +Interval 1300 失败重试间隔 +RestoreProfit false 恢复上次盈利 +LastProfit false 上次盈利 +ProfitAsOrg false 上次盈利算入均价 +EnableAccountCheck true 启用资金检验 +EnableStopLoss false 开启止损 +StopLoss 100 最大浮动亏损(元) +StopLossMode 0 止损后操作: 回收并退出|回收再撒网 +EnableStopWin false 开启止盈 +StopWin 120 最大浮动盈利(元) +StopWinMode 0 止盈后操作: 回收并退出|回收再撒网 +AutoMove false 自动移动 +MaxDistance 20 最大距离(元) +MaxIdle 7200 最大空闲(秒) +EnableDynamic false 开启动态挂单 +DynamicMax 30 订单失效距离(元) +ResetData true 启动时清空所有数据 +Precision 5 价格小数位长度 + +按钮 默认值 描述 +---- ---------- ---------- +收网 __button__ 停止并平衡到初始状态 +*/ + +function hasOrder(orders, orderId) { + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == orderId) { + return true; + } + } + return false; +} + + +function cancelPending() { + var ret = false; + while (true) { + if (ret) { + Sleep(Interval); + } + var orders = _C(exchange.GetOrders); + if (orders.length == 0) { + break; + } + + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]); + ret = true; + } + } + return ret; +} + +function valuesToString(values, pos) { + var result = ''; + if (typeof(pos) === 'undefined') { + pos = 0; + } + for (var i = pos; i < values.length; i++) { + if (i > pos) { + result += ' '; + } + if (values[i] === null) { + result += 'null'; + } else if (typeof(values[i]) == 'undefined') { + result += 'undefined'; + } else { + switch (values[i].constructor.name) { + case 'Date': + case 'Number': + case 'String': + case 'Function': + result += values[i].toString(); + break; + default: + result += JSON.stringify(values[i]); + break; + } + } + } + return result; +} + +function Trader() { + var vId = 0; + var orderBooks = []; + var hisBooks = []; + var orderBooksLen = 0; + this.Buy = function(price, amount, extra) { + if (typeof(extra) === 'undefined') { + extra = ''; + } else { + extra = valuesToString(arguments, 2); + } + vId++; + var orderId = "V" + vId; + orderBooks[orderId] = { + Type: ORDER_TYPE_BUY, + Status: ORDER_STATE_PENDING, + Id: 0, + Price: price, + Amount: amount, + Extra: extra + }; + orderBooksLen++; + return orderId; + }; + this.Sell = function(price, amount, extra) { + if (typeof(extra) === 'undefined') { + extra = ''; + } else { + extra = valuesToString(arguments, 2); + } + vId++; + var orderId = "V" + vId; + orderBooks[orderId] = { + Type: ORDER_TYPE_SELL, + Status: ORDER_STATE_PENDING, + Id: 0, + Price: price, + Amount: amount, + Extra: extra + }; + orderBooksLen++; + return orderId; + }; + this.GetOrders = function() { + var orders = _C(exchange.GetOrders); + for (orderId in orderBooks) { + var order = orderBooks[orderId]; + if (order.Status !== ORDER_STATE_PENDING) { + continue; + } + var found = false; + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == order.Id) { + found = true; + break; + } + } + if (!found) { + orders.push(orderBooks[orderId]); + } + } + return orders; + } + this.GetOrder = function(orderId) { + if (typeof(orderId) === 'number') { + return exchange.GetOrder(orderId); + } + if (typeof(hisBooks[orderId]) !== 'undefined') { + return hisBooks[orderId]; + } + if (typeof(orderBooks[orderId]) !== 'undefined') { + return orderBooks[orderId]; + } + return null; + }; + this.Len = function() { + return orderBooksLen; + }; + this.RealLen = function() { + var n = 0; + for (orderId in orderBooks) { + if (orderBooks[orderId].Id > 0) { + n++; + } + } + return n; + }; + this.Poll = function(ticker, priceDiff) { + var orders = _C(exchange.GetOrders); + for (orderId in orderBooks) { + var order = orderBooks[orderId]; + if (order.Id > 0) { + var found = false; + for (var i = 0; i < orders.length; i++) { + if (order.Id == orders[i].Id) { + found = true; + } + } + if (!found) { + order.Status = ORDER_STATE_CLOSED; + hisBooks[orderId] = order; + delete(orderBooks[orderId]); + orderBooksLen--; + continue; + } + } + var diff = _N(order.Type == ORDER_TYPE_BUY ? (ticker.Buy - order.Price) : (order.Price - ticker.Sell)); + var pfn = order.Type == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell; + if (order.Id == 0 && diff <= priceDiff) { + var realId = pfn(order.Price, order.Amount, order.Extra + "(距离: " + diff + (order.Type == ORDER_TYPE_BUY ? (" 买一: " + ticker.Buy) : (" 卖一: " + ticker.Sell))+")"); + if (typeof(realId) === 'number') { + order.Id = realId; + } + } else if (order.Id > 0 && diff > (priceDiff + 1)) { + var ok = true; + do { + ok = true; + exchange.CancelOrder(order.Id, "不必要的" + (order.Type == ORDER_TYPE_BUY ? "买单" : "卖单"), "委托价:", order.Price, "量:", order.Amount, ", 距离:", diff, order.Type == ORDER_TYPE_BUY ? ("买一: " + ticker.Buy) : ("卖一: " + ticker.Sell)); + Sleep(200); + orders = _C(exchange.GetOrders); + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == order.Id) { + ok = false; + } + } + } while (!ok); + order.Id = 0; + } + } + }; +} + +function balanceAccount(orgAccount, initAccount) { + cancelPending(); + var nowAccount = _C(exchange.GetAccount); + var slidePrice = 0.2; + var ok = true; + while (true) { + var diff = _N(nowAccount.Stocks - initAccount.Stocks); + if (Math.abs(diff) < exchange.GetMinStock()) { + break; + } + var depth = _C(exchange.GetDepth); + var books = diff > 0 ? depth.Bids : depth.Asks; + var n = 0; + var price = 0; + for (var i = 0; i < books.length; i++) { + n += books[i].Amount; + if (n >= Math.abs(diff)) { + price = books[i].Price; + break; + } + } + var pfn = diff > 0 ? exchange.Sell : exchange.Buy; + var amount = Math.abs(diff); + var price = diff > 0 ? (price - slidePrice) : (price + slidePrice); + Log("开始平衡", (diff > 0 ? "卖出" : "买入"), amount, "个币"); + if (diff > 0) { + amount = Math.min(nowAccount.Stocks, amount); + } else { + amount = Math.min(nowAccount.Balance / price, amount); + } + if (amount < exchange.GetMinStock()) { + Log("资金不足, 无法平衡到初始状态"); + ok = false; + break; + } + pfn(price, amount); + Sleep(1000); + cancelPending(); + nowAccount = _C(exchange.GetAccount); + } + if (ok) { + LogProfit(_N(nowAccount.Balance - orgAccount.Balance)); + Log("平衡完成", nowAccount); + } +} + +var STATE_WAIT_OPEN = 0; +var STATE_WAIT_COVER = 1; +var STATE_WAIT_CLOSE = 2; +var ProfitCount = 0; +var BuyFirst = true; +var IsSupportGetOrder = true; +var LastBusy = 0; + +function setBusy() { + LastBusy = new Date(); +} + +function isTimeout() { + if (MaxIdle <= 0) { + return false; + } + var now = new Date(); + if (((now.getTime() - LastBusy.getTime()) / 1000) >= MaxIdle) { + LastBusy = now; + return true; + } + return false; +} + +function onexit() { + if (CancelAllWS) { + Log("正在退出, 尝试取消所有挂单"); + cancelPending(); + } + Log("策略成功停止"); + Log(_C(exchange.GetAccount)); +} + + +function fishing(orgAccount, fishCount) { + setBusy(); + var account = _C(exchange.GetAccount); + Log(account); + var InitAccount = account; + var ticker = _C(exchange.GetTicker); + var amount = _N(AmountOnce); + var amountB = [amount]; + var amountS = [amount]; + if (typeof(AmountType) !== 'undefined' && AmountType == 1) { + for (var idx = 0; idx < AllNum; idx++) { + amountB[idx] = BAmountOnce; + amountS[idx] = SAmountOnce; + } + } else { + for (var idx = 1; idx < AllNum; idx++) { + switch (AmountCoefficient[0]) { + case '+': + amountB[idx] = amountB[idx - 1] + parseFloat(AmountCoefficient.substring(1)); + break; + case '-': + amountB[idx] = amountB[idx - 1] - parseFloat(AmountCoefficient.substring(1)); + break; + case '*': + amountB[idx] = amountB[idx - 1] * parseFloat(AmountCoefficient.substring(1)); + break; + case '/': + amountB[idx] = amountB[idx - 1] / parseFloat(AmountCoefficient.substring(1)); + break; + } + amountB[idx] = _N(amountB[idx], AmountDot); + amountS[idx] = amountB[idx]; + } + } + if (FirstPriceAuto) { + FirstPrice = BuyFirst ? _N(ticker.Buy - PriceGrid, Precision) : _N(ticker.Sell + PriceGrid, Precision); + } + // Initialize fish table + var fishTable = {}; + var uuidTable = {}; + var needStocks = 0; + var needMoney = 0; + var actualNeedMoney = 0; + var actualNeedStocks = 0; + var notEnough = false; + var canNum = 0; + for (var idx = 0; idx < AllNum; idx++) { + var price = _N((BuyFirst ? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)), Precision); + needStocks += amountS[idx]; + needMoney += price * amountB[idx]; + if (BuyFirst) { + if (_N(needMoney) <= _N(account.Balance)) { + actualNeedMondy = needMoney; + actualNeedStocks = needStocks; + canNum++; + } else { + notEnough = true; + } + } else { + if (_N(needStocks) <= _N(account.Stocks)) { + actualNeedMondy = needMoney; + actualNeedStocks = needStocks; + canNum++; + } else { + notEnough = true; + } + } + fishTable[idx] = STATE_WAIT_OPEN; + uuidTable[idx] = -1; + } + if (!EnableAccountCheck && (canNum < AllNum)) { + Log("警告, 当前资金只可做", canNum, "个网格, 全网共需", (BuyFirst ? needMoney : needStocks), "请保持资金充足"); + canNum = AllNum; + } + if (BuyFirst) { + if (EnableProtectDiff && (FirstPrice - ticker.Sell) > ProtectDiff) { + throw "首次买入价比市场卖1价高" + _N(FirstPrice - ticker.Sell, Precision) + ' 元'; + } else if (EnableAccountCheck && account.Balance < _N(needMoney)) { + if (fishCount == 1) { + throw "资金不足, 需要" + _N(needMoney) + "元"; + } else { + Log("资金不足, 需要", _N(needMoney), "元, 程序只做", canNum, "个网格 #ff0000"); + } + } else { + Log('预计动用资金: ', _N(needMoney), "元"); + } + } else { + if (EnableProtectDiff && (ticker.Buy - FirstPrice) > ProtectDiff) { + throw "首次卖出价比市场买1价高 " + _N(ticker.Buy - FirstPrice, Precision) + ' 元'; + } else if (EnableAccountCheck && account.Stocks < _N(needStocks)) { + if (fishCount == 1) { + throw "币数不足, 需要 " + _N(needStocks) + " 个币"; + } else { + Log("资金不足, 需要", _N(needStocks), "个币, 程序只做", canNum, "个网格 #ff0000"); + } + } else { + Log('预计动用币数: ', _N(needStocks), "个, 约", _N(needMoney), "元"); + } + } + + var trader = new Trader(); + var OpenFunc = BuyFirst ? exchange.Buy : exchange.Sell; + var CoverFunc = BuyFirst ? exchange.Sell : exchange.Buy; + if (EnableDynamic) { + OpenFunc = BuyFirst ? trader.Buy : trader.Sell; + CoverFunc = BuyFirst ? trader.Sell : trader.Buy; + } + var ts = new Date(); + var preMsg = ""; + var profitMax = 0; + while (true) { + var now = new Date(); + var table = null; + if (now.getTime() - ts.getTime() > 5000) { + if (typeof(GetCommand) == 'function' && GetCommand() == "收网") { + Log("开始执行命令进行收网操作"); + balanceAccount(orgAccount, InitAccount); + return false; + } + ts = now; + var nowAccount = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + if (EnableDynamic) { + trader.Poll(ticker, DynamicMax); + } + var amount_diff = (nowAccount.Stocks + nowAccount.FrozenStocks) - (InitAccount.Stocks + InitAccount.FrozenStocks); + var money_diff = (nowAccount.Balance + nowAccount.FrozenBalance) - (InitAccount.Balance + InitAccount.FrozenBalance); + var floatProfit = _N(money_diff + (amount_diff * ticker.Last)); + var floatProfitAll = _N((nowAccount.Balance + nowAccount.FrozenBalance - orgAccount.Balance - orgAccount.FrozenBalance) + ((nowAccount.Stocks + nowAccount.FrozenStocks - orgAccount.Stocks - orgAccount.FrozenStocks) * ticker.Last)); + var isHold = Math.abs(amount_diff) >= exchange.GetMinStock(); + if (isHold) { + setBusy(); + } + + profitMax = Math.max(floatProfit, profitMax); + if (EnableAccountCheck && EnableStopLoss) { + if ((profitMax - floatProfit) >= StopLoss) { + Log("当前浮动盈亏", floatProfit, "利润最高点: ", profitMax, "开始止损"); + balanceAccount(orgAccount, InitAccount); + if (StopLossMode == 0) { + throw "止损退出"; + } else { + return true; + } + } + } + if (EnableAccountCheck && EnableStopWin) { + if (floatProfit > StopWin) { + Log("当前浮动盈亏", floatProfit, "开始止盈"); + balanceAccount(orgAccount, InitAccount); + if (StopWinMode == 0) { + throw "止盈退出"; + } else { + return true; + } + } + } + var distance = 0; + if (EnableAccountCheck && AutoMove) { + if (BuyFirst) { + distance = ticker.Last - FirstPrice; + } else { + distance = FirstPrice - ticker.Last; + } + var refish = false; + if (!isHold && isTimeout()) { + Log("空仓过久, 开始移动网格"); + refish = true; + } + if (distance > MaxDistance) { + Log("价格超出网格区间过多, 开始移动网格, 当前距离: ", _N(distance, Precision), "当前价格:", ticker.Last); + refish = true; + } + if (refish) { + balanceAccount(orgAccount, InitAccount); + return true; + } + } + + var holdDirection, holdAmount = "--", + holdPrice = "--"; + if (isHold) { + if (RestoreProfit && ProfitAsOrg) { + if (BuyFirst) { + money_diff += LastProfit; + } else { + money_diff -= LastProfit; + } + } + holdAmount = amount_diff; + holdPrice = (-money_diff) / amount_diff; + if (!BuyFirst) { + holdAmount = -amount_diff; + holdPrice = (money_diff) / -amount_diff; + } + holdAmount = _N(holdAmount, 4); + holdPrice = _N(holdPrice, Precision); + holdDirection = BuyFirst ? "多" : "空"; + } else { + holdDirection = "--"; + } + table = { + type: 'table', + title: '运行状态', + cols: ['动用资金', '持有仓位', '持仓大小', '持仓均价', '总浮动盈亏', '当前网格盈亏', '撒网次数', '网格偏移', '真实委托', '最新币价'], + rows: [ + [_N(actualNeedMondy, 4), holdDirection, holdAmount, holdPrice, _N(floatProfitAll, 4) + ' ( ' + _N(floatProfitAll * 100 / actualNeedMondy, 4) + ' % )', floatProfit, fishCount, (AutoMove && distance > 0) ? ((BuyFirst ? "向上" : "向下") + "偏离: " + _N(distance) + " 元") : "--", trader.RealLen(), ticker.Last] + ] + }; + + } + var orders = _C(trader.GetOrders); + if (table) { + if (!EnableDynamic) { + table.rows[0][8] = orders.length; + } + LogStatus('`' + JSON.stringify(table) + '`'); + } + for (var idx = 0; idx < canNum; idx++) { + var openPrice = _N((BuyFirst ? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)), Precision); + var coverPrice = _N((BuyFirst ? openPrice + PriceDiff : openPrice - PriceDiff), Precision); + var state = fishTable[idx]; + var fishId = uuidTable[idx]; + if (hasOrder(orders, fishId)) { + continue; + } + + if (fishId != -1 && IsSupportGetOrder) { + var order = trader.GetOrder(fishId); + if (!order) { + Log("获取订单信息失败, ID: ", fishId); + continue; + } + if (order.Status == ORDER_STATE_PENDING) { + //Log("订单状态为未完成, ID: ", fishId); + continue; + } + } + + if (state == STATE_WAIT_COVER) { + var coverId = CoverFunc(coverPrice, (BuyFirst ? amountS[idx] : amountB[idx]), (BuyFirst ? '完成买单:' : '完成卖单:'), openPrice, '量:', (BuyFirst ? amountB[idx] : amountS[idx])); + if (typeof(coverId) === 'number' || typeof(coverId) === 'string') { + fishTable[idx] = STATE_WAIT_CLOSE; + uuidTable[idx] = coverId; + } + } else if (state == STATE_WAIT_OPEN || state == STATE_WAIT_CLOSE) { + var openId = OpenFunc(openPrice, BuyFirst ? amountB[idx] : amountS[idx]); + if (typeof(openId) === 'number' || typeof(openId) === 'string') { + fishTable[idx] = STATE_WAIT_COVER; + uuidTable[idx] = openId; + if (state == STATE_WAIT_CLOSE) { + ProfitCount++; + var account = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + var initNet = _N(((InitAccount.Stocks + InitAccount.FrozenStocks) * ticker.Buy) + InitAccount.Balance + InitAccount.FrozenBalance, 8); + var nowNet = _N(((account.Stocks + account.FrozenStocks) * ticker.Buy) + account.Balance + account.FrozenBalance, 8); + var actualProfit = _N(((nowNet - initNet)) * 100 / initNet, 8); + if (AmountType == 0) { + var profit = _N((ProfitCount * amount * PriceDiff) + LastProfit, 8); + Log((BuyFirst ? '完成卖单:' : '完成买单:'), coverPrice, '量:', (BuyFirst ? amountS[idx] : amountB[idx]), '平仓收益', profit); + } else { + Log((BuyFirst ? '完成卖单:' : '完成买单:'), coverPrice, '量:', (BuyFirst ? amountS[idx] : amountB[idx])); + } + } + } + } + } + Sleep(CheckInterval); + } + return true; +} + +function main() { + if (ResetData) { + LogProfitReset(); + LogReset(); + } + exchange.SetMaxDigits(Precision) + if (typeof(AmountType) === 'undefined') { + AmountType = 0; + } + if (typeof(AmountDot) === 'undefined') { + AmountDot = 3; + } + if (typeof(EnableDynamic) === 'undefined') { + EnableDynamic = false; + } + if (typeof(AmountCoefficient) === 'undefined') { + AmountCoefficient = "*1"; + } + if (typeof(EnableAccountCheck) === 'undefined') { + EnableAccountCheck = true; + } + BuyFirst = (OpType == 0); + IsSupportGetOrder = exchange.GetName().indexOf('itstamp') == -1; + if (!IsSupportGetOrder) { + Log(exchange.GetName(), "不支持GetOrder, 可能影响策略稳定性."); + } + + SetErrorFilter("502:|503:|S_U_001|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|refused|EOF|When"); + + exchange.SetRate(1); + Log('已经禁用汇率转换, 当前货币为', exchange.GetBaseCurrency()); + + if (!RestoreProfit) { + LastProfit = 0; + } + + var orgAccount = _C(exchange.GetAccount); + var fishCount = 1; + while (true) { + if (!fishing(orgAccount, fishCount)) { + break; + } + fishCount++; + Log("第", fishCount, "次重新撒网..."); + FirstPriceAuto = true; + Sleep(1000); + } +} diff --git "a/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.js" "b/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.js" index 16ab1dc8..59a6744d 100644 --- "a/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.js" +++ "b/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.js" @@ -1,7 +1,7 @@ /* 策略出处: https://www.botvs.com/strategy/8916 策略名称: 记录净资产变动情况2.0 -策略作者: 青铜战国级机器人 +策略作者: 中本姜(青铜机器人) 策略描述: 说明 diff --git "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277 (Copy).js" "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277 (Copy).js" deleted file mode 100644 index e80d78ea..00000000 --- "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277 (Copy).js" +++ /dev/null @@ -1,305 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/41741 -策略名称: 转换任意K线周期管理模板 (Copy) -策略作者: 779335834 -策略描述: - -1. 修改自小小梦的"转换任意K线周期" 模板 - -原理: - - 获得固定K线的周期,然后合成任意固定K线整数倍的新K线周期 - -功能: - - 转换基础K线为任意K线周期 - - 暂时不支持 秒级别 - -限制: - - 新K线周期必须是固定K线周期的整数倍. - - 固定K线周期为1min, 3min, 5min, 15min, 30min, 新K线周期也必须是分钟且<60 - - 固定K线周期为1hour, 新K线周期也必须是小时且<24 - - 固定K线周期为1day, 新K线周期也必须是天 - - 每次获得的固定K线周期数目必须>=2 -测试版本,如有BUG ,问题 欢迎留言。 - -输出函数: - $.RecordsManager(NewCycleMS) 生成新周期管理器, NewCycleMS 为新K线周期毫秒数. 默认(1000*60*60*2) 2hour. - $.AssembleRecords(records, BaseCycleMS) 通过原records生成新的K线的records, BaseCycleMS 为固定K线周期毫秒,默认用固定records进行计算 - $.GetRecordsTable(n) 得到新K线最新的N个条目, 默认输出所有条目, 输出为table类型,便于LogStatus输出 - $.Get***** 获得一些基本信息 - - -参数 默认值 描述 ----------------- ------------ ------- -UI_NewCycleForMS 1000*60*60*2 合成周期毫秒数 -*/ - -/*backtest - period: 60 - */ -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; -}; - -var DAY = 0; -var HOURS = 1; -var MINUTES = 2; - -function GetDHM(objTime, BaseCycle, NewCycleForMS){ - var ret = []; - if(BaseCycle % (1000 * 60 * 60 * 24) === 0){ - ret[0] = objTime.getDate(); - ret[1] = DAY; - }else if(BaseCycle % (1000 * 60 * 60) === 0){ - ret[0] = objTime.getHours(); - ret[1] = HOURS; - }else if(BaseCycle % (1000 * 60) === 0){ - ret[0] = objTime.getMinutes(); - ret[1] = MINUTES; - } - if(NewCycleForMS % (1000 * 60 * 60 * 24) === 0){ - ret[2] = DAY; - }else if(NewCycleForMS % (1000 * 60 * 60) === 0){ - ret[2] = HOURS; - }else if(NewCycleForMS % (1000 * 60) === 0){ - ret[2] = MINUTES; - } - return ret; -} - -function SearchFirstTime(ret, BaseCycle, NewCycleForMS){ - if(ret[1] === DAY && ret[2] === DAY){ - var array_day = []; - for(var i = 1 ; i < 29; i += (NewCycleForMS / BaseCycle)){ - array_day.push(i); - } - for(var j = 0 ; j < array_day.length; j++ ){ - if(ret[0] === array_day[j]){ - return true; - } - } - }else if(ret[1] === HOURS && ret[2] === HOURS){ - var array_hours = []; - for(var i = 0 ; i < 24; i += (NewCycleForMS / BaseCycle)){ - array_hours.push(i); - } - for(var j = 0 ; j < array_hours.length ; j++){ - if(ret[0] === array_hours[j]){ - return true; - } - } - }else if(ret[1] === MINUTES && ret[2] === MINUTES){ - var array_minutes = []; - for(var i = 0; i < 60; i += (NewCycleForMS / BaseCycle)){ - array_minutes.push(i); - } - for(var j = 0; j < array_minutes.length; j++){ - if(ret[0] === array_minutes[j]){ - return true; - } - } - }else{ - throw "目标周期与基础周期不匹配!目标周期毫秒数:" + NewCycleForMS + " 基础周期毫秒数: " + BaseCycle; - } -} - -function Calc_High(AssRecords, n, BaseCycle, NewCycleForMS){ - var max = AssRecords[n].High; - for(var i = 1 ; i < NewCycleForMS / BaseCycle; i++){ - max = Math.max(AssRecords[n + i].High, max); - } - return max; -} - -function Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS){ - var min = AssRecords[n].Low; - for(var i = 1 ; i < NewCycleForMS / BaseCycle; i++){ - min = Math.min(AssRecords[n + i].Low, min); - } - return min; -} - -function _RecordsManager(NewCycleForMS) { - if (typeof NewCycleForMS == 'string') { - this._NewCycleForMS = 1; - var arrayNum = NewCycleForMS.split("*"); - for(var indexNum = 0 ; indexNum < arrayNum.length ; indexNum++){ - this._NewCycleForMS = this._NewCycleForMS * Number(arrayNum[indexNum]); - } - } else { - this._NewCycleForMS = NewCycleForMS; - } - - this._Records = new Array(); - - this.GetNewCycleForMS = function() { - return this._NewCycleForMS; - }; - - this.AssembleRecords = function(records, BaseCycle) { - var NewCycleForMS = this._NewCycleForMS; - var AssRecords = records.slice(0); // 深拷贝 - var AfterAssRecords = []; - - if (!records || records.length == 0) { - Log("record 为空!"); - return records; - } - if(records.length < 2){ - throw (!records) ? "传入的records参数为 错误" + records : "基础K线长度小于2"; - } - if (typeof BaseCycle === 'undefined') { - BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time; - } - if(NewCycleForMS % BaseCycle !== 0){ - throw "目标周期‘" + NewCycleForMS + "’不是 基础周期 ‘" + BaseCycle + "’ 的整倍数,无法合成!"; - } - if(NewCycleForMS / BaseCycle > records.length){ - Log("records: ", records, "NewCycleForMS: ", NewCycleForMS, ", BaseCycle: ", BaseCycle); - throw "基础K线数量不足,请检查是否基础K线周期过小!"; - } - - // 判断时间戳, 找到 基础K线 相对于 目标K线的起始时间。 - var objTime = new Date(); - var isFirstFind = true; - var FirstStamp = null; - for (var i = 0; i < AssRecords.length; i++) { - objTime.setTime(AssRecords[i].Time); - var ret = GetDHM(objTime, BaseCycle, NewCycleForMS); - - if (isFirstFind === true && SearchFirstTime(ret, BaseCycle, NewCycleForMS) === true) { - FirstStamp = AssRecords[i].Time; - for (j = 0; j < i; j++) { - AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。 - } - isFirstFind = false; - break; // 排除后跳出 - }else if(isFirstFind === false){ - if((AssRecords[i].Time - FirstStamp) % NewCycleForMS === 0){ - for (j = 0; j < i; j++) { - AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。 - } - break; - } - } - } - var BarObj = { // 定义一个 K线柱结构 - Time: 0, - Open: 0, - High: 0, - Low: 0, - Close: 0, - Volume: 0, - }; - var n = 0; - for (n = 0; n < AssRecords.length - (NewCycleForMS / BaseCycle); n += (NewCycleForMS / BaseCycle)) { // 合成 - /* - { - Time :一个时间戳, 精确到毫秒,与Javascript的 new Date().getTime() 得到的结果格式一样 - Open :开盘价 - High :最高价 - Low :最低价 - Close :收盘价 - Volume :交易量 - } - */ - BarObj.Time = AssRecords[n].Time; - BarObj.Open = AssRecords[n].Open; - BarObj.High = Calc_High(AssRecords, n, BaseCycle, NewCycleForMS); - BarObj.Low = Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS); - BarObj.Close = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Close; - BarObj.Volume = 0; - for (var j = n; j < n + (NewCycleForMS / BaseCycle); j++) { - BarObj.Volume += AssRecords[j].Volume; - } - AfterAssRecords.push(cloneObj(BarObj)); - } - - BarObj.Time = AssRecords[Math.max(n - (NewCycleForMS / BaseCycle), 0)].Time + NewCycleForMS; // 最后一根时间不能变, - BarObj.Open = AssRecords[n].Open; - BarObj.Close = AssRecords[AssRecords.length - 1].Close; - BarObj.Volume = 0; - var max = AssRecords[n].High; - var min = AssRecords[n].Low; - for(var index_n = n + 1 ;index_n < AssRecords.length; index_n++){ - max = Math.max(max, AssRecords[index_n].High); - min = Math.min(min, AssRecords[index_n].Low); - BarObj.Volume += AssRecords[index_n].Volume; - } - BarObj.High = max; - BarObj.Low = min; - AfterAssRecords.push(cloneObj(BarObj)); - - this._Records = AfterAssRecords; - return AfterAssRecords; - }; - - this.GetKlineName = function () { - return " " + this._NewCycleForMS / 60 / 1000 + " 分钟K线"; - }; - - /* 获得records数据表格*/ - this.GetRecordsTable = function (n) { - if (typeof n !== 'undefined' && n >=0 ) { - var records = this._Records.slice(-n); - } else { - var records = this._Records.slice(0); - } - - var record_array = new Array(); - for (var i = records.length - 1; i >= 0; i--) { - var newDate = new Date(); - newDate.setTime(records[i].Time); - var time_str = newDate.toLocaleString(); - record_array.push([time_str, records[i].Open, records[i].Close, - records[i].High, records[i].Low, records[i].Volume]); - } - var title = this.GetKlineName() + "(" + records.length + "根)"; - var table = {type: 'table', title: title, - cols: ['Time', 'Open','Close', 'High', 'Low', 'Volume'], - rows: record_array}; - return table; - } -} - -$.RecordsManager = function (NewCycleForMS) { - - if (typeof NewCycleForMS === 'undefined') { - NewCycleForMS = UI_NewCycleForMS; - } - var RecordsManager = new _RecordsManager(NewCycleForMS); - return RecordsManager; -} - -function main() { - var records = exchange.GetRecords(); - while (!records || records.length < 24) { - records = exchange.GetRecords(); - Sleep(1000); - } - - while (true) { - records = _C(exchange.GetRecords); - record_manager0 = $.RecordsManager(); - new_records0 = record_manager0.AssembleRecords(records); - var table0 = record_manager0.GetRecordsTable(); - - var BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time; - record_manager1 = $.RecordsManager(BaseCycle); - new_records1 = record_manager1.AssembleRecords(records); - var table1 = record_manager1.GetRecordsTable(); - LogStatus('`' + JSON.stringify([table0, table1]) +'`'); - Sleep(1000); - } -} diff --git "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170531) (Copy).js" "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170531) (Copy).js" deleted file mode 100644 index c03fb3c8..00000000 --- "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170531) (Copy).js" +++ /dev/null @@ -1,315 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/43082 -策略名称: 转换任意K线周期管理模板(最近更新20170531) (Copy) -策略作者: guangming -策略描述: - -更新于20170531 - a. fix Volume计算错误 - -1. 修改自小小梦的"转换任意K线周期" 模板 - -原理: - - 获得固定K线的周期,然后合成任意固定K线整数倍的新K线周期 - -功能: - - 转换基础K线为任意K线周期 - - 暂时不支持 秒级别 - -限制: - - 新K线周期必须是固定K线周期的整数倍. - - 固定K线周期为1min, 3min, 5min, 15min, 30min, 新K线周期也必须是分钟且<60 - - 固定K线周期为1hour, 新K线周期也必须是小时且<24 - - 固定K线周期为1day, 新K线周期也必须是天 - - 每次获得的固定K线周期数目必须>=2 -测试版本,如有BUG ,问题 欢迎留言。 - -输出函数: - $.RecordsManager(NewCycleMS) 生成新周期管理器, NewCycleMS 为新K线周期毫秒数. 默认(1000*60*60*2) 2hour. - $.AssembleRecords(records, BaseCycleMS) 通过原records生成新的K线的records, BaseCycleMS 为固定K线周期毫秒,默认用固定records进行计算 - $.GetRecordsTable(n) 得到新K线最新的N个条目, 默认输出所有条目, 输出为table类型,便于LogStatus输出 - $.Get***** 获得一些基本信息 - - -参数 默认值 描述 ----------------- ------------ ------- -UI_NewCycleForMS 1000*60*60*2 合成周期毫秒数 -*/ - -/*backtest - period: 60 - */ -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; -}; - -var DAY = 0; -var HOURS = 1; -var MINUTES = 2; - -function GetDHM(objTime, BaseCycle, NewCycleForMS){ - var ret = []; - if(BaseCycle % (1000 * 60 * 60 * 24) === 0){ - ret[0] = objTime.getDate(); - ret[1] = DAY; - }else if(BaseCycle % (1000 * 60 * 60) === 0){ - ret[0] = objTime.getHours(); - ret[1] = HOURS; - }else if(BaseCycle % (1000 * 60) === 0){ - ret[0] = objTime.getMinutes(); - ret[1] = MINUTES; - } - if(NewCycleForMS % (1000 * 60 * 60 * 24) === 0){ - ret[2] = DAY; - }else if(NewCycleForMS % (1000 * 60 * 60) === 0){ - ret[2] = HOURS; - }else if(NewCycleForMS % (1000 * 60) === 0){ - ret[2] = MINUTES; - } - return ret; -} - -function SearchFirstTime(ret, BaseCycle, NewCycleForMS){ - if(ret[1] === DAY && ret[2] === DAY){ - var array_day = []; - for(var i = 1 ; i < 29; i += (NewCycleForMS / BaseCycle)){ - array_day.push(i); - } - for(var j = 0 ; j < array_day.length; j++ ){ - if(ret[0] === array_day[j]){ - return true; - } - } - }else if(ret[1] === HOURS && ret[2] === HOURS){ - var array_hours = []; - for(var i = 0 ; i < 24; i += (NewCycleForMS / BaseCycle)){ - array_hours.push(i); - } - for(var j = 0 ; j < array_hours.length ; j++){ - if(ret[0] === array_hours[j]){ - return true; - } - } - }else if(ret[1] === MINUTES && ret[2] === MINUTES){ - var array_minutes = []; - for(var i = 0; i < 60; i += (NewCycleForMS / BaseCycle)){ - array_minutes.push(i); - } - for(var j = 0; j < array_minutes.length; j++){ - if(ret[0] === array_minutes[j]){ - return true; - } - } - }else{ - throw "目标周期与基础周期不匹配!目标周期毫秒数:" + NewCycleForMS + " 基础周期毫秒数: " + BaseCycle; - } -} - -function Calc_High(AssRecords, n, BaseCycle, NewCycleForMS){ - var max = AssRecords[n].High; - for(var i = 1 ; i < NewCycleForMS / BaseCycle; i++){ - max = Math.max(AssRecords[n + i].High, max); - } - return max; -} - -function Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS){ - var min = AssRecords[n].Low; - for(var i = 1 ; i < NewCycleForMS / BaseCycle; i++){ - min = Math.min(AssRecords[n + i].Low, min); - } - return min; -} - -function _RecordsManager(NewCycleForMS) { - if (typeof NewCycleForMS == 'string') { - this._NewCycleForMS = 1; - var arrayNum = NewCycleForMS.split("*"); - for(var indexNum = 0 ; indexNum < arrayNum.length ; indexNum++){ - this._NewCycleForMS = this._NewCycleForMS * Number(arrayNum[indexNum]); - } - } else { - this._NewCycleForMS = NewCycleForMS; - } - - this._Records = new Array(); - - this.GetNewCycleForMS = function() { - return this._NewCycleForMS; - }; - - this.GetRecords = function() { - return this._Records; - } - - this.AssembleRecords = function(records, BaseCycle) { - var NewCycleForMS = this._NewCycleForMS; - var AssRecords = records.slice(0); // 深拷贝 - var AfterAssRecords = []; - - if (!records || records.length == 0) { - Log("record 为空@!"); - return records; - } - if(records.length < 2){ - throw (!records) ? "传入的records参数为 错误" + records : "基础K线长度小于2"; - } - if (typeof BaseCycle === 'undefined') { - BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time; - } - if(NewCycleForMS % BaseCycle !== 0){ - throw "目标周期‘" + NewCycleForMS + "’不是 基础周期 ‘" + BaseCycle + "’ 的整倍数,无法合成!"; - } - if(NewCycleForMS / BaseCycle > records.length){ - Log("records: ", records, "NewCycleForMS: ", NewCycleForMS, ", BaseCycle: ", BaseCycle); - throw "基础K线数量不足,请检查是否基础K线周期过小!"; - } - - // 判断时间戳, 找到 基础K线 相对于 目标K线的起始时间。 - var objTime = new Date(); - var isFirstFind = true; - var FirstStamp = null; - for (var i = 0; i < AssRecords.length; i++) { - objTime.setTime(AssRecords[i].Time); - var ret = GetDHM(objTime, BaseCycle, NewCycleForMS); - - if (isFirstFind === true && SearchFirstTime(ret, BaseCycle, NewCycleForMS) === true) { - FirstStamp = AssRecords[i].Time; - for (j = 0; j < i; j++) { - AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。 - } - isFirstFind = false; - break; // 排除后跳出 - }else if(isFirstFind === false){ - if((AssRecords[i].Time - FirstStamp) % NewCycleForMS === 0){ - for (j = 0; j < i; j++) { - AssRecords.shift(); // 把目标K线周期前不满足合成的数据排除。 - } - break; - } - } - } - var BarObj = { // 定义一个 K线柱结构 - Time: 0, - Open: 0, - High: 0, - Low: 0, - Close: 0, - Volume: 0, - }; - var n = 0; - for (n = 0; n < AssRecords.length - (NewCycleForMS / BaseCycle); n += (NewCycleForMS / BaseCycle)) { // 合成 - /* - { - Time :一个时间戳, 精确到毫秒,与Javascript的 new Date().getTime() 得到的结果格式一样 - Open :开盘价 - High :最高价 - Low :最低价 - Close :收盘价 - Volume :交易量 - } - */ - BarObj.Time = AssRecords[n].Time; - BarObj.Open = AssRecords[n].Open; - BarObj.High = Calc_High(AssRecords, n, BaseCycle, NewCycleForMS); - BarObj.Low = Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS); - BarObj.Close = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Close; - BarObj.Volume = 0; - for (var j = n; j < n + (NewCycleForMS / BaseCycle); j++) { - BarObj.Volume += AssRecords[j].Volume; - } - AfterAssRecords.push(cloneObj(BarObj)); - } - - BarObj.Time = AssRecords[Math.max(n - (NewCycleForMS / BaseCycle), 0)].Time + NewCycleForMS; // 最后一根时间不能变, - BarObj.Open = AssRecords[n].Open; - BarObj.Close = AssRecords[AssRecords.length - 1].Close; - BarObj.Volume = AssRecords[n].Volume; - //BarObj.Volume = 0; - var max = AssRecords[n].High; - var min = AssRecords[n].Low; - for(var index_n = n + 1 ;index_n < AssRecords.length; index_n++){ - max = Math.max(max, AssRecords[index_n].High); - min = Math.min(min, AssRecords[index_n].Low); - BarObj.Volume += AssRecords[index_n].Volume; - } - BarObj.High = max; - BarObj.Low = min; - AfterAssRecords.push(cloneObj(BarObj)); - - this._Records = AfterAssRecords; - return AfterAssRecords; - }; - - this.GetKlineName = function () { - return " " + this._NewCycleForMS / 60 / 1000 + " 分钟K线"; - }; - - /* 获得records数据表格*/ - this.GetRecordsTable = function (n) { - if (typeof n !== 'undefined' && n >=0 ) { - var records = this._Records.slice(-n); - } else { - var records = this._Records.slice(0); - } - - var record_array = new Array(); - for (var i = records.length - 1; i >= 0; i--) { - var newDate = new Date(); - newDate.setTime(records[i].Time); - var time_str = newDate.toLocaleString(); - record_array.push([time_str, records[i].Open, records[i].Close, - records[i].High, records[i].Low, records[i].Volume]); - } - var title = this.GetKlineName() + "(" + records.length + "根)"; - var table = {type: 'table', title: title, - cols: ['Time', 'Open','Close', 'High', 'Low', 'Volume'], - rows: record_array}; - return table; - } -} - -$.RecordsManager = function (NewCycleForMS) { - - if (typeof NewCycleForMS === 'undefined') { - NewCycleForMS = UI_NewCycleForMS; - } - var RecordsManager = new _RecordsManager(NewCycleForMS); - return RecordsManager; -} - -function main() { - var records = exchange.GetRecords(); - while (!records || records.length < 24) { - records = exchange.GetRecords(); - Sleep(1000); - } - - while (true) { - records = _C(exchange.GetRecords); - record_manager0 = $.RecordsManager(); - new_records0 = record_manager0.AssembleRecords(records); - var table0 = record_manager0.GetRecordsTable(); - - var BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time; - record_manager1 = $.RecordsManager(BaseCycle); - new_records1 = record_manager1.AssembleRecords(records); - var table1 = record_manager1.GetRecordsTable(); - LogStatus('`' + JSON.stringify([table0, table1]) +'`'); - records = record_manager1.GetRecords(); - //Log(records[records.length-1]); - Sleep(60000); - } -} diff --git "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170622).js" "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020171113).js" similarity index 78% rename from "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170622).js" rename to "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020171113).js" index 0a655f69..c955bdee 100644 --- "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020170622).js" +++ "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020171113).js" @@ -1,9 +1,14 @@ /* 策略出处: https://www.botvs.com/strategy/41163 -策略名称: 转换任意K线周期管理模板(最近更新20170622) -策略作者: 青铜战国级机器人 +策略名称: 转换任意K线周期管理模板(最近更新20171113) +策略作者: 中本姜(青铜机器人) 策略描述: +更新于20171114 + a. 解决Open找不到问题,是record数组访问越界造成的,访问越界是之前的K线有问题导致的。 +更新于20171113 + a. 过滤掉起始时间不正确的K线组合 + b. 过滤掉时间间隔不正确的K线组合 更新于20170622 a. RecordsManager 增加Name参数,便于区分不同的K线 b. Fix 当固定K线数目不满一根新K线周期时,Time计算不正确的问题 @@ -49,6 +54,58 @@ UI_NewCycleForMS 1000*60*60*2 合成周期毫秒数 /*backtest period: 60 */ +/* +更新于20171114 + a. 解决Open找不到问题,是record数组访问越界造成的,访问越界是之前的K线有问题导致的。 +更新于20171113 + a. 过滤掉起始时间不正确的k线组合 + b. 过滤掉时间间隔不正确的k线组合 +更新于20170622 + a. RecordsManager 增加Name参数,便于区分不同的K线 + b. Fix 当固定K线数目不满一根新K线周期时,Time计算不正确的问题 + +更新于20170531 + a. fix Volume计算错误 + +1. 修改自小小梦的"转换任意K线周期" 模板 + +原理: + - 获得固定K线的周期,然后合成任意固定K线整数倍的新K线周期 + +功能: + - 转换基础K线为任意K线周期 + - 暂时不支持 秒级别 + +限制: + - 新K线周期必须是固定K线周期的整数倍. + - 固定K线周期为1min, 3min, 5min, 15min, 30min, 新K线周期也必须是分钟且<60 + - 固定K线周期为1hour, 新K线周期也必须是小时且<24 + - 固定K线周期为1day, 新K线周期也必须是天 + - 每次获得的固定K线周期数目必须>=2 +测试版本,如有BUG ,问题 欢迎留言。 + +输出函数: + $.RecordsManager(NewCycleMS, Name) 生成新周期管理器 + NewCycleMS 为新K线周期毫秒数. 默认(1000*60*60*2) 2hour. + Name: 为该K线管理指定名字 + 返回K线管理器 + $.AssembleRecords(records, BaseCycleMS) + records: 拿到的原始records + BaseCycleMS 为固定K线周期毫秒,默认用固定records进行计算 + 返回新K线周期的records + $.GetRecordsTable(n) 得到新K线最新的N个条目, 默认输出所有条目, 输出为table类型,便于LogStatus输出 + $.Get***** 获得一些基本信息 +*/ +function EasyReadTime(millseconds) { + if (typeof millseconds == 'undefined' || + !millseconds) { + millseconds = new Date().getTime(); + } + var newDate = new Date(); + newDate.setTime(millseconds); + return newDate.toLocaleString(); +} + var cloneObj = function(obj) { // 深拷贝 对象函数 var str, newobj = obj.constructor === Array ? [] : {}; if (typeof obj !== 'object') { @@ -183,7 +240,8 @@ function _RecordsManager(NewCycleForMS, Name) { BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time; } if(NewCycleForMS % BaseCycle !== 0){ - throw "目标周期‘" + NewCycleForMS + "’不是 基础周期 ‘" + BaseCycle + "’ 的整倍数,无法合成!"; + Log("目标周期‘", NewCycleForMS, "’不是 基础周期 ‘", BaseCycle, "’ 的整倍数,无法合成!"); + return null; } if(NewCycleForMS / BaseCycle > records.length){ Log("records: ", records, "NewCycleForMS: ", NewCycleForMS, ", BaseCycle: ", BaseCycle); @@ -223,7 +281,7 @@ function _RecordsManager(NewCycleForMS, Name) { Volume: 0, }; var n = 0; - for (n = 0; n < AssRecords.length - (NewCycleForMS / BaseCycle); n += (NewCycleForMS / BaseCycle)) { // 合成 + for (n = 0; n < AssRecords.length - (NewCycleForMS / BaseCycle);) { // 合成 /* { Time :一个时间戳, 精确到毫秒,与Javascript的 new Date().getTime() 得到的结果格式一样 @@ -234,6 +292,22 @@ function _RecordsManager(NewCycleForMS, Name) { Volume :交易量 } */ + //时间判断 + var is_bad = false; + var start_time = AssRecords[n].Time; + var stop_time = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Time + BaseCycle; + if (start_time % NewCycleForMS != 0) { + //Log("过滤起始时间不正确的k线组合", EasyReadTime(start_time)); + is_bad = true; + } + if (stop_time - start_time != NewCycleForMS) { + //Log("过滤时间间隔不正确的k线组合", EasyReadTime(start_time), EasyReadTime(stop_time)); + is_bad=true; + } + if (is_bad) { + n++; + continue; + } BarObj.Time = AssRecords[n].Time; BarObj.Open = AssRecords[n].Open; BarObj.High = Calc_High(AssRecords, n, BaseCycle, NewCycleForMS); @@ -244,6 +318,7 @@ function _RecordsManager(NewCycleForMS, Name) { BarObj.Volume += AssRecords[j].Volume; } AfterAssRecords.push(cloneObj(BarObj)); + n += (NewCycleForMS / BaseCycle) } if (n == 0) { @@ -324,9 +399,10 @@ function main() { record_manager1 = $.RecordsManager(BaseCycle); new_records1 = record_manager1.AssembleRecords(records); var table1 = record_manager1.GetRecordsTable(); - LogStatus('`' + JSON.stringify([table0, table1]) +'`'); + LogStatus('`' + JSON.stringify([table0, table1, ""]) +'`'); records = record_manager1.GetRecords(); //Log(records[records.length-1]); Sleep(60000); } } + diff --git "a/\351\234\207\350\215\241\347\252\201\347\240\264\347\255\226\347\225\245 (\345\210\240\345\207\217B\345\200\274\350\247\246\345\217\221\345\271\263\344\273\223\343\200\201\345\212\250\346\200\201\350\260\203\346\225\264\350\247\246\345\217\221\345\200\274 \344\274\230\345\214\226ing) (\345\244\215\345\210\266)ttttttttt.js" "b/\351\234\207\350\215\241\347\252\201\347\240\264\347\255\226\347\225\245 (\345\210\240\345\207\217B\345\200\274\350\247\246\345\217\221\345\271\263\344\273\223\343\200\201\345\212\250\346\200\201\350\260\203\346\225\264\350\247\246\345\217\221\345\200\274 \344\274\230\345\214\226ing) (\345\244\215\345\210\266)ttttttttt.js" deleted file mode 100644 index aed79193..00000000 --- "a/\351\234\207\350\215\241\347\252\201\347\240\264\347\255\226\347\225\245 (\345\210\240\345\207\217B\345\200\274\350\247\246\345\217\221\345\271\263\344\273\223\343\200\201\345\212\250\346\200\201\350\260\203\346\225\264\350\247\246\345\217\221\345\200\274 \344\274\230\345\214\226ing) (\345\244\215\345\210\266)ttttttttt.js" +++ /dev/null @@ -1,532 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/23549 -策略名称: 震荡突破策略 (删减B值触发平仓、动态调整触发值 优化ing) (复制)ttttttttt -策略作者: 总值约: 23938.37 元 -策略描述: - -1、吃单优化为在触发值上挂单 -2、止损仓 在被套的情况下开启止损仓。 -3、动态阀值 -4、加入 STOCHRSI 指标 - - -参数 默认值 描述 ----------------- ----- ------------- -NPeriod 4 计算周期 -Ks 0.5 上轨系数 -Kx 0.5 下轨系数 -AmountOP true 开仓量 -Interval 2000 重试间隔(毫秒) -LoopInterval 3 轮询间隔(秒) -PeriodShow 500 图表最大显示K线柱数 -InitMoveStop -20 初始止损值 -step 5 滑动止损步长 -isShowTouchLine true 显示触发值 -isCurrentKLineOP true 是否允许当前K线平仓后交易 -*/ - -var ChartCfg = { - __isStock: true, - title: { - text: '震荡突破策略' - }, - yAxis: [{ - title: {text: 'KL'},//标题 - style: {color: '#4572A7'},//样式 - opposite: false, //生成右边Y轴 - plotLines: [{ - value: 0, - color: 'red', - width: 2, - label: { - text: '触发值A', - align: 'center' - }, - }, { - value: 0, - color: 'green', - width: 2, - label: { - text: '触发值B', - align: 'center' - }, - }] - }, - { - title:{text: "STOCHRSI"}, - opposite: true //生成右边Y轴 ceshi - } - ], - series: [{ - type: 'candlestick', - name: '当前周期', - id: 'primary', - data: [] - }, { - type: 'flags', - onSeries: 'primary', - data: [], - },{ - type: 'spline', - yAxis: 1, - name: 'F', - data: [] - },{ - type: 'spline', - yAxis: 1, - name: 'S', - data: [] - }] -}; - -/* -plotLines: [{ - value: 0, - color: 'red', - width: 2, - label: { - text: '触发值A', - align: 'center' - }, - }, { - value: 0, - color: 'green', - width: 2, - label: { - text: '触发值B', - align: 'center' - }, - }] -*/ -var STATE_IDLE = 0; -var STATE_LONG = 1; -var STATE_SHORT = 2; -var State = STATE_IDLE; - -var LastBarTime = 0; -var UpTrack = 0; -var BottomTrack = 0; -var chart = null; -var InitAccount = null; -var Counter = { - w: 0, - l: 0 -}; - -function LLV(array,period){ - if(!array || array.length - period < 0){ - throw "error:" + array; - } - var min = array[array.length - period]; - for(var i = array.length - period; i < array.length; i++){ - if( array[i] < min ){ - min = array[i]; - } - } - return min; -} - -function HHV(array,period){ - if(!array || array.length - period < 0){ - throw "error:" + array; - } - var max = array[array.length - period]; - for(var i = array.length - period; i < array.length; i++){ - if( array[i] > max){ - max = array[i]; - } - } - return max; -} - -function DeleteNullEle(initArr){ - var dealArr = []; - var initArrLen = initArr.length; - for(var i = 0,j = 0 ; i < initArrLen ; i++,j++){ - if(initArr[i] === null || isNaN(initArr[i]) ){ - j--; - continue; - } - dealArr[j] = initArr[i]; - } - return dealArr; -} - -function FstochRSI(records,n,m,p1,p2){ - var len = records.length; - //var LC = records[len-2];//上一周期收盘价 - //var rsi = TA.RSI(records,n);// RSI 数组 ,talib - var rsi = talib.RSI(records,n); - rsi = DeleteNullEle(rsi);//ceshi - - var arr1 = []; - var arr2 = []; - var arr3 = []; - var arr4 = []; - var rsi_a = []; - var rsi_b = []; - var k = []; - var d = null; - - for(var a = 0 ;a < rsi.length ; a++ ){//改造 不用 LLV - if(a < m){ - continue; - } - for(var aa = 0 ; aa <= a; aa++ ){ - rsi_a.push(rsi[aa]); - } - arr1.push(rsi[a] - LLV(rsi_a,m)); - } - for(var b = 0 ;b < rsi.length ; b++ ){//改造 不用 HHV - if(b < m){ - continue; - } - for(var bb = 0 ; bb <= b; bb++ ){ - rsi_b.push(rsi[bb]); - } - arr2.push(HHV(rsi_b,m) - LLV(rsi_b,m)); - } - - arr1 = DeleteNullEle(arr1); - arr2 = DeleteNullEle(arr2); - //Log("arr1:",arr1.length,"-",arr1);//ceshi - //Log("arr2:",arr2.length,"-",arr2);//ceshi - - arr3 = talib.MA(arr1,p1); - arr4 = talib.MA(arr2,p1); - - arr3 = DeleteNullEle(arr3); - arr4 = DeleteNullEle(arr4); - - //Log("ceshi");//ceshi - var c = 0; - var diff = 0; - if(arr3.length !== arr4.length){//实测 长度不相等 - throw "error: !=" + arr3.length + "----" + arr4.length; - diff = arr4.length - arr3.length; //example diff = 10 - 6 - }else{ - //throw "error:" + arr3.length + "----" + arr4.length; - } - - for( ;c < arr3.length ; c++ ){ - k.push(arr3[c] / arr4[c + diff] * 100); - } - - d = talib.MA(k,p2); - - return [k,d,rsi]; -} - -function CancelPendingOrders() { - while (true) { - var orders = exchange.GetOrders(); - for (var i = 0; i < orders.length; i++) { - exchange.CancelOrder(orders[i].Id); - Sleep(Interval); - } - if (orders.length === 0) { - break; - } - } -} - -var isBegin = false; -var isTrade_OC = false; -var stochrsiFast = 0; -var stochrsiSlow = 0; -function onTick(exchange) { - var records = exchange.GetRecords(); - if (!records || (records.length < 50 || records.length <= NPeriod)) { //默认 STOCHRSI 指标 最大周期14 限制 - return; - } - //Log(records.length);//ceshi - //throw "stop"; //ceshi - - var stochrsi = FstochRSI(records,14,14,3,3); // 计算 STOCHRSI 指标 - var Bar = records[records.length - 1]; - if (LastBarTime !== Bar.Time) { - isTrade_OC = false; - var HH = TA.Highest(records, NPeriod, 'High'); - var HC = TA.Highest(records, NPeriod, 'Close'); - var LL = TA.Lowest(records, NPeriod, 'Low'); - var LC = TA.Lowest(records, NPeriod, 'Close'); - - var Range = Math.max(HH - LC, HC - LL); - - UpTrack = _N(Bar.Open + (Ks * Range)); - DownTrack = _N(Bar.Open - (Kx * Range)); - //更新触发值 - table.a3 = UpTrack; - table.b3 = DownTrack; - - if (LastBarTime > 0) { - var PreBar = records[records.length - 2]; - chart.add(0, [PreBar.Time, PreBar.Open, PreBar.High, PreBar.Low, PreBar.Close], -1); - chart.add(2,[records[records.length - 2].Time,stochrsi[0][stochrsi[0].length - 2]], -1); //增加 快线 - chart.add(3,[records[records.length - 2].Time,stochrsi[1][stochrsi[1].length - 2]], -1); //增加 慢线 - } else { - for (var i = Math.min(records.length, NPeriod * 3); i > 1; i--) { - var b = records[records.length - i]; - //Log(stochrsi[0][stochrsi[0].length - 1],stochrsi[1][stochrsi[1].length - 1]);//ceshi - chart.add(0, [b.Time, b.Open, b.High, b.Low, b.Close]); - if(isBegin === false){ - chart.add(1, {x:(new Date()).getTime(), color: "black", shape: 'flag', title: "title", text: "开始"}); - isBegin = true; - } - //chart.add(2,[records[records.length - 1].Time,stochrsi[0][stochrsi[0].length - 1]]); //增加快线 - //chart.add(3,[records[records.length - 1].Time,stochrsi[1][stochrsi[1].length - 1]]); //增加慢线 - } - } - chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close]); - chart.add(2,[records[records.length - 2].Time,stochrsi[0][stochrsi[0].length - 2]]); //增加 快线 - chart.add(3,[records[records.length - 2].Time,stochrsi[1][stochrsi[1].length - 2]]); //增加 慢线 - if(isShowTouchLine === true){//是否显示触发值 - ChartCfg.yAxis[0].plotLines[0].value = UpTrack; - ChartCfg.yAxis[0].plotLines[1].value = DownTrack; - } - ChartCfg.subtitle = { - text: '触发值A: ' + UpTrack + ' 触发值B: ' + DownTrack - }; - chart.update(ChartCfg); - //chart.reset(PeriodShow); //ceshi 取消 - LastBarTime = Bar.Time; - } else { - chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close], -1); - chart.add(2,[records[records.length - 1].Time,stochrsi[0][stochrsi[0].length - 1]], -1); // 增加 快线 - chart.add(3,[records[records.length - 1].Time,stochrsi[1][stochrsi[1].length - 1]], -1); // 增加 慢线 - } - //Log(stochrsi);//ceshi - //LogStatus("Price:", Bar.Close, "Up:", UpTrack, "Down:", DownTrack, "Wins: ", Counter.w, "Losses:", Counter.l, "Date:", new Date(),"\n",NowPositionInfo); - var msg; - var fcolor = null; - var ftitle = ""; - stochrsiFast = table.a6 = stochrsi[0][stochrsi[0].length - 1]; - stochrsiSlow = table.b6 = stochrsi[1][stochrsi[1].length - 1]; - if((isTrade_OC === true && isCurrentKLineOP === false) && ( isTurnOP_Long === false && isTurnOP_Short === false ) ){//是否允许当前K线交易,排除反手的条件 - return; - } - - - if (State === STATE_IDLE) { - if ( isTurnOP_Long || (Bar.Close >= UpTrack && stochrsiFast < 30 && isTurnOP_Short === false) ) { // 加入STOCHRSI 控制 - msg = '做多 触发价: ' + Bar.Close + ' 触发值A:' + UpTrack + "stochrsiFast" + stochrsiFast; - if(isTurnOP_Long === true){ - msg = "反手做多" + msg + "#FF0000"; - } - Log(msg); - buyInfo = $.Buy(AmountOP); - State = STATE_LONG; - Log("buyInfo:",buyInfo); - if(buyInfo === null){ - return; - } - if(NowPositionInfo.direction === NONE){ - NowPositionInfo.direction = LONG; - fcolor = 'red'; - ftitle = 'L'; - moveStop = InitMoveStop; //设置 默认止损额度 - moveLevel = 0; - lastMoveStop = 0; - } - chart.add(1, {x:(new Date()).getTime(), color: fcolor, shape: 'flag', title: ftitle, text: msg}); - } - } - - if (State === STATE_IDLE) { - if ( isTurnOP_Short || (Bar.Close <= DownTrack && stochrsiFast > 70 && isTurnOP_Long === false) ) {//是否触发 反手 加入 STOCHRSI 控制 - msg = '做空 触发价: ' + Bar.Close + ' 触发值B:' + DownTrack + "stochrsiFast" + stochrsiFast; - if(isTurnOP_Short === true){ - msg = "反手做空" + msg + "#FF0000"; - } - Log(msg); - sellInfo = $.Sell(AmountOP); - Log("sellInfo:",sellInfo); - if(sellInfo === null){ - return; - } - State = STATE_SHORT; - if(NowPositionInfo.direction === NONE){ - NowPositionInfo.direction = SHORT; - fcolor = 'green'; - ftitle = 'S'; - moveStop = InitMoveStop; //设置默认止损额度 - moveLevel = 0; - lastMoveStop = 0; - } - chart.add(1, {x:(new Date()).getTime(), color: fcolor, shape: 'circlepin', title: ftitle, text: msg}); - } - } - //滑动止损 - if( (State === STATE_SHORT && NowPositionInfo.direction === SHORT ) || ( NowPositionInfo.direction === LONG && State === STATE_LONG) ){ - if(NowPositionInfo.floatProfit > step){//滑动止损 结束后 lastMoveStop 要赋值 0 , moveLevel 要赋值 0 , moveStop 重新赋值初始止损值 - moveStop = 0; - if(NowPositionInfo.floatProfit - lastMoveStop > step){ - lastMoveStop = (++moveLevel) * step; - } - } - table.b5 = "lastLine" + lastMoveStop + ", Level" + moveLevel + " ,default" + moveStop; - //Log("NowPositionInfo",NowPositionInfo,"止损",moveStop + moveLevel * step); //ceshi - if(NowPositionInfo.floatProfit <= moveStop + moveLevel * step ){ - //cover - //Log("NowPositionInfo",NowPositionInfo,"止损",moveStop + moveLevel * step); //ceshi - if(NowPositionInfo.direction === SHORT){//空仓止损 - buyInfo = $.Buy(NowPositionInfo.amount); - if(buyInfo === null){ - return; - } - isTurnOP_Short = false;//重置 反手条件为false - isTurnOP_Long = false;//重置 反手条件为false - State = STATE_IDLE; - Log("止损平仓",NowPositionInfo,"moveStop + moveLevel * step",moveStop + moveLevel * step,_C(exchange.GetTicker),buyInfo);//ceshi - CalculateCounter(buyInfo);//处理Counter 计数 - NowPositionInfo.direction = NONE; - Calculate(); - InitAccount = _C(exchange.GetAccount); - LogProfit(Profit,InitAccount); - fcolor = 'blue'; - ftitle = '止损 平仓'; - msg = "moveLevel:" + moveLevel + ", lastMoveStop:" + lastMoveStop; - isTrade_OC = true;//当前bar 已经交易 - if(moveStop !== 0){//突破止损反手 - isTurnOP_Long = true; - } - } - if(NowPositionInfo.direction === LONG){//多仓止损 - sellInfo = $.Sell(NowPositionInfo.amount); - if(sellInfo === null){ - return; - } - isTurnOP_Long = false;//重置反手条件为false - isTurnOP_Short = false;//重置反手条件为false - State = STATE_IDLE; - Log("止损平仓",NowPositionInfo,"moveStop + moveLevel * step",moveStop + moveLevel * step,_C(exchange.GetTicker),sellInfo);//ceshi - CalculateCounter(sellInfo);//处理Counter 计数 - NowPositionInfo.direction = NONE; - Calculate(); - InitAccount = _C(exchange.GetAccount); - LogProfit(Profit,InitAccount); - fcolor = 'blue'; - ftitle = '止损 平仓'; - msg = "moveLevel:" + moveLevel + ", lastMoveStop:" + lastMoveStop; - isTrade_OC = true;//当前bar 已经交易 - if(moveStop !== 0){//突破止损反手 - isTurnOP_Short = true; - } - } - chart.add(1, {x:(new Date()).getTime(), color: fcolor, shape: 'circlepin', title: ftitle, text: msg}); - } - } -} - -//反手 -var isTurnOP_Long = false; -var isTurnOP_Short = false; - -//滑动止损 参数 -//var step = 5; //滑动步长 -var moveStop = InitMoveStop; //初始止损 -var lastMoveStop = 0; //上次止损挡位 -var moveLevel = 0; //止损等级 -//var OpAmount = 1;//ceshi -//var maxProfit = 0.2; -var buyInfo = null; -var sellInfo = null; -var SHORT = 2; -var LONG = 1; -var NONE = 0; -var NowPositionInfo = { // - avgPrice : 0 , - amount : 0, - floatProfit : 0, - direction : 0 // 0 未持仓 , 1多仓 , 2空仓 -}; - - -function CalculateCounter(CoverInfo) { - if(NowPositionInfo.direction === STATE_LONG && (CoverInfo.price - NowPositionInfo.avgPrice > 0)){//处理多仓 - Counter.w++; - }else if(NowPositionInfo.direction === STATE_LONG){ - Counter.l++; - } - if(NowPositionInfo.direction === STATE_SHORT && (NowPositionInfo.avgPrice - CoverInfo.price > 0)){//处理空仓 - Counter.w++; - }else if(NowPositionInfo.direction === STATE_SHORT){ - Counter.l++; - } - table.b4 = Counter; //更新 Counter -} - - -var Profit = 0; -function Calculate(nowAccount,nowDepth){//计算并更新收益 、 浮动收益 、计算 持仓均价 、持仓量 - if(typeof(nowAccount) === 'undefined' ){ - nowAccount = _C(exchange.GetAccount); - nowDepth = _C(exchange.GetDepth); - } - var diff_stocks = nowAccount.Stocks - InitAccount.Stocks;//币之差 - var diff_balance = nowAccount.Balance - InitAccount.Balance;//钱之差 - NowPositionInfo.avgPrice = _N(Math.abs(diff_balance) / Math.abs(diff_stocks),5); - //throw nowAccount.Stocks + "----" + nowAccount.Balance;//ceshi - NowPositionInfo.amount = _N(Math.abs(diff_stocks),5); - NowPositionInfo.floatProfit = _N(diff_balance + diff_stocks * (NowPositionInfo.direction === LONG?nowDepth.Bids[0].Price : nowDepth.Asks[0].Price),5); //此次交易的浮动盈亏 - Profit = (nowAccount.Stocks - beginAccount.Stocks) * (NowPositionInfo.direction === LONG?nowDepth.Bids[0].Price : nowDepth.Asks[0].Price) + (nowAccount.Balance - beginAccount.Balance); //总盈亏 - table.b1 = nowAccount;//更新当前的账户信息 - table.a5 = NowPositionInfo; - //更新入界面 -} - -var table = null; -function main() { - CancelPendingOrders(); - _CInterval = 200; - InitAccount = exchange.GetAccount();//上次平仓后账户信息 - beginAccount = InitAccount; //启动时账户信息 - LoopInterval = Math.min(1, LoopInterval); - //清空 - LogReset(); - LogProfitReset(); - chart = Chart(ChartCfg); - chart.reset(); - - Log('交易平台:', exchange.GetName(), InitAccount); - LogStatus("Ready..."); - Log(InitAccount); - - LoopInterval = Math.max(LoopInterval, 1); - //初始化表格 - table = $.TableInit(2,7); - table.a0 = "初始账户:↓"; - table.a1 = beginAccount; - table.b0 = "当前账户:↓"; - table.a2 = "触发值A:↓"; - table.b2 = "触发值B:↓"; - table.a4 = "NowPositionInfo:↓"; - //table.b4 = "stop"; - //table.a5 = "Counter:"; - - - var beginTime = 0; - while (true) { - beginTime = (new Date()).getTime(); - onTick(exchange); - /* //ceshi - if(NowPositionInfo.floatProfit < -5){ - Log("ticker:",_C(exchange.GetTicker),NowPositionInfo); - } - //ceshi - */ - Calculate(); - $.UpdateLogStatus("loop used time:" + ((new Date()).getTime() - beginTime) + "ms"); - Sleep(LoopInterval * 1000); - } -} - -/* -0.是否当前K线允许交易 处理还有问题 -1.触发平仓触发值,导致平仓,是否增加反转。 -2. 计算浮动盈亏的函数 -//改进 -1、动态 触发值调整,根据波动率 -2、参数 步长 、系数、试试 本K 重复开仓选项 -3、双仓 -*/ diff --git "a/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266 (Copy).js" "b/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266 (Copy).js" deleted file mode 100644 index 4422074c..00000000 --- "a/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266 (Copy).js" +++ /dev/null @@ -1,256 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/43579 -策略名称: (13)策略框架 (Copy) -策略作者: dsfaong -策略描述: - -策略框架 - - -参数 默认值 描述 ----------- ----- --------- -isLogReset true 启动时是否清除日志 - -按钮 默认值 描述 ------------- ---------- ------- -upDateAmount true 更新开仓量按钮 -cmdOpen __button__ 开仓命令 -cmdCover __button__ 平仓命令 -*/ - -var Interval = 500; -var _long = 1; -var free = 0; -var state = free; //每次开仓 平仓 重置 -var buyInfo = null; //每次平仓重置 -var sellInfo = null; //每次开仓重置 -var initAccount = null; //每次平仓重置 -var beginAccount = null; //不重置 -var Profit = 0; //已实现盈亏 -var prefloatProfit = 0;//上次的浮动盈亏,滑动止盈 更新 -var openBalance = 0;//开仓量 -var isCover = false; - -var tiaojian = 0; //这里可以设置 触发条件,比如 自定义的指标函数 发出开仓信号(比如返回了 数值 1 ), 比如 0 时 是等待, 等于 2 时 是平仓 - //也可能 触发了平仓条件 -var Amount = 1; //这里可以把 交易的量(币数) 写在程序里 自动控制(比如,根据盘口量), 也可以设置在界面上做成界面上的参数,在程序运行的时候传进来。 - -var NowPositionInfo = {//持仓信息, 每次平仓更新 - avgPrice: 0, - amount: 0 , - floatProfit: 0 -}; - -function openUpdate(){//开仓后的更新 - state = _long; - sellInfo = null; - tiaojian = 0;//重置条件 -} -function closeUpdate(){//平仓后的更新 - state = free; - addLevel = 0; - buyInfo = null; - initAccount = _C(exchange.GetAccount); - NowPositionInfo.avgPrice = 0; - NowPositionInfo.amount = 0; - NowPositionInfo.floatProfit = 0; - isCover = true; - tiaojian = 0;//重置条件 -} - -function Calculate(nowAccount,nowDepth){//计算并更新收益 、 浮动收益 、计算 持仓均价 、持仓量 - if(typeof(nowAccount) === 'undefined' ){ - nowAccount = _C(exchange.GetAccount); - nowDepth = _C(exchange.GetDepth); - } - var diff_stocks = nowAccount.Stocks - initAccount.Stocks;//币之差 - var diff_balance = nowAccount.Balance - initAccount.Balance;//钱之差 - NowPositionInfo.avgPrice = Math.abs(diff_balance) / Math.abs(diff_stocks); - NowPositionInfo.amount = Math.abs(diff_stocks); - NowPositionInfo.floatProfit = diff_balance + diff_stocks * nowDepth.Bids[0].Price; //此次交易的浮动盈亏 - Profit = (initAccount.Stocks - beginAccount.Stocks) * nowDepth.Bids[0].Price + (initAccount.Balance - beginAccount.Balance); //实现盈亏 - - //更新入界面 -} - -function get_Command(){//负责交互的函数,交互及时更新 相关数值 ,熟悉的用户可以自行扩展 - var keyValue = 0;// 命令传来的参数 数值 - var way = null; //路由 - var cmd = GetCommand(); //获取 交互命令API - if (cmd) { - Log("按下了按钮:",cmd);//日志显示 - arrStr = cmd.split(":"); // GetCommand 函数返回的 是一个字符串,这里我处理的麻烦了,因为想熟悉一下JSON ,所以先对字符串做出处理,把函数返回的字符串以 : 号分割成2个字符串。储存在字符串数组中。 - - if(arrStr.length === 2){//接受的不是 数值型的,是按钮型的。 - jsonObjStr = '{' + '"' + arrStr[0] + '"' + ':' + arrStr[1] + '}'; // 把 字符串数组中的元素重新 拼接 ,拼接成 JSON 字符串 用于转换为JSON 对象。 - jsonObj = JSON.parse(jsonObjStr); // 转换为JSON 对象 - - for(var key in jsonObj){ // 遍历对象中的 成员名 - keyValue = jsonObj[key]; //取出成员名对应的 值 , 就是交互按钮的值 - } - - if(arrStr[0] == "upDateAmount"){// 此处为 数字型 。这里处理分为 按钮 和 数字型 。 详见 策略参数 设置界面 下的 交互设置 - way = 1; - } - if(arrStr[0] == "扩展1"){ - way = 2; - } - if(arrStr[0] == "扩展2"){ - way = 3; - } - if(arrStr[0] == "扩展3"){ - way = 4; - } - }else if(arrStr.length === 1){// 此处为 按钮型 - //路由 - if(cmd == "cmdOpen"){ - way = 0; - } - if(cmd == "cmdCover"){ - way = 5; - } - }else{ - throw "error:" + cmd + "--" + arrStr; - } - switch(way){ // 分支选择 操作 - case 0://处理 发出开仓信号 - tiaojian = 1; - break; - case 1://处理 - Amount = keyValue;//把交互界面设置的 数值 传递给 Amount - Log("开仓量修改为:",Amount);//提示信息 - break; - case 2://处理 - - break; - case 3://处理 - - break; - case 4://处理 - - break; - case 5://处理 发出平仓信号 - tiaojian = 2; - break; - default: break; - } - } -} - -function Loop(){//循环主体 - //获取 行情、账户等信息 - var account = _C(exchange.GetAccount); - var records = _C(exchange.GetRecords); - var depth = _C(exchange.GetDepth); - var len = records.length - 1; - - //对获取的数据 容错处理 - if(records.length < 10 ){//这里可以对 API 获取的数据 容错处理,这里举个例子 就是 获取的K线长度 必须大于10,小于10了 就返回 不做处理并在界面显示提示信息。 - //输出到状态栏表格,显示K线长度不足 - msg = "K线长度不足,获取中..."; - return; - } - msg = "K line `s length:" + (len + 1); - - //图表模板的使用--------------- - $.Draw(records); - //--------------------------- - - - //第一次启动 处理的内容--------- - if(isFirst === true){ - $.SignOP((new Date()).getTime(),null,null,3,"图表显示启动!");// 测试标记 自定义信息 到图表上 - Log("程序启动!"); - isFirst = false; - } - //-------------------------- - - //策略运行时状态栏表格上的显示数据 table.b1 就是往 b1 这个格子里 写入 "stock:" + account.Stocks + "#ff00ff"; 这些数据,可以对比截图,自己动手试试。 - table.b1 = "stock:" + account.Stocks + "#ff00ff"; - table.c1 = "Fstock:" + account.FrozenStocks + "#ff00ff"; - table.d1 = "balance:" + account.Balance + "#ff00ff"; - table.e1 = "Fbalance:" + account.FrozenBalance + "#ff00ff"; - table.b2 = "open:" + records[len].Open; - table.c2 = "high:" + records[len].High; - table.d2 = "low:" + records[len].Low; - table.e2 = "close:" + records[len].Close; - table.b3 = "bids[0].price:" + depth.Bids[0].Price; - table.c3 = "bids[0].amount:" + depth.Bids[0].Amount; - table.d3 = "asks[0].price:" + depth.Asks[0].Price; - table.e3 = "asks[0].amount:" + depth.Asks[0].Amount; - table.c4 = "avgPrice:" + NowPositionInfo.avgPrice; - table.d4 = "amount:" + NowPositionInfo.amount; - table.e4 = "floatProfit:" + NowPositionInfo.floatProfit; - //------------------------------------------------------------------------- - - //处理 策略交互 - get_Command();//获取 并处理交互 - - - //这里可以自定义 触发 操作的代码,比如 指标交叉了(当然这是你自定义的), 就可以给 tiaojian 这个变量赋值 1, 即: tiaojian = 1; 这样下面满足条件就执行相应操作。 - - - if(state === free && tiaojian === 1 ){//开仓条件,可以自行扩展,指标形态、差价、交易量 等等 - //触发了上面的if括号内的条件,这个里面就是执行具体的开仓操作了,举个例子是用 数字货币交易类库 这个模板处理开仓。 - buyInfo = $.Buy(Amount); - if(buyInfo === null){// $.Buy这个函数 返回 null 说明有原因导致 没有买到(即没有开仓成功,原因有多个可能。) - return; - } - $.SignOP((new Date()).getTime(),buyInfo.price,buyInfo.amount,1);// 把操作标记 到图表上 . 图表模板 用法可以看论坛上的帖子 - openUpdate(); - }else if(state === _long && tiaojian === 2 ){ - sellInfo = $.Sell(NowPositionInfo.amount); - if(buyInfo === null){ - return; - } - $.SignOP((new Date()).getTime(),sellInfo.price,sellInfo.amount,0);// 把操作标记 到图表上 - closeUpdate(); - } - - - //如果平仓了,更新收益----------------------- - Calculate();//计算收益,更新持仓状态 - if(isCover === true){ - LogProfit(Profit); - isCover = false; - } - //---------------------------------------- - - //更新图表--------------------------- - $.UpDateChart(records); - //--------------------------------- -} - -var table = null; -var msg = "";//显示在状态栏表格头部的 消息 -var isFirst = true; - -function main(){ - //初始化 - if(isLogReset === true){ - LogReset(); - } - beginAccount = _C(exchange.GetAccount);//程序开始运行时的初始账户信息 - initAccount = beginAccount;//每次开仓前的账户信息 - table = $.TableInit(5,6); - //初始化表格 5,代表 表格生成5列 分别是 a b c d e , 6代表表格生成 6行 分别是 0 1 2 3 4 5 6 。 这样最左上角的表格单元的坐标就是 a0 , table.a0 = 3; 此时就会显示到相应的表格 - - //给表格写上不许要变动的内容------------------ - table.a1 = "account:" + "#ff00ff"; - table.a2 = "records[length-1]:"; - table.a3 = "depth.Bids[0]/Asks[0]:"; - table.a0 = "beginAccount:"; - table.b0 = "stock:" + beginAccount.Stocks; - table.c0 = "Fstock:" + beginAccount.FrozenStocks; - table.d0 = "balance:" + beginAccount.Balance; - table.e0 = "Fbalance:" + beginAccount.FrozenBalance; - //---------------------------------------------------- - - while(true){ - Loop();//循环函数 - $.UpDateLogStatus(msg);//更新表格 数据 - msg = ""; - Sleep(Interval); - } -} - From a2c99df109d52b4e0ce861b78e24b14e9df13363 Mon Sep 17 00:00:00 2001 From: botvs Date: Sun, 11 Mar 2018 13:19:51 +0800 Subject: [PATCH 03/19] update --- ...210\206\346\236\220 (Share 1513097042).js" | 78 ++ ...250\241\345\236\213 (Share 1513096985).js" | 234 +++++ ...344\272\272 (Copy) (Share 1512130985).js" | 182 ++++ ...03\347\224\250\344\276\213\345\255\220.js" | 136 +++ MA_20180107 (Copy).js | 79 ++ ...71\345\206\262\347\255\226\347\225\245.js" | 951 ------------------ ...03\346\236\227\345\257\271\345\206\262.js" | 538 ---------- ...(\346\265\213\350\257\225\347\211\210).py" | 6 +- README.md | 43 +- Shannon's Demon (Copy).js | 52 + Shannon's Demon.js | 52 + ...01\351\207\221\344\272\244\346\230\223.js" | 12 + ...13\350\257\225\347\211\210\357\274\211.py" | 4 +- ...11\345\217\252\344\271\214\351\270\246.js" | 31 + ...60\261\346\230\257\345\271\262 (Copy).js" | 74 ++ ...01\347\240\264\345\211\215\351\253\230.py" | 48 + ...4GetMinStock()\345\207\275\346\225\260.js" | 37 + ...63\345\235\207\345\256\232\346\212\225.js" | 92 ++ ...\254(two platforms hedging-JS) (Copy).js" | 225 +++++ ...\346\234\254(two platforms hedging-JS).js" | 2 +- ...44\346\230\223\347\261\273\345\272\223.js" | 113 ++- ...345\210\260\346\234\254\345\234\260CSV.py" | 46 + ...201\347\255\226\347\225\245V0.2 (Copy).py" | 236 ----- ...25\347\256\200\345\215\225\347\211\210.js" | 76 ++ ...255\226\347\225\245 (Share 1512580165).js" | 181 ++++ ...\214\201$.CTA\345\207\275\346\225\260).js" | 12 + ...21\346\216\247\345\210\206\346\236\220.js" | 471 --------- ...44\346\230\223\347\261\273\345\272\223.js" | 2 +- ...346\230\223\347\261\273\345\272\223c++.js" | 317 ++++++ ...56\344\273\267\345\257\271\345\206\262.js" | 2 +- ...6\350\241\250\346\230\276\347\244\272).js" | 167 +++ "\346\265\213\350\257\225.py" | 15 - ...73\347\272\277\347\261\273\345\272\223.js" | 6 +- "\347\255\226\347\225\245001-szc.py" | 79 -- ...06\346\236\266\346\250\241\346\235\277.js" | 6 + ...11\351\246\231\345\206\234\347\211\210.js" | 98 ++ ...7\221\346\233\264\346\226\26020180118).js" | 7 +- ...\346\230\223_\346\265\213\350\257\2251.py" | 298 ------ ...24\342\200\224\345\244\261\350\264\245.py" | 215 ---- ...\346\230\223_\346\265\213\350\257\2253.py" | 352 ------- 40 files changed, 2360 insertions(+), 3215 deletions(-) create mode 100644 "02\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220 (Share 1513097042).js" create mode 100644 "03\345\237\272\344\272\216\345\225\206\345\223\201\346\234\237\350\264\247\347\232\204\345\245\227\345\210\251\347\255\226\347\225\245\346\250\241\345\236\213 (Share 1513096985).js" create mode 100644 "2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272 (Copy) (Share 1512130985).js" create mode 100644 "C++ API\350\260\203\347\224\250\344\276\213\345\255\220.js" create mode 100644 MA_20180107 (Copy).js delete mode 100644 "OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.js" delete mode 100644 "OKCoin\350\267\250\346\234\237\345\270\203\346\236\227\345\257\271\345\206\262.js" create mode 100644 Shannon's Demon (Copy).js create mode 100644 Shannon's Demon.js create mode 100644 "talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" create mode 100644 "\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262 (Copy).js" create mode 100644 "\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" create mode 100644 "\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.js" create mode 100644 "\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225.js" create mode 100644 "\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS) (Copy).js" create mode 100644 "\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.py" delete mode 100644 "\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2 (Copy).py" create mode 100644 "\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.js" create mode 100644 "\345\271\275\347\201\265\344\272\244\346\230\223\350\200\205\347\255\226\347\225\245 (Share 1512580165).js" delete mode 100644 "\346\225\260\345\255\227\350\264\247\345\270\201\345\267\256\344\273\267\347\233\221\346\216\247\345\210\206\346\236\220.js" create mode 100644 "\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.js" create mode 100644 "\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).js" delete mode 100644 "\346\265\213\350\257\225.py" delete mode 100644 "\347\255\226\347\225\245001-szc.py" create mode 100644 "\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.js" rename "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020171113).js" => "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180118).js" (98%) delete mode 100644 "\351\241\272\345\212\277_\351\253\230\351\242\221_\344\272\244\346\230\223_\346\265\213\350\257\2251.py" delete mode 100644 "\351\241\272\345\212\277_\351\253\230\351\242\221_\344\272\244\346\230\223_\346\265\213\350\257\2252\342\200\224\342\200\224\345\244\261\350\264\245.py" delete mode 100644 "\351\241\272\345\212\277_\351\253\230\351\242\221_\344\272\244\346\230\223_\346\265\213\350\257\2253.py" diff --git "a/02\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220 (Share 1513097042).js" "b/02\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220 (Share 1513097042).js" new file mode 100644 index 00000000..8d611b3b --- /dev/null +++ "b/02\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220 (Share 1513097042).js" @@ -0,0 +1,78 @@ +/* +策略出处: https://www.botvs.com/strategy/63223 +策略名称: 02顺大势逆小势策略之代码实现及可行性分析 (Share 1513097042) +策略作者: ellajella-0378 +策略描述: + + + + +参数 默认值 描述 +----- ----- ----- +maLen 100 maLen +kd1 50 kd1 +kd2 15 kd2 +*/ + +//语法固定格式,调用main主函数 +function main() { + + //调用商品期货交易类库中的CTA框架 + $.CTA("RM000", function(st) { + + //获取K线数组 + var j = st.records; + + //指标运算参考的最大K线数量 + if (j.length < 100) { + return; + } + + //获取上根K线的收盘价 + var c = j[j.length - 2].Close; + + //获取KDJ指标数组 + var kds = TA.KDJ(j, kd1, kd2, kd2); + + //获取KDJ指标K的数组 + var ks = kds[0]; + + //获取KDJ指标D的数组 + var ds = kds[1]; + + //获取上根K线的K值 + var k = ks[ks.length - 2].toFixed(2); + + //获取上根K线的D值 + var d = ds[ds.length - 2].toFixed(2); + + //获取均线数组 + var mas = TA.MA(j, 100); + + //获取上根K线的MA值 + var ma = mas[mas.length - 2]; + + //获取当前的持仓数量,正数指多仓, 负数指空仓, 0则不持仓 + var mp = st.position.amount; + + //如果当前持有多单,并且上根K线的K值小于上根K线的D值,平多单 + if (mp > 0 && k < d) { + return -1; //如果当前有多单,指定返回值为-N,就是平N手多单。 + } + + //如果当前持有空单,并且上根K线的K值大于上根K线的D值,平空单 + if (mp < 0 && k > d) { + return 1; //如果当前有空单,指定返回值为N,就是平N手空单。 + } + + //如果当前无持仓,并且上根K线的收盘价大于上根K线的MA值,并且上根K线的K值大于上根K线的D值,开多单 + if (mp === 0 && c > ma && k > d) { + return 1; //如果当前无持仓,指定返回值为N,就是开N手多单。 + } + + //如果当前无持仓,并且上根K线的收盘价小于上根K线的MA值,并且上根K线的K值小于上根K线的D值,开空单 + if (mp === 0 && c < ma && k < d) { + return -1; //如果当前无持仓,指定返回值为-N,就是开N手空单。 + } + }); +} diff --git "a/03\345\237\272\344\272\216\345\225\206\345\223\201\346\234\237\350\264\247\347\232\204\345\245\227\345\210\251\347\255\226\347\225\245\346\250\241\345\236\213 (Share 1513096985).js" "b/03\345\237\272\344\272\216\345\225\206\345\223\201\346\234\237\350\264\247\347\232\204\345\245\227\345\210\251\347\255\226\347\225\245\346\250\241\345\236\213 (Share 1513096985).js" new file mode 100644 index 00000000..870216fe --- /dev/null +++ "b/03\345\237\272\344\272\216\345\225\206\345\223\201\346\234\237\350\264\247\347\232\204\345\245\227\345\210\251\347\255\226\347\225\245\346\250\241\345\236\213 (Share 1513096985).js" @@ -0,0 +1,234 @@ +/* +策略出处: https://www.botvs.com/strategy/63221 +策略名称: 03基于商品期货的套利策略模型 (Share 1513096985) +策略作者: ellajella-0378 +策略描述: + +商品期货对冲 + 网格 + +传统的跨期对冲一般指统计套利, 用线性回归或者其它办法生成一个套利区间, 这样套利机会比较少, 而且有预测性, 未来价差很可能不是预计的那样回归 + +为了解决这种办法, 进而更频繁的进行套利操作, 我们把两个关联品种或者跨期品种的套利价差定义成一个网格, 每满足一定的价差就开一次仓, 做一次对冲 + +这样价差来回在我们设置的网格里进行波动,我们就能不断的开仓平仓实现盈利. + +不善文案, 不做文字表达了, 具体看策略代码 + + +参数 默认值 描述 +----------- -------------------------------------------------------------------------------------- ----------- +HedgeTable (MA705&MA709)30:15:1;40:25:1;50:35:1;60:45:1(FG705&FG709)10:0:1;15:5:1;20:10:1;25:15:1 开仓表 +CoverAll false 启动时平掉所有仓位 +CalcPeriod 60 账户权益统计周期(分) +AutoRestore false 自动恢复 +*/ + +function Hedge(q, e, positions, symbolA, symbolB, hedgeSpread) { + var self = {} + self.q = q + self.symbolA = symbolA + self.symbolB = symbolB + self.name = symbolA + " & " + symbolB + self.e = e + self.isBusy = false + self.diffA = 0 + self.diffB = 0 + self.update = _D() + var arr = hedgeSpread.split(';') + self.dic = [] + var n = 0 + var coefficient = 1 + for (var i = 0; i < positions.length; i++) { + if (positions[i].ContractType == symbolA) { + n += positions[i].Amount + if (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) { + coefficient = -1 + } + } + } + _.each(arr, function(pair) { + var tmp = pair.split(':'); + if (tmp.length != 3) { + throw "开仓表不正确"; + } + var st = { + open: Number(tmp[0]), + cover: Number(tmp[1]), + amount: Number(tmp[2]), + hold: 0 + } + if (n > 0) { + var m = Math.min(n, st.amount) + n -= m + st.hold = m * coefficient + Log("恢复", self.name, st) + } + self.dic.push(st) + }); + if (n > 0) { + throw "恢复失败, 有多余仓位 " + n; + } + + self.poll = function() { + if (self.isBusy || (!$.IsTrading(self.symbolA))) { + return + } + var insDetailA = exchange.SetContractType(self.symbolA) + if (!insDetailA) { + return + } + var tickerA = exchange.GetTicker() + if (!tickerA) { + return + } + var insDetailB = exchange.SetContractType(self.symbolB) + if (!insDetailB) { + return + } + var tickerB = exchange.GetTicker() + if (!tickerB) { + return + } + + self.update = _D(tickerA.Time) + + var action = null + var diffA = _N(tickerA.Buy - tickerB.Sell) + var diffB = _N(tickerA.Sell - tickerB.Buy) + self.diffA = diffA + self.diffB = diffB + + for (var i = 0; i < self.dic.length && !action; i++) { + if (self.dic[i].hold == 0) { + if (self.dic[i].open <= diffA) { + action = [i, "sell", "buy", self.dic[i].amount] + } else if (self.dic[i].open <= -diffB) { + action = [i, "buy", "sell", -self.dic[i].amount] + } + } else { + if (self.dic[i].hold > 0 && self.dic[i].cover >= diffB) { + action = [i, "closesell", "closebuy", self.dic[i].hold] + } else if (self.dic[i].hold < 0 && self.dic[i].cover >= -diffA) { + action = [i, "closebuy", "closesell", self.dic[i].hold] + } + } + } + + if (!action) { + return + } + + Log("A卖B买: " + _N(diffA) + ", A买B卖: " + _N(diffB), ", Action: " + JSON.stringify(action)) + + self.isBusy = true + + self.q.pushTask(self.e, self.symbolA, action[1], self.dic[action[0]].amount, function(task, ret) { + if (!ret) { + self.isBusy = false + return + } + self.q.pushTask(self.e, self.symbolB, action[2], self.dic[action[0]].amount, function(task, ret) { + if (!ret) { + throw "开仓失败..." + } + self.isBusy = false + if (task.action != "buy" && task.action != "sell") { + self.dic[action[0]].hold = 0; + } else { + self.dic[action[0]].hold = action[3]; + } + }) + }) + } + return self +} + + +function main() { + SetErrorFilter("ready|login|timeout") + Log("正在与交易服务器连接...") + while (!exchange.IO("status")) Sleep(1000); + Log("与交易服务器连接成功") + var mode = exchange.IO("mode", 0); + if (typeof(mode) !== 'number') { + throw "切换模式失败, 请更新到最新托管者!"; + } else { + Log("已切换到适合多品种价格查询的立即模式"); + } + + if (CoverAll) { + Log("开始平掉所有残余仓位..."); + $.NewPositionManager().CoverAll(); + Log("操作完成"); + } + LogStatus("尝试获取持仓状态") + var positions = _C(exchange.GetPosition) + LogStatus("Ready") + + if (positions.length > 0 && !AutoRestore) { + throw "发现持仓, 请勾选自动恢复" + } + + var pairs = [] + var q = $.NewTaskQueue(function(task, ret) { + Log(task.desc, ret ? "成功" : "失败") + }) + var arr = HedgeTable.split('('); + var tbl = { + type: 'table', + title: 'Runtime', + cols: ['Pair', 'Open', 'Cover', 'Hold', 'DiffA', 'DiffB', 'Time'], + rows: [] + }; + _.each(arr, function(item) { + if (item != '') { + var tmp = item.split(')'); + var pair = tmp[0].replace('(', '').split('&'); + var symbolDetail = _C(exchange.SetContractType, pair[0]) + Log("合约", symbolDetail.InstrumentName, "一手", symbolDetail.VolumeMultiple, "份, 最大下单量", symbolDetail.MaxLimitOrderVolume, "保证金率:", _N(symbolDetail.LongMarginRatio), _N(symbolDetail.ShortMarginRatio), "交割日期", symbolDetail.StartDelivDate); + symbolDetail = _C(exchange.SetContractType, pair[1]) + Log("合约", symbolDetail.InstrumentName, "一手", symbolDetail.VolumeMultiple, "份, 最大下单量", symbolDetail.MaxLimitOrderVolume, "保证金率:", _N(symbolDetail.LongMarginRatio), _N(symbolDetail.ShortMarginRatio), "交割日期", symbolDetail.StartDelivDate); + pairs.push(Hedge(q, exchanges[0], positions, pair[0], pair[1], tmp[1])) + } + }); + + var ts = 0 + var lastUpdate = 0 + while (true) { + if (!exchange.IO("status")) { + Sleep(1000) + continue + } + + var now = new Date().getTime() + if (now - ts > (CalcPeriod * 60000)) { + var account = exchange.GetAccount() + if (account) { + var obj = JSON.parse(exchange.GetRawJSON()) + $.PlotLine('账户权益', obj['Balance'] + obj['PositionProfit']); + ts = now + } + } + // IO("wait") 会一直等待收到任何一个品种的行情推送信息, 返回收到行情的真实时间 + var n = exchange.IO("wait") + // 计算行情信息传到策略层花费的时间 + var idle = UnixNano() - n + + if (now - lastUpdate > 5000) { + tbl.rows = [] + _.each(pairs, function(t) { + for (var i = 0; i < t.dic.length; i++) { + tbl.rows.push([t.name, t.dic[i].open, t.dic[i].cover, t.dic[i].hold, t.diffA, t.diffB, t.update]) + } + }); + LogStatus('`' + JSON.stringify(tbl) + '`\nUpdate: ' + _D() + ', Idle: ' + (idle/1000000) + ' ms') + lastUpdate = now + } + + _.each(pairs, function(t) { + t.poll() + }); + + q.poll() + } +} diff --git "a/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272 (Copy) (Share 1512130985).js" "b/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272 (Copy) (Share 1512130985).js" new file mode 100644 index 00000000..67b11734 --- /dev/null +++ "b/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272 (Copy) (Share 1512130985).js" @@ -0,0 +1,182 @@ +/* +策略出处: https://www.botvs.com/strategy/61398 +策略名称: 2014年的简易短线机器人 (Copy) (Share 1512130985) +策略作者: ellajella-0378 +策略描述: + +**策略的介绍** + +策略分享地址: +https://www.botvs.com/strategy/1088 +这个策略是我做虚拟货币以来的主要策略,后面经过不断完善和修改,复杂了很多,但主要思想并没有改变,分享的这个版本是无明显bug的 最初版本,最为简单清晰,没有仓位管理,每次交易都是满仓,没有卡死后重启等等,但也足够说明问题。 +策略从2014年8月运行,直到今年年初交易所收手续费。期间运行的还算很好,亏损的时间很少。资金从最初的200元跑到了80比特币。具体的过程可以看[小草的新浪博客](http://blog.sina.com.cn/u/2389357153)里[虚拟货币自动化交易之路](http://blog.sina.com.cn/s/blog_8e6ab2610102v6sq.html)系列文章。 + +**为什么分享这个策略** + +1.交易所收取手续费后,几乎杀死了所有的高频策略,我的也不例外。但策略改改也许还能用,大家可以研究一下。 +2.好久没有分享东西了,这篇文章早就想写了。 +3.和大家共同交流学习。 + +**策略的原理** + +这个策略原理极为简单,可以理解为准高频的做市策略,各位看了之后可能想打人,这都能赚钱,当时几乎谁都能写出来。我开始也没预料到它能这么有效,可见心中有想法要赶紧付出实践,说不一定有意外之喜。在比特币机器人初兴的2014年,写出赚钱的策略太容易了。 +和所有的高频策略一样,本策略也是基于orderbook,下图就是一个典型的比特币交易所的订单分布, + https://dn-filebox.qbox.me/0d8ec18c831404d3d1c19e17299c78017abcfd48.png +可以看到左侧是买单,显示了不同价格的挂单数量,右侧是卖单。可以想象如果一个人要买入比特币,如果不想挂单等待的话,只能选择吃单,如果他的单子比较多,会使得卖单挂单大量成交,对价格造成冲击,但是这种冲击一般不会一直持续,还有人想吃单卖出,价格在极短时间很可能还会恢复,反过来理解有人要卖币也类似。 +以图中的挂单为例,如果要直接买入5个币,那么价格会达到10377,在这时如果有人要直接卖出5个币,价格会达到10348,这个空间就是利润空间.策略会在稍低于10377的价格挂单,如10376.99,同时会以稍高于10348的价格买入,如10348.01,这是如果刚才的情况发生了,显然就会赚到其中的差价。虽然不会每次都如此完美,但在概率的作用下,赚钱的几率实际高得惊人。 +以现在策略的参数讲解一下具体操作,这个参数当然无法使用了,仅作一个说明。它会向上寻找累计卖挂单量为8个币的价格,这里是10377,那么此时的卖价就是这个价格减去0.01(减去多少可以是随机的),同理向下寻找累计买挂单为8个币,这里是10348,那么此时的卖价就是10348.01,此时买卖价的差价是10376.99-10348.01=28.98,大于策略预设的差价1.5,就以这两个价格挂单等待成交,如果价差小于1.5,也会找一个价格进行挂单,如盘口价格加减10,等待捡漏(更合适的应该是继续往下找跟多的深度)。 + +**进一步的说明** + +1. 没有钱或币了怎么办? +这种情况在我的钱较少是十分普遍,大多数时候只挂一边的单子,但不是大问题。其实可以加入币钱平衡的逻辑,但在平衡的过程难免产生损失,毕竟每一次的成交都是概率的垂青,我选择保持单边等待成交,当然这样也浪费了另一边的成交机会。 +2. 仓位是如何管理的? +刚开始都是满仓买入卖出,后来根据不同的参数分为不同的组,不会一次完全成交。 +3. 没有止损吗? +策略有完整的买卖挂单的逻辑,我认为不需要止损(可以讨论),还有就是概率的垂青,成交就是机会,止损可惜了。 +4. 如何调整为赚币的策略? +此时的参数是对称的,即向上8个币的累计卖单,向下8个币的累计买单,稍微不平衡一下,比如向上改为15个币的累计卖单,使得卖币机会更难得,有更大的几率会以更低的价格接回来,这样就会赚币,反过来就赚钱。实际上前期策略如此有效,币和钱都是增加的。 + +**代码讲解** + +完整的代码可以见我在www.botvs.com得策略分享,这里只讲解核心逻辑函数。在没有改动的情况下,在botvs自带的模拟盘竟然运转完全正常,这是一个3年多前的策略,平台还支持到现在,太让人感动了。 +首先是获取买卖价函数GetPrice(),需要获取订单深度信息,注意不同平台的订单深度信息长度不同,以及即使遍历了所有订单仍然没有所需要的量的情况(在后期许多0.01的网格挂单会导致这种情况),调用是GetPrice('Buy')就是获取买价。 +``` +function GetPrice(Type) { + //_C()是平台的容错函数 + var depth=_C(exchange.GetDepth); + var amountBids=0; + var amountAsks=0; + //计算买价,获取累计深度达到预设的价格 + if(Type=="Buy"){ + for(var i=0;i<20;i++){ + amountBids+=depth.Bids[i].Amount; + //参数floatamountbuy是预设的累计深度 + if (amountBids>floatamountbuy){ + //稍微加0.01,使得订单排在前面 + return depth.Bids[i].Price+0.01;} + } + } + //同理计算卖价 + if(Type=="Sell"){ + for(var j=0; j<20; j++){ + amountAsks+=depth.Asks[j].Amount; + if (amountAsks>floatamountsell){ + return depth.Asks[j].Price-0.01;} + } + } + //遍历了全部深度仍未满足需求,就返回一个价格,以免出现bug + return depth.Asks[0].Price +} +``` +每个循环的主函数onTick(),这里定的循环时间3.5s,每次循环都会把原来的单子撤销,重新挂单,越简单越不会遇到bug. +``` +function onTick() { + var buyPrice = GetPrice("Buy"); + var sellPrice= GetPrice("Sell"); + //diffprice是预设差价,买卖价差如果小于预设差价,就会挂一个相对更深的价格 + if ((sellPrice - buyPrice) <= diffprice){ + buyPrice-=10; + sellPrice+=10;} + //把原有的单子全部撤销,实际上经常出现新的价格和已挂单价格相同的情况,此时不需要撤销 + CancelPendingOrders() + //获取账户信息,确定目前账户存在多少钱和多少币 + var account=_C(exchange.GetAccount); + //可买的比特币量,_N()是平台的精度函数 + var amountBuy = _N((account.Balance / buyPrice-0.1),2); + //可卖的比特币量,注意到没有仓位的限制,有多少就买卖多少,因为我当时的钱很少 + var amountSell = _N((account.Stocks),2); + if (amountSell > 0.02) { + exchange.Sell(sellPrice,amountSell);} + if (amountBuy > 0.02) { + exchange.Buy(buyPrice, amountBuy);} + //休眠,进入下一轮循环 + Sleep(sleeptime); +} +``` + +**尾巴** + +整个程序也就40多行,看上去十分简单,但当时也花了我一个多星期,这还是在botvs平台上情况下。最大的优势还是起步早,在2014年,市场上以搬砖为主,网格和抢盘口的高频也不多,使得策略如鱼得水,后来竞争不可避免越来越激烈,我的钱也越来越多,面临的挑战很多,每隔一段时间都要进行较大的改动来应对,但总体还算顺利。在交易平台不收取手续费的情况下,是程序化交易的天堂,散户因为不收手续费跟倾向于操作,为高频和套利提供了空间,这一切也基本随着动辄0.1-0.2%的双向手续费终结了,不仅是自己被收费的问题,而是整个市场活跃度下降。 +但不需要高频的量化策略任然有很大的空间。 + + +参数 默认值 描述 +--------------- ------ ---- +sleeptime 3500 休眠时间 +floatamountbuy 8 买单深度 +floatamountsell 8 卖单高度 +diffprice 1.5 套利差价 +*/ + +/* +就是我刚开始编写机器人的源代码,几乎没有改动,参数也是原来的参数。这个版本的程序有许多 +需要改进的地方,但即使如此,它也当时表现除了惊人的盈利能力,在我本金不多时,不加杠杆平 +均每天盈利在5%左右。当然无论从哪一方面,它都不适应今天的市场。 +我同时也发了一篇文章在社区,大家可以看看。 +by 小草 +*/ + +//稍微改了一下,用了平台的容错函数_C(),和精度函数_N(). +//取消全部订单 +function CancelPendingOrders() { + var orders = _C(exchange.GetOrders); + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]);} +} + +//计算将要下单的价格 +function GetPrice(Type) { + var depth=_C(exchange.GetDepth); + var amountBids=0; + var amountAsks=0; + //计算买价,获取累计深度达到预设的价格 + if(Type=="Buy"){ + for(var i=0;i<20;i++){ + amountBids+=depth.Bids[i].Amount; + //floatamountbuy就是预设的累计买单深度 + if (amountBids>floatamountbuy){ + //稍微加0.01,使得订单排在前面 + return depth.Bids[i].Price+0.01;} + } + } + //同理计算卖价 + if(Type=="Sell"){ + for(var j=0; j<20; j++){ + amountAsks+=depth.Asks[j].Amount; + if (amountAsks>floatamountsell){ + return depth.Asks[j].Price-0.01;} + } + } + //遍历了全部深度仍未满足需求,就返回一个价格,以免出现bug + return depth.Asks[0].Price +} + +function onTick() { + var buyPrice = GetPrice("Buy"); + var sellPrice= GetPrice("Sell"); + //买卖价差如果小于预设值diffprice,就会挂一个相对更深的价格 + if ((sellPrice - buyPrice) <= diffprice){ + buyPrice-=10; + sellPrice+=10;} + //把原有的单子全部撤销,实际上经常出现新的价格和已挂单价格相同的情况,此时不需要撤销 + CancelPendingOrders() + //获取账户信息,确定目前账户存在多少钱和多少币 + var account=_C(exchange.GetAccount); + //可买的比特币量 + var amountBuy = _N((account.Balance / buyPrice-0.1),2); + //可卖的比特币量,注意到没有仓位的限制,有多少就买卖多少,因为我当时的钱很少 + var amountSell = _N((account.Stocks),2); + if (amountSell > 0.02) { + exchange.Sell(sellPrice,amountSell);} + if (amountBuy > 0.02) { + exchange.Buy(buyPrice, amountBuy);} + //休眠,进入下一轮循环 + Sleep(sleeptime); +} + +function main() { + while (true) { + onTick(); + } +} diff --git "a/C++ API\350\260\203\347\224\250\344\276\213\345\255\220.js" "b/C++ API\350\260\203\347\224\250\344\276\213\345\255\220.js" new file mode 100644 index 00000000..d6e4d235 --- /dev/null +++ "b/C++ API\350\260\203\347\224\250\344\276\213\345\255\220.js" @@ -0,0 +1,136 @@ +/* +策略出处: https://www.botvs.com/strategy/61533 +策略名称: C++ API调用例子 +策略作者: Zero +策略描述: + +支持C++ 11, 兼容各种平台(Windows/Linux/Mac). 云端编译. + +*/ + +void main() { + if (!Test("c++")) { + Panic("请下载最新版本托管者"); + } + // json: https://github.com/nlohmann/json + // 所有的对像返回用Valid来判断是否有效 + LogProfitReset(); + LogReset(); + Log(_N(9.12345, 2)); + Log("use _C", _C(exchange.GetTicker), _C(exchange.GetAccount)); + + // 测试异步并发 + auto routineTicker = exchange.Go("GetTicker"); + auto routineDepth = exchange.Go("GetDepth"); + Ticker asyncTicker; + Depth asyncDepth; + + // 无超时, 一直等到 Ticker 返回 + if (routineTicker.wait(asyncTicker)) { + Log("Wait Ticker OK", asyncTicker.Valid, asyncTicker, asyncTicker.Last); + } else { + Log("Wait Ticker fail"); + } + // 带超时的等待300ms, 如果指定为0,就立即返回 + if (routineDepth.wait(asyncDepth, 200)) { + // 在等待时间Api返回调用, 但不说明深度一定就有效, asyncDepth.Valid 代表是否有效 + Log("Wait Depth OK", asyncDepth.Valid, asyncDepth); + } else { + Log("Wait Depth timeout"); + } + + auto records = _C(exchange.GetRecords); + Log("K线最后一根", records[records.size()-1].Time, _D(records[records.size()-1].Time), records[records.size()-1]); + // Test TA + auto ema = TA.EMA(records, 20); + Log("EMA最后几组", ema[ema.size()-1], ema[ema.size()-2], ema[ema.size()-3]); + + auto macd = talib.MACD(records); + Log("MACD最后几组", macd[0][macd[0].size()-1], macd[1][macd[1].size()-1], macd[2][macd[2].size()-1]); + + //SetErrorFilter("timeout"); + Log(GetOS(), GetPid(), GetLastError(), "MD5", MD5("hello")); + Log("Hash", Hash("md5", "hex", "hello"), Hash("sha512", "base64", "hello")); + Log("HMAC", HMAC("sha512", "base64", "hello", "pass")); + Log(Version(), Unix(), UnixNano()); + Log("Start Test Chart"); + Chart c = Chart(R"EOF({"chart":{"type":"line"},"title":{"text":"简单图表"},"xAxis":{"title":{"text":"Date"}},"yAxis":{"title":{"text":"Number"}},"series":[{"name":"number","data":[]}]})EOF"); + c.reset(); + for (size_t i = 0; i < 10; i++) { + c.add(0, {(Unix() + i)*1000, rand() % 100}); + } + Log(exchange.GetName(), exchange.GetLabel(), exchanges.size()); + auto acc = exchange.GetAccount(); + if (acc.Valid) { + Log(acc); + } + + // 用LogStatus结合json画一个表格, 自带的json库很强大, 可参考: https://github.com/nlohmann/json + json tbl = R"({"type" : "table", "title" : "AAA", "cols" : ["Head1", "Head2"], "rows": []})"_json; + tbl["rows"].push_back({"111", "222"}); + tbl["rows"].push_back({"col2", "col22"}); + LogStatus("`"+tbl.dump()+"`"); + + auto ticker = exchange.GetTicker(); + if (ticker.Valid) { + Log(ticker); + Log(ticker.Info); // Info结构直接是json对像 + } + + auto d = exchange.GetDepth(); + if (d.Valid) { + Log(d.Asks[0], d.Bids[0]); + } + // 测试期货 + if (exchange.GetName() == "Futures_OKCoin") { + exchange.SetContractType("this_week"); + exchange.SetMarginLevel(20); + exchange.SetDirection("closebuy"); + + auto positions = exchange.GetPosition(); + if (positions.Valid) { + Log(positions); + } + } + // 测试其它库 + Log("HttpQuery", HttpQuery("http://www.baidu.com/404").size()); + auto obj = json::parse(HttpQuery("http://www.baidu.com/404", "", "", "", true)); + string body = obj["Body"]; + Log("HttpQuery", body.size(), obj["Header"].dump()); + Log(Mail("smtp://smtp.163.com", "test@163.com", "password", "admin@163.com", "title", "test c++ email")); + // Test Dial + auto client = Dial("tcp://www.baidu.com:80"); + if (client.Valid) { + client.write("GET / HTTP/1.1\nHost: www.baidu.com\nConnection: Close\n\n"); + while (true) { + string buf = client.read(); + if (buf == "") { + break; + } + Log("Dial receive", buf.size()); + } + client.close(); + } + + _G("OK","xxx"); + Log(_G("OK")); + _G("OK","yyyyyy"); + Log(_G("OK")); + _G("OK",NULL); + Log(_G("OK")); + + // 测试商品期货 + if (exchange.GetName() == "Futures_CTP") { + // C++ IO返回的是一个json对象 + exchange.IO("mode", 0); + vector Symbols = {"MA888", "rb888"}; + for (auto &s : Symbols) { + // C++ SetContractType 返回的是一个json对象 + Log(s, _C(exchange.SetContractType, s)["InstrumentName"]); + } + // 接收到100个tick后退出 + for (size_t i = 0; i < 100; i++) { + Log(exchange.IO("wait_any")); + } + } +} diff --git a/MA_20180107 (Copy).js b/MA_20180107 (Copy).js new file mode 100644 index 00000000..fe2a5336 --- /dev/null +++ b/MA_20180107 (Copy).js @@ -0,0 +1,79 @@ +/* +策略出处: https://www.botvs.com/strategy/69033 +策略名称: MA_20180107 (Copy) +策略作者: ellajella-0378 +策略描述: + + + + +参数 默认值 描述 +------------ ----- ------------ +long_period 156 long_period +short_period 35 short_period +*/ + +/*backtest +start: 2018-01-01 00:00:00 +end: 2018-01-07 22:00:00 +period: 15m +exchanges: [{"eid":"Bitfinex","currency":"LTC","balance":100000,"stocks":0}] +*/ + +function refresh_data() { + ticker = exchange.GetTicker(); + coin_price = ticker.Last + account = exchange.GetAccount(); + balance = account.Balance + frozen_balance = account.FrozenBalance + stocks = account.Stocks + frozen_stocks = account.FrozenStocks + total_asset = balance + frozen_balance + (stocks + frozen_stocks) * coin_price +} + + +function main() { + refresh_data() + var init_total_asset = total_asset + var Profit = null + Log("账户信息,Total_asset:", total_asset); + + while (true) { + refresh_data() + ticker = exchange.GetTicker(); + coin_price = ticker.Last + var buy_amount = account.Balance / coin_price + var sell_amount = account.Stocks + + var records = exchange.GetRecords(PERIOD_M15); //可以填入不同k线周期,比如PERIOD_M1,PERIOD_M30,PERIOD_H1...... + var ma_short = TA.MA(records, short_period); + ma_short = ma_short[ma_short.length - 1] + var ma_long = TA.MA(records, long_period); + ma_long = ma_long[ma_long.length - 1] + + var condition = ma_short - ma_long + + if (condition > 0 & buy_amount > 0.001) { + Log('buy,coin_price=', coin_price, 'buy_amount=', buy_amount) + var id_buy = exchange.Buy(coin_price, buy_amount); + Log("id:", id_buy); + refresh_data() + Log("账户信息,Total_asset:", total_asset); + Profit = total_asset - init_total_asset + LogProfit(Profit) + } else if (condition <= 0 & sell_amount > 0.001) { + Log('sell,coin_price=', coin_price, 'sell_amount=', sell_amount) + var id_sell = exchange.Sell(coin_price, sell_amount); + Log("id:", id_sell); + refresh_data() + Log("账户信息,Total_asset:", total_asset); + Profit = total_asset - init_total_asset + LogProfit(Profit) + } + Sleep(1000 * 60) + } + refresh_data() + Profit = total_asset - init_total_asset + LogProfit(Profit) + Log("账户信息,Total_asset:", total_asset); +} diff --git "a/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.js" "b/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.js" deleted file mode 100644 index f1f2b91f..00000000 --- "a/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.js" +++ /dev/null @@ -1,951 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/34878 -策略名称: OKCoin期货跨期对冲策略 -策略作者: 小小梦 -策略描述: - -### OKCoin期货跨期对冲策略,季度、当周、次周 -- 1、 季度-当周 -- 2、 季度-次周 -- 3、 当周-次周 -- 4、在周五交割前5分钟会自动 平仓, 锁定15分钟 后再正常运行。 - -### 更新: -- 更新新域名 修改API 地址 用于获取 交割时间,原地址 修改为 www.okex.com - -### BUG: -在期货策略中 不能使用 Go函数 ,会导致切换合约问题, 对此 策略已经修改,改为一般调用。 -支持限价单模式。 -市价单模式有一些问题。 -如有BUG 请回复 QQ: 359706687 小小梦, 及时更新! -#### 测试有部分问题,持续更新中。 - - -参数 默认值 描述 ------------------ -------------------------- --------------- -HedgeTable (this_week&quarter)30:15:1 对冲控制表 -isCreateHedgeList false 是否生成 对冲表(只支持1组) -begin 10 起始差价 -end 300 结束差价 -size 10 网眼大小 -step 20 网格节点间距 -amountOfPoint true 节点下单量 -symbolA this_week 合约A -symbolB quarter 合约B -istry false 是否为回测模式 或者 实盘测试 -isFilter true 是否过滤常规错误 -For_USD false 显示为 美元 计价 -MarginLevel 10 杠杆 -MarginRatio 0.5 保证金占总 资金的比例 -AutoRecoveryState true 自动恢复 -Interval 500 轮询间隔 -isUseMarketOrder false 是否使用市价单 -*/ - -//2017.2.22 -/* 临时参数 -1、合约1 最大开仓量 -2、合约2 最大开仓量 -3、ATR 系数 -4、ATR 柱数 -5、ATR 更新周期(秒) -6、样本数量 -7、样本采集轮询比例 -8、触发线调整周期(秒) -9、合约1 杠杆参数 -10、合约2 杠杆参数 -11、合约1 字符串 -12、合约2 字符串 -13、盘口扫描深度 -14、轮询周期 -15、正对冲 开仓 -16、正对冲 平仓 -17、反对冲 开仓 -18、反对冲 平仓 -// 控制开关 -19、是否开启自动触发控制 -20、是否开启 交易控制表 -21、是否开启常规错误过滤 -22、是否开启回测 模式 -*/ -var checkTime = 0; -var residualTime = 0; -var checkPreTime = 0; -var JGDate = []; // 交割模拟。 ["BTC1129", "BTC1229", "BTC0316"]; -var JGDateIndex = 0; // 模拟交割索引。 -var JGHoursCorrect = 8; // 检测交割剩余小时,在实盘中需要修正 8小时。 模拟时该值设置为0 -var idA = null; -var idB = null; -var A = 1; -var B = 2; -var PRE = 3; -var PLUS = 4; -var MINUS = 5; -var FREE = 6; - -function init(){ - if(istry){ - JGHoursCorrect = 0; // 模拟中 该值修改为0 - Log("启用模拟 交割,初始化交割日期列表。"); - UpdateJGDate(); - } -} - -function UpdateJGDate(){ - // 循环31次 遍历出 当前月份的所有 星期5的 日期, 取时间戳, 对比当前时间戳,小于当前的 丢弃,大于当前的第一个即是 - // 在用时间戳恢复日期,拿到 字符串 - var array_JG_stamp = []; - var date = new Date(); - var nowStamp = date.getTime(); - var nowMonth = date.getMonth(); - var nextJG_Stamp = 0; - date.setHours(16); // 0~23 - date.setMinutes(0); // 0~59 - date.setSeconds(0); // 0~59 - for(var i = 1 ; i <= 31; i++){ - date.setDate(i); - var EveryDay = date.getDay(); // 1~6 - if(EveryDay === 5 && nowMonth == date.getMonth()){ - var fridayStamp = date.getTime(); - array_JG_stamp.push(fridayStamp); - } - } - for(var j = 0 ; j < array_JG_stamp.length ; j++){ - if(nowStamp <= array_JG_stamp[j]){ - nextJG_Stamp = array_JG_stamp[j]; - break; - } - if(j == array_JG_stamp.length - 1){ - nextJG_Stamp = array_JG_stamp[j] + 1000 * 7 * 24 * 60 * 60; - } - } - array_JG_stamp = []; - for(var n = 1 ; n <= 100; n++){ // 生成 100 个 模拟交割日期。 - if(n == 1){ - array_JG_stamp.push(nextJG_Stamp); - }else{ - nextJG_Stamp += 1000 * 7 * 24 * 60 * 60; - array_JG_stamp.push(nextJG_Stamp); - } - } - var date2 = new Date(); - for(var m = 0 ; m < array_JG_stamp.length ; m++){ - date2.setTime(array_JG_stamp[m]); - var strMonth = date2.getMonth() + 1; - var strDate = date2.getDate(); - if(strMonth < 10){ - strMonth = '0' + strMonth; - } - if(strDate < 10){ - strDate = '0' + strDate; - } - JGDate.push("BTC" + strMonth + strDate); - } - Log("模拟生成的交割日期:", JGDate); -} - -function CheckDelivery(nowTime, Symbol, task) { - var contractInfo = null; - if(checkTime <= 0){ - var contractName = ""; - var ContractIndex = 0; - if(Symbol === "this_week"){ - ContractIndex = 0; - }else if(Symbol === "next_week"){ - ContractIndex = 1; - }else if(Symbol === "quarter"){ - ContractIndex = 2; - } - if(istry === true){ // 判断是不是 模拟测试 - try{ - contractName = JGDate[JGDateIndex]; // 模拟测试 交割日期 - JGDateIndex++; - } catch(e){ - Log("回测模式,更新交割日期错误", e); - JGDateIndex--; - } - } - while (contractName == "") { - //var contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=this_week"); //只是检测this_week ,避免重复调用提高效率 - switch(ContractIndex){ - case 0: contractInfo = HttpQuery("https://www.okex.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=this_week"); - // www.okex.com 更换新域名 - break; - case 1: contractInfo = HttpQuery("https://www.okex.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=next_week"); - break; - case 2: contractInfo = HttpQuery("https://www.okex.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=quarter"); - break; - default: Log("contractInfo:", contractInfo); - //throw "switch NumContractType Error!"; - } //根据 contractType 类型 选择读取合约交割日期 - if (!contractInfo || contractInfo.length === 0) { - Sleep(100); - continue; - } - try { - contractName = (JSON.parse(contractInfo))[0].contract_name; - } catch (e) { - Log("CheckDelivery Error",contractInfo, e); - return 0; - } - } - var nowDateTime = new Date(); - contractName = contractName.split("BTC")[1]; //抽取BTC后的字符串 重新赋值 - var strMonth = contractName[0] + contractName[1]; - var strDay = contractName[2] + contractName[3]; - var strYear = nowDateTime.getFullYear() + ""; //获取 年份字符串 - - // 处理跨年问题 - var nowMonth = nowDateTime.getMonth(); // 获取月份 - if(strMonth < nowMonth){ - strYear = (strYear - 0) + 1; - strYear = strYear + ""; - } - - var strDate = strYear + '-' + strMonth + '-' + strDay + ' ' + "16:00:00"; - var deliveryTime = (new Date(strDate)).getTime(); // + 16 * 60 * 60 * 1000; - nowTime = nowDateTime.getTime(); - residualTime = (deliveryTime - nowTime) / 1000 / 60 / 60 - JGHoursCorrect; //单位是小时 - checkTime = (deliveryTime - nowTime) - JGHoursCorrect * 1000 * 60 * 60; //还差多少毫秒交割 - checkPreTime = nowTime; //记录开始的时间 - Log("合约", Symbol, "交割日期获取:", strDate); - }else{ - checkTime -= nowTime - checkPreTime; //减去消耗的时间 - checkPreTime = nowTime; - residualTime = checkTime / 1000 / 60 / 60; // 计算距离交割多少小时 - } - if(residualTime < 24){ //交割小于24小时 - MSG_String = "  " + Symbol + " 交割时间剩余:" + residualTime + "小时!!#FF0000"; - if((checkTime / 1000 / 60) <= 5 && task.isFrozen == false){ // 每次交割前5分钟 锁定。 - Log("距离交割剩余5分钟,平掉所有仓位!#FF0000"); - for(var index = 0; index < task.dic.length; index++){ - if(task.dic[index].hold > 0){ // 平空A 平多B - task.action = [index, "closesell", "closebuy", task.dic[index].hold]; - Log(JSON.stringify(task.action)); - Hedge_Open_Cover(task); - $.PlotFlag(nowTime, "C", "closesell-closebuy", "circlepin"); - }else if(task.dic[index].hold < 0){ // 平多A 平空B - task.action = [index, "closebuy", "closesell", task.dic[index].hold]; - Log(JSON.stringify(task.action)); - Hedge_Open_Cover(task); - $.PlotFlag(nowTime, "C", "closebuy-closesell", "circlepin"); - } - } - task.nowAccount = _C(task.e.GetAccount); - var Positions = _C(task.e.GetPosition); - UpdatePosition(task, Positions); - Log("全部仓位已平,检查持仓:", Positions, "程序冻结15分钟!#FF0000"); - task.isFrozen = true; - task.FrozenStartTime = new Date().getTime(); - } - }else{ - MSG_String = "  " + Symbol + " 交割时间剩余:" + residualTime + "小时!!"; - } - return _N(residualTime, 3); -} - - -function OpenPriceToActual(Price, Piece){ - var OnePieceEquivalentCoin = 100 / Price; - var OpenFee = Piece * (OnePieceEquivalentCoin) * (0.03 * 0.01); - var Actual = Price + (OpenFee * Price) / (OnePieceEquivalentCoin * Piece); - return Actual; - //Log("Actual:", Actual, "OpenFee:", OpenFee, "OnePieceEquivalentCoin:", OnePieceEquivalentCoin, "保证金:", OpenFee / 0.01 / 0.03 / 10); // 测试 - //var Actual = Price + ((0.03 * 0.01) * Price); -} - -function CreateHedgeList(Begin, End, Size, Step, AmountOfPoint, SymbolA, SymbolB){ - // "(this_week&quarter)100:90:1;110:100:1;120:110:1;130:120:1;140:130:1;150:140:1;160:150:1;170:160:1;180:170:1;190:180:1"; - if((SymbolA !== "this_week" && SymbolA !== "next_week" && SymbolA !== "quarter") || (SymbolB !== "this_week" && SymbolB !== "next_week" && SymbolB !== "quarter")){ - throw "合约代码错误: SymbolA " + SymbolA + " SymbolB " + SymbolB; - } - var BodyString = ""; - var HeadString = '(' + SymbolA + '&' + SymbolB + ')'; - for(var i = Begin ; i <= End ; i += Step){ - if(i + Step > End){ - BodyString += (i + ':') + (i - Size) + (':' + AmountOfPoint); - }else{ - BodyString += (i + ':') + (i - Size) + (':' + AmountOfPoint) + ';'; - } - } - var HL = HeadString + BodyString; - Log("按参数生成对冲列表:", HL); - return HL; -} - -function UpdatePosition(task, Positions, onlyAorBorPRE){ - if(Positions.length > 2){ - Log(Positions, "Positions 长度大于2!#FF0000"); - throw "同类型合约不能同时持有多仓空仓。"; - } - if(onlyAorBorPRE == PRE){ - task.Pre_APositions = task.APositions; - task.Pre_BPositions = task.BPositions; - } - for(var i = 0; i < Positions.length; i++){ - if(Positions[i].ContractType == task.symbolA && onlyAorBorPRE !== B){ - task.APositions = Positions[i]; - } - if(Positions[i].ContractType == task.symbolB && onlyAorBorPRE !== A){ - task.BPositions = Positions[i]; - } - } - if(Positions.length == 0){ - if(onlyAorBorPRE !== B){ - task.APositions = {MarginLevel: 0, Amount: 0, FrozenAmount: 0, Price: 0, Profit: 0, Type: 0, ContractType: ""}; - } - if(onlyAorBorPRE !== A){ - task.BPositions = {MarginLevel: 0, Amount: 0, FrozenAmount: 0, Price: 0, Profit: 0, Type: 0, ContractType: ""}; - } - if(onlyAorBorPRE !== A && onlyAorBorPRE !== B){ - task.APositions = {MarginLevel: 0, Amount: 0, FrozenAmount: 0, Price: 0, Profit: 0, Type: 0, ContractType: ""}; - task.BPositions = {MarginLevel: 0, Amount: 0, FrozenAmount: 0, Price: 0, Profit: 0, Type: 0, ContractType: ""}; - } - } -} - -function DealAction(task, AorB, amount){ - if(amount <= 0){ - throw "错误: DealAction 的 amount 参数为:" + amount; - } - if(AorB == A){ - task.e.SetContractType(task.symbolA); - task.e.SetDirection(task.action[1]); - if(task.action[1] == "buy" || task.action[1] == "closesell"){ - idA = task.e.Buy(-1, typeof(amount) == "undefined" ? Math.abs(task.action[3]) : amount, task.symbolA); - }else if(task.action[1] == "sell" || task.action[1] == "closebuy"){ - idA = task.e.Sell(-1, typeof(amount) == "undefined" ? Math.abs(task.action[3]) : amount, task.symbolA); - } - } - if(AorB == B){ - task.e.SetContractType(task.symbolB); - task.e.SetDirection(task.action[2]); - if(task.action[2] == "buy" || task.action[2] == "closesell"){ - idB = task.e.Buy(-1, typeof(amount) == "undefined" ? Math.abs(task.action[3]) : amount, task.symbolB); - }else if(task.action[2] == "sell" || task.action[2] == "closebuy"){ - idB = task.e.Sell(-1, typeof(amount) == "undefined" ? Math.abs(task.action[3]) : amount, task.symbolB); - } - } -} - -function DealActionLimit(task, AorB, Piece, isAgain){ - var tradeInfo = null; - var Price = 0; - var Piece = Math.abs(Piece); - if(isAgain){ - while(true){ - task.e.SetContractType(task.symbolA); - var Adepth = task.e.GetDepth(); - task.e.SetContractType(task.symbolB); - var Bdepth = task.e.GetDepth(); - - if(!Adepth || !Bdepth || Adepth.Asks.length === 0 || Adepth.Bids.length === 0 || Bdepth.Asks.length === 0 || Bdepth.Bids.length === 0){ - //Log("获取深度信息异常!", Adepth, Bdepth); - Sleep(Interval); - continue; - } - - task.Adepth = Adepth; - task.Bdepth = Bdepth; - - task.Adiff = _N(Adepth.Bids[0].Price - Bdepth.Asks[0].Price); - task.Bdiff = _N(Adepth.Asks[0].Price - Bdepth.Bids[0].Price); - break; - } - } - task.e.SetContractType(AorB == A ? task.symbolA : task.symbolB); - task.e.SetDirection(task.action[AorB]); - if(task.action[AorB] == "buy"){ - Price = AorB == A ? task.Adepth.Asks[0].Price : task.Bdepth.Asks[0].Price; - tradeInfo = task.P.OpenLong(AorB == A ? task.symbolA : task.symbolB, Piece, Price); - }else if(task.action[AorB] == "sell"){ - Price = AorB == A ? task.Adepth.Bids[0].Price : task.Bdepth.Bids[0].Price; - tradeInfo = task.P.OpenShort(AorB == A ? task.symbolA : task.symbolB, Piece, Price); - }else if(task.action[AorB] == "closebuy"){ - Price = AorB == A ? task.Adepth.Bids[0].Price : task.Bdepth.Bids[0].Price; - tradeInfo = task.P.Cover(AorB == A ? task.symbolA : task.symbolB, Price, Piece, PD_LONG); // task.action[AorB] - }else if(task.action[AorB] == "closesell"){ - Price = AorB == A ? task.Adepth.Asks[0].Price : task.Bdepth.Asks[0].Price; - tradeInfo = task.P.Cover(AorB == A ? task.symbolA : task.symbolB, Price, Piece, PD_SHORT); // task.action[AorB] - } - if((task.action[AorB] == "buy" || task.action[AorB] == "sell") && tradeInfo.amount === 0){ - return false; - }else if((task.action[AorB] == "closebuy" || task.action[AorB] == "closesell") && tradeInfo == 0){ - return false; - } - return tradeInfo; -} - -function CalcActualPrice(task){ - if(task.action[0] == 0){ - var A_Pv = task.APositions.Price; - var B_Pv = task.BPositions.Price; - task.dic[task.action[0]].ActualPrice = A_Pv - B_Pv; - Log(task.symbolA, A_Pv, task.symbolB, B_Pv, "#FF0000"); - }else if(task.APositions.Amount == 1 && task.BPositions.Amount == 1){ - var A_Pv = task.APositions.Price; - var B_Pv = task.BPositions.Price; - task.dic[task.action[0]].ActualPrice = A_Pv - B_Pv; - Log(task.symbolA, A_Pv, task.symbolB, B_Pv, "#FF0000"); - }else{ - var A_Pv = task.APositions.Price; - var A_P1 = task.Pre_APositions.Price; - var A_m = task.APositions.Amount - task.Pre_APositions.Amount; - var A_n = task.Pre_APositions.Amount; - - var B_Pv = task.BPositions.Price; - var B_P1 = task.Pre_BPositions.Price; - var B_m = task.BPositions.Amount - task.Pre_BPositions.Amount; - var B_n = task.Pre_BPositions.Amount; - - var A_P2 = A_Pv * A_P1 * A_m / ((A_m + A_n) * A_P1 - A_n * A_Pv); - var B_P2 = B_Pv * B_P1 * B_m / ((B_m + B_n) * B_P1 - B_n * B_Pv); - - task.dic[task.action[0]].ActualPrice = A_P2 - B_P2; - Log(task.symbolA, A_P2, task.symbolB, B_P2, "#FF0000"); - } -} - -function Hedge_Open_Cover(task){ - if(task.isUseMarketOrder === false){ // 限价单 - if((task.action[1] === "buy" && task.action[2] === "sell") || (task.action[1] === "sell" && task.action[2] === "buy")){ // open - var tradeInfo_A = DealActionLimit(task, A, task.action[3]); - var dealAmount_A = Math.abs(task.action[3]); - while(tradeInfo_A == false || (dealAmount_A -= tradeInfo_A.amount) > 0){ // 此处应该 判断是否小于 0 。 等于 0 会引起 BUG ,修改为 大于 0 - Log("合约:" + task.symbolA + "已对冲" + (tradeInfo_A == false ? 0 : tradeInfo_A.amount), "剩余,重试!张数:" + dealAmount_A); - tradeInfo_A = DealActionLimit(task, A, dealAmount_A, true); - Sleep(Interval); - } - - var tradeInfo_B = DealActionLimit(task, B, task.action[3]); - var dealAmount_B = Math.abs(task.action[3]); - while(tradeInfo_B == false || (dealAmount_B -= tradeInfo_B.amount) > 0){ - Log("合约:" + task.symbolB + "已对冲" + (tradeInfo_B == false ? 0 : tradeInfo_B.amount), "剩余,重试!张数:" + dealAmount_B); - tradeInfo_B = DealActionLimit(task, B, dealAmount_B, true); - Sleep(Interval); - } - - task.dic[task.action[0]].hold = task.action[3]; - // task.dic[task.action[0]].ActualPrice = _N(orderA.AvgPrice - orderB.AvgPrice); - }else if((task.action[1] === "closesell" && task.action[2] === "closebuy") || (task.action[1] === "closebuy" && task.action[2] === "closesell")){ // cover - var tradeInfo_A_Piece = DealActionLimit(task, A, task.action[3]); - var dealAmount_A = Math.abs(task.action[3]); - while(tradeInfo_A_Piece == false || (dealAmount_A -= tradeInfo_A_Piece) > 0){ // 此处应该 判断是否小于 0 。 等于 0 会引起 BUG ,修改为 大于 0 - Log("合约:" + task.symbolA + "已对冲" + (tradeInfo_A == false ? 0 : tradeInfo_A_Piece), "剩余,重试!张数:" + dealAmount_A); - tradeInfo_A_Piece = DealActionLimit(task, A, dealAmount_A, true); - Sleep(Interval); - } - - var tradeInfo_B_Piece = DealActionLimit(task, B, task.action[3]); - var dealAmount_B = Math.abs(task.action[3]); - while(tradeInfo_B_Piece == false || (dealAmount_B -= tradeInfo_B_Piece) > 0){ - Log("合约:" + task.symbolB + "已对冲" + (tradeInfo_B == false ? 0 : tradeInfo_B_Piece), "剩余,重试!张数:" + dealAmount_B); - tradeInfo_B_Piece = DealActionLimit(task, B, dealAmount_B, true); - Sleep(Interval); - } - - task.dic[task.action[0]].hold = 0; - task.dic[task.action[0]].ActualPrice = 0; - task.dic[task.action[0]].CoverTimes += 1; - } - Sleep(100); - }else if(task.isUseMarketOrder === true){ // 市价单 - var orderA = null; - var orderB = null; - if((task.action[1] === "buy" && task.action[2] === "sell") || (task.action[1] === "sell" && task.action[2] === "buy")){ // open - DealAction(task, A); - DealAction(task, B); - - while(!idA || !idB){ - if(!idA){ - DealAction(task, A); - } - if(!idB){ - DealAction(task, B); - } - } - - while(true){ - if(!orderA || orderA.Status !== ORDER_STATE_CLOSED){ - orderA = task.e.GetOrder(idA); - } - if(!orderB || orderB.Status !== ORDER_STATE_CLOSED){ - orderB = task.e.GetOrder(idB); - } - if(orderA && orderB && orderA.Status == ORDER_STATE_CLOSED && orderB.Status == ORDER_STATE_CLOSED){ - break; - } - Sleep(Interval); - } - - //Log("Open symbolA:", orderA, "symbolB:", orderB); - task.dic[task.action[0]].hold = task.action[3]; - task.dic[task.action[0]].ActualPrice = _N(orderA.AvgPrice - orderB.AvgPrice); - }else if((task.action[1] === "closesell" && task.action[2] === "closebuy") || (task.action[1] === "closebuy" && task.action[2] === "closesell")){ // cover - DealAction(task, A); - DealAction(task, B); - - while(!idA || !idB){ - if(!idA){ - DealAction(task, A); - } - if(!idB){ - DealAction(task, B); - } - } - - while(true){ - if(!orderA || orderA.Status !== ORDER_STATE_CLOSED){ - orderA = task.e.GetOrder(idA); - } - if(!orderB || orderB.Status !== ORDER_STATE_CLOSED){ - orderB = task.e.GetOrder(idB); - } - if(orderA && orderB && orderA.Status == ORDER_STATE_CLOSED && orderB.Status == ORDER_STATE_CLOSED){ - break; - } - Sleep(Interval); - } - - //Log("Cover symbolA:", orderA, "symbolB:", orderB); - task.dic[task.action[0]].hold = 0; - task.dic[task.action[0]].ActualPrice = 0; - task.dic[task.action[0]].CoverTimes += 1; - } - Sleep(100); // 避免访问过于频繁。 - } -} - -function TasksController(){ // 任务控制器 构造函数 - // 构造用于返回的 控制器对象 - var self = {}; - self.tasks = []; // 控制器的任务数组。 - - self.AddTask = function(e, symbolA, symbolB, HedgeList){ // 添加对冲 任务, 函数中进行 构造, 部分参数变量未初始化。在main 函数开始 根据界面参数列表,确定task 个数 进行构造。 - var task = { - // 任务的参数变量 - e : e, - symbolA : symbolA, - symbolB : symbolB, - HedgeList : HedgeList, - dic : [], - Adepth : null, - Bdepth : null, - Adiff : 0, - Bdiff : 0, - action : null, - lastUpdateLineTime : 0, - MarginLevel : MarginLevel, - isUseMarketOrder : true, - // 账户信息 - initAccount : _C(e.GetAccount), - nowAccount : null, - isFrozen : false, - FrozenStartTime : 0, - APositions : null, - BPositions : null, - Pre_APositions : null, - Pre_BPositions : null, - PositionsLastUpdateTime : 0, - isLogProfit : false, - taskProfit : 0, - State : FREE, - }; - self.tasks.push(task); - } - - self.InitTask = function(){ // 初始化 任务,设置合约 杠杆等 - _.each(self.tasks, function(task){ - var arr = task.HedgeList.split(';'); - var hedgeDirection = 1; - // 可扩展 恢复持仓,读取当前持仓。 - _.each(arr, function(pair){ - var tmp = pair.split(':'); // 把每个 网格节点的 单元 按照':'字符 分割成 参数 数组 tmp - if (tmp.length != 3) { // 由于 格式 是 30:15:1 即 开仓差价: 平仓差价: 下单量 ,所以 用 ':' 分割后 tmp长度 不是3的 即 格式错误 - throw "开仓表不正确"; // 抛出异常 格式错误 - } - var st = { // 每次迭代的时候 构造一个对象 - open: Number(tmp[0]), // 开仓 把 tmp[0] 即 30:15:1 按 ':' 分割后 生成的数组中的 第一个元素 30 , 通过 Number 函数 转换为数值 - cover: Number(tmp[1]), // 平仓.. - amount: Number(tmp[2]), // 量.. - hold: 0, // 持仓 初始为0 - ActualPrice: 0, - PointProfit : 0, // 但个仓位累计差价。 - CoverTimes : 0, // 平仓次数 - }; - task.dic.push(st); - }); - // 处理其它 初始化工作 - task.P = $.NewPositionManager(task.e); - task.isUseMarketOrder = isUseMarketOrder; // 初始是否使用市价单 - task.e.SetMarginLevel(task.MarginLevel); // 设置杠杆 - task.nowAccount = _C(task.e.GetAccount); // 初始化 当前账户信息 - // 检查, 启用的网格 是否会 耗尽资金 - if((task.dic[0].open < 0 && isCreateHedgeList) || (task.dic[0].cover < 0 && isCreateHedgeList)){ - // throw "自动网格生成错误:第一个节点开仓值、平仓值 小于0,会引起产生重复部分。" +JSON.stringify(task.dic); - } - var dic_length = task.dic.length; - var sumPiece = 0; - for(var i = 0; i < dic_length; i++){ - sumPiece += task.dic[i].amount; - } - sumPiece = sumPiece * 2; - task.e.SetContractType(task.symbolA); - var tickerA = _C(task.e.GetTicker); - task.e.SetContractType(task.symbolB); - var tickerB = _C(task.e.GetTicker); - var Margin = sumPiece * 100 * OK_Rate / ((tickerA.Last + tickerB.Last) / 2) / task.MarginLevel; - if(MarginRatio * task.initAccount.Stocks < Margin){ - if(istry == false || IsVirtual()){ - throw "满仓所需保证金:" + Margin + " 超出 限制比例: " + MarginRatio; - }else{ - Log("注意,实盘测试模式开启!#FF0000"); - } - } - Log("按照当前初始化,满仓将开" + sumPiece + "张合约,共需要 保证金:" + Margin + "BTC"); - }); - } - - self.DealTask = function(nowTime){ - // 处理task 任务 - tbls = []; // 每次初始清空 - _.each(self.tasks, function(task){ - // 迭代处理 task - task.e.SetContractType(task.symbolA); - var Adepth = task.e.GetDepth(); - task.e.SetContractType(task.symbolB); - var Bdepth = task.e.GetDepth(); - - if(!Adepth || !Bdepth || Adepth.Asks.length === 0 || Adepth.Bids.length === 0 || Bdepth.Asks.length === 0 || Bdepth.Bids.length === 0){ - return; - } - - task.Adepth = Adepth; - task.Bdepth = Bdepth; - - task.Adiff = _N(Adepth.Bids[0].Price - Bdepth.Asks[0].Price); - task.Bdiff = _N(Adepth.Asks[0].Price - Bdepth.Bids[0].Price); - - if(nowTime - task.lastUpdateLineTime > 1000 * 60){ - $.PlotLine("plus", task.Adiff); - $.PlotLine("minus", task.Bdiff); - task.lastUpdateLineTime = nowTime; - } - - // 判断解除冻结 - if(nowTime - task.FrozenStartTime > 1000 * 15 * 60 && task.isFrozen == true){ - task.isFrozen = false; - if(For_USD == false){ - var lastRate = OK_Rate; - OK_Rate = task.e.GetUSDCNY(); - task.e.SetRate(OK_Rate); - } - Log("冻结解除!", For_USD == false ? "并且更新汇率,上次汇率:" + lastRate + "更新后汇率:" + OK_Rate + "#FF0000" : "#FF0000"); - } - - // 交易逻辑 - var SumHold = task.dic.length; - for(var index = 0; index < task.dic.length && task.isFrozen == false; index++){ - if(task.dic[index].hold === 0){ - if(task.dic[index].open <= task.Adiff && task.State !== MINUS){ // 正对冲 空A 多B - task.action = [index, "sell", "buy", task.dic[index].amount]; - Log(JSON.stringify(task.action)); - Hedge_Open_Cover(task); - - $.PlotFlag(nowTime, "O", "sell-buy", "flag", "red"); - task.isLogProfit = false; - task.nowAccount = _C(task.e.GetAccount); - var Positions = _C(task.e.GetPosition); // 获取持仓信息。 - UpdatePosition(task, Positions, PRE); - Log("Open symbolA:", task.APositions, "symbolB:", task.BPositions); - CalcActualPrice(task); - task.State = PLUS; - }else if(task.dic[index].open <= -task.Bdiff && task.State !== PLUS){ // 反对冲 多A 空B - task.action = [index, "buy", "sell", -task.dic[index].amount]; - Log(JSON.stringify(task.action)); - Hedge_Open_Cover(task); - - $.PlotFlag(nowTime, "O", "buy-sell", "flag", "red"); - task.isLogProfit = false; - task.nowAccount = _C(task.e.GetAccount); - var Positions = _C(task.e.GetPosition); // 获取持仓信息。 - UpdatePosition(task, Positions, PRE); - Log("Open symbolA:", task.APositions, "symbolB:", task.BPositions); - CalcActualPrice(task); - task.State = MINUS; - }else{ - SumHold--; - } - }else{ - if(task.dic[index].hold > 0 && task.dic[index].cover >= task.Bdiff){ // 平空A 平多B - task.action = [index, "closesell", "closebuy", task.dic[index].hold]; - Log(JSON.stringify(task.action)); - // Buy_SymbolA_Sell_SymbolB(task); - Hedge_Open_Cover(task); - $.PlotFlag(nowTime, "C", "closesell-closebuy", "circlepin"); - task.nowAccount = _C(task.e.GetAccount); - var Positions = _C(task.e.GetPosition); // 获取持仓信息。 - UpdatePosition(task, Positions); - Log("Cover symbolA:", task.APositions, "symbolB:", task.BPositions); - }else if(task.dic[index].hold < 0 && task.dic[index].cover >= -task.Adiff){ // 平多A 平空B - task.action = [index, "closebuy", "closesell", task.dic[index].hold]; - Log(JSON.stringify(task.action)); - // Sell_SymbolA_Buy_SymbolB(task); - Hedge_Open_Cover(task); - $.PlotFlag(nowTime, "C", "closebuy-closesell", "circlepin"); - task.nowAccount = _C(task.e.GetAccount); - var Positions = _C(task.e.GetPosition); // 获取持仓信息。 - UpdatePosition(task, Positions); - Log("Cover symbolA:", task.APositions, "symbolB:", task.BPositions); - } - } - } - - if(SumHold != 0 && nowTime - task.PositionsLastUpdateTime > 1000 * 30){ - var Positions = _C(task.e.GetPosition); // 获取持仓信息。 - UpdatePosition(task, Positions); - task.PositionsLastUpdateTime = nowTime; - }else if(SumHold == 0 && task.isLogProfit == false){ - sumProfit = 0; - task.State = FREE; - for(var a = 0 ; a < TC.tasks.length; a++){ - sumProfit += TC.tasks[a].taskProfit; - } - LogProfit(sumProfit, "当前:", task.nowAccount, "初始:", task.initAccount); - task.taskProfit = task.nowAccount.Stocks - task.initAccount.Stocks; - task.isLogProfit = true; - } - - // 检测交割剩余时间、发送 交割前平仓命令 - CheckDelivery(nowTime, "this_week", task); // 检测 当周交割。 必须在当周交割前平仓。 - - // 测试 将数据现在状态栏 - var tbl = { - type : "table", - title : task.symbolA + "&" + task.symbolB, - cols : ["key", "value"], - rows : [] - }; - for(var key in task){ - value = task[key]; - if(key === "dic" || key === "Adepth" || key === "Bdepth" || key === "initAccount" || key === "nowAccount" || key === "isFrozen" || - key === "FrozenStartTime" || key === "P" || key === "Pre_APositions" || key === "Pre_BPositions"){ // 过滤显示 - continue; - } - if(key === "e"){ - value = "初始: " + JSON.stringify(task.initAccount) + " 当前: " + JSON.stringify(task.nowAccount); - key = task[key].GetName(); - } - tbl.rows.push([key, value]); - } - // 判断下网格方向 - if(task.dic[0].hold < 0){ - for(var j = 0; j < task.dic.length; j++){ - var task_dic = JSON.stringify(task.dic[j]); - if(task.dic[j].hold > 0){ - task_dic += "#FF0000"; - }else if(task.dic[j].hold < 0){ - task_dic += "#32CD32"; - } - tbl.rows.push([j, task_dic]); - } - }else if(task.dic[0].hold > 0){ - for(var j = task.dic.length - 1; j >= 0; j--){ - var task_dic = JSON.stringify(task.dic[j]); - if(task.dic[j].hold > 0){ - task_dic += "#FF0000"; - }else if(task.dic[j].hold < 0){ - task_dic += "#32CD32"; - } - tbl.rows.push([j, task_dic]); - } - }else{ - for(var j = 0; j < task.dic.length; j++){ - var task_dic = JSON.stringify(task.dic[j]); - if(task.dic[j].hold > 0){ - task_dic += "#FF0000"; - }else if(task.dic[j].hold < 0){ - task_dic += "#32CD32"; - } - tbl.rows.push([j, task_dic]); - } - } - tbls.push(tbl); - }); - if(tbls.length === 0){ // 容错模式,或者实盘中 可能有原因导致 _.each 迭代中 返回,tbls 为 [] ,处理此种情况。 - return; - } - LogStatus("轮询耗时:" + StrLoopTime + " 当前时间:" + _D() + MSG_String + '\n`' + JSON.stringify(tbls) + '`'); // 输出到状态栏 - } - - // 返回对象 - return self; -} - -var TC = null; // TasksController 对象 -var tbls = []; -var MSG_String = "  "; -var StrLoopTime = ""; -var OK_Rate = 0; -var SumUseTime = 0; -var times = 0; -var sumTimes = 0; -var sumProfit = 0; -function main(){ - // 测试代码 模拟界面参数 - if(isFilter){ - Log("启用过滤常规错误信息。"); - SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused"); - } - - var Positions = []; - for(var j = 0 ; j < exchanges.length ; j++){ - var position = _C(exchanges[j].GetPosition); - if(position.length !== 0){ - Positions.push(position); - } - } - if(AutoRecoveryState == false && Positions.length == 0){ // 没有持仓,并且关闭了自动恢复 - if(isCreateHedgeList == true){ - HedgeTable = CreateHedgeList(begin, end, size, step, amountOfPoint, symbolA, symbolB); - } - - // 输出对冲控制表,并检查。 - Log("对冲控制表", HedgeTable); - if(HedgeTable == "(this_week&quarter)30:15:1"){ - Log("注意!对冲控制表 当前为 默认值!可能引起亏损。"); - } - - // 创建控制器对象 - TC = TasksController(); - - var exchangesNum = 0; - var e_index = 0; - for(var i = 0; i < exchanges.length; i++){ // 遍历交易所对象数组 - exchangesNum++; - } - - var arr = HedgeTable.split('('); - - _.each(arr, function(item) { - if (item != '') { - var tmp = item.split(')'); - var pair = tmp[0].replace('(', '').split('&'); - // Log("pair:", pair, "tmp:", tmp); // 测试 显示 处理后的 控制表字符串 - TC.AddTask(exchanges[e_index], pair[0], pair[1], tmp[1]); - if(For_USD){ // 设置汇率 - OK_Rate = 1; - exchanges[e_index].SetRate(1); - Log("使用的价格为美元计价,汇率:", OK_Rate, ",请注意 ”对冲 控制表“ 是否为美元差价#FF0000"); // 币种提示 - }else{ - OK_Rate = exchanges[e_index].GetUSDCNY(); - exchanges[e_index].SetRate(OK_Rate); - Log("使用的价格为RMB计价,汇率:", OK_Rate, ",请注意 ”对冲 控制表“ 是否为RMB差价#FF0000"); // 币种提示 - } - if(--exchangesNum < 0){ - throw "添加的交易所 和 对冲控制表 不匹配!交易所个数:" + exchanges.length + " arr:" + arr; - }else if(exchangesNum !== 0){ - e_index++; - } - } - }); - - Log("交易所对象最大索引 e_index:", e_index, "关联后剩余交易所数量: exchangesNum:", exchangesNum); // 测试 - - // 调用控制器对象的初始化函数 - TC.InitTask(); - }else if(AutoRecoveryState == false && Positions.length !== 0){ // 未开启恢复,有持仓 - throw "未开启自动恢复,检测到有持仓信息:" + JSON.stringify(Positions); - }else if(AutoRecoveryState == true && Positions.length == 0 && (istry == false || IsVirtual())){ // 开启自动恢复, 无持仓信息 - throw "未检测到持仓信息,无法恢复!"; - }else{ // 恢复持仓 - Log("恢复持仓!"); - if(isCreateHedgeList == true){ - HedgeTable = CreateHedgeList(begin, end, size, step, amountOfPoint, symbolA, symbolB); - } - - // 输出对冲控制表,并检查。 - Log("对冲控制表", HedgeTable); - if(HedgeTable == "(this_week&quarter)30:15:1"){ - Log("注意!对冲控制表 当前为 默认值!可能引起亏损。"); - } - - // 创建控制器对象 - TC = TasksController(); - - var exchangesNum = 0; - var e_index = 0; - for(var i = 0; i < exchanges.length; i++){ // 遍历交易所对象数组 - exchangesNum++; - } - - var arr = HedgeTable.split('('); - - _.each(arr, function(item) { - if (item != '') { - var tmp = item.split(')'); - var pair = tmp[0].replace('(', '').split('&'); - // Log("pair:", pair, "tmp:", tmp); // 测试 显示 处理后的 控制表字符串 - TC.AddTask(exchanges[e_index], pair[0], pair[1], tmp[1]); - if(For_USD){ // 设置汇率 - OK_Rate = 1; - exchanges[e_index].SetRate(1); - Log("使用的价格为美元计价,汇率:", OK_Rate, ",请注意 ”对冲 控制表“ 是否为美元差价#FF0000"); // 币种提示 - }else{ - OK_Rate = exchanges[e_index].GetUSDCNY(); - exchanges[e_index].SetRate(OK_Rate); - Log("使用的价格为RMB计价,汇率:", OK_Rate, ",请注意 ”对冲 控制表“ 是否为RMB差价#FF0000"); // 币种提示 - } - if(--exchangesNum < 0){ - throw "添加的交易所 和 对冲控制表 不匹配!交易所个数:" + exchanges.length + " arr:" + arr; - }else if(exchangesNum !== 0){ - e_index++; - } - } - }); - - Log("交易所对象最大索引 e_index:", e_index, "关联后剩余交易所数量: exchangesNum:", exchangesNum); // 测试 - - // 调用控制器对象的初始化函数 - TC.InitTask(); - var PreTC = _G("TC"); - for(var index = 0; index < TC.tasks.length ; index++){ - for(var key in TC.tasks[index]){ - if(key == "e" || key == "Adepth" || key == "Bdepth" || key == "P"){ - continue; - } - TC.tasks[index][key] = PreTC.tasks[index][key]; - } - } - } - - while(true){ - var nowTime = new Date().getTime(); - TC.DealTask(nowTime); - Sleep(Interval); - var endTime = new Date().getTime(); - if(times < 100000){ - SumUseTime += (endTime - nowTime); - times++; - }else{ - SumUseTime = 0; - times = 0; - SumUseTime += (endTime - nowTime); - times++; - } - sumTimes++; - var avgUseTime = _N(SumUseTime / times); - StrLoopTime = (endTime - nowTime) + " ms " + "平均耗时:" + avgUseTime + "循环次数:" + sumTimes; - } -} - -function onexit(){ - Log("退出策略,自动保存状态。"); - _G("TC", TC); -} -/* -1、需要是一个 期货账户 的模式。 -2、合约开仓手续费 0.03% -3、计算手续费进开仓均价 -4、可以用市价单。 -*/ diff --git "a/OKCoin\350\267\250\346\234\237\345\270\203\346\236\227\345\257\271\345\206\262.js" "b/OKCoin\350\267\250\346\234\237\345\270\203\346\236\227\345\257\271\345\206\262.js" deleted file mode 100644 index 24f323f9..00000000 --- "a/OKCoin\350\267\250\346\234\237\345\270\203\346\236\227\345\257\271\345\206\262.js" +++ /dev/null @@ -1,538 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/43049 -策略名称: OKCoin跨期布林对冲 -策略作者: 小小梦 -策略描述: - - - - -参数 默认值 描述 --------------- --------- ------------------------------ -isLogReset false 是否清空所有日志 -P_SymbolA quarter 合约A -P_SymbolB this_week 合约B -P_Interval 500 轮询间隔 -P_isSetTest false 测试模式 -MaxUsedRatio 0.5 保证金最大使用比例 -MarginLevel 10 杠杆 -P_piece 2 每次触发开仓下单量 -CoverRatio 0.1 每次平仓比例 -minCoverAmount 2 每次平仓最小值 -P_KPeriod 0 K线周期: 1分钟|5分钟|15分钟|30分钟|1小时|1天 -Add_lv 0.05 系数递增比例 -*/ - -var P_isSetOneKLine = true; -var isShowChart = true; -var retrySlidePrice = 2; - -// 全局变量 -var KPeriod = [PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_D1][P_KPeriod]; -var DiffData = { // 差价K线数据 - plusKLine : [], // 差价K线数组 - minusKLine : [], - KPeriod : KPeriod, // 差价K线周期 -}; - -var distance = 0; // 距离 -var IDLE = 0; -var PLUS = 1; -var MINUS = 2; -var State = IDLE; // 策略 运行状态状态 -var perState = IDLE; - -var OPEN = 3; // 用于区分 是那种操作 在 BuyA_SellB 、 SellA_BuyB 函数中 -var COVER = 4; -var isTradeOnThisBar = false; // 是否在当前Bar 交易了 废弃 -var isCoverOnthisBar = false; // 废弃 -var upRatio = 0; -var downRatio = 0; - -var P = null; // 交易控制对象 -var ManagerData = { // 控制对象 - initAccount : null, // 初始账户 信息 - Account : null, // 当前账户 信息 - perAccount : null, - MaxUsedRatio : MaxUsedRatio, // 最大 保证金使用率 - MaxUsedMargin : 0, // 每次 平仓后 重新计算的 最大保证金使用量 - APosition : null, // 多头 仓位信息 - BPosition : null, // 空头 仓位信息 - floatProfit : 0, // 浮动盈亏 - CoverProfit : 0, // 平仓盈亏 - MarginLevel : MarginLevel, // 杠杆数 - Margin : 0, // 当前保证金使用 - - // 行情数据 - DepthA : null, // A 合约的 深度数据 - DepthB : null, // B 合约的 深度数据 - - // 错误信息 - ErrorStr : "", // 错误信息字符串 - ErrorTimeStamp : 0, // 错误信息 时间戳 -} - -var DiffDataOneKLine = { // K线结构 - KLine : [], // K线数组 ,整理后的差价 - KPeriod : KPeriod, // K线周期 -} -var test = { // 测试 模式 使用的结构 - amount : 4, - ProfitDiff : 0, - ID : 0, - OpenDiff : 0, -}; -var perRecordsTime = 0; // 合成的 K线 上一个bar 的时间戳 - -var PeriodBeginTime = 0; // 周期起始时间 - -function UpdateDiffData(DepthA, DepthB, RecordsA, RecordsB){ // 处理差价K线数据的更新 - var plusDiff = DepthA.Bids[0].Price - DepthB.Asks[0].Price; - var minusDiff = DepthA.Asks[0].Price - DepthB.Bids[0].Price; - if(P_isSetOneKLine){ - var Diff = _N((plusDiff + minusDiff) / 2 , 4); - } - if(RecordsA[RecordsA.length - 1].Time == RecordsB[RecordsB.length - 1].Time && RecordsB[RecordsB.length - 1].Time !== PeriodBeginTime){ - if(!P_isSetOneKLine){ - // 新K线周期出现 - var plusBar = { - Open : plusDiff, - Close : plusDiff, - High : plusDiff, - Low : plusDiff, - Time : 0, - }; - - var minusBar = { - Open : minusDiff, - Close : minusDiff, - High : minusDiff, - Low : minusDiff, - Time : 0, - }; - - PeriodBeginTime = RecordsB[RecordsB.length - 1].Time; - plusBar.Time = PeriodBeginTime; - minusBar.Time = PeriodBeginTime; - DiffData.plusKLine.push(plusBar); - DiffData.minusKLine.push(minusBar); - }else{ - var Bar = { - Open : Diff, - Close : Diff, - High : Diff, - Low : Diff, - Time : 0, - }; - PeriodBeginTime = RecordsB[RecordsB.length - 1].Time; - Bar.Time = PeriodBeginTime; - DiffDataOneKLine.KLine.push(Bar); - } - }else{ - if(!P_isSetOneKLine){ - if(plusDiff > DiffData.plusKLine[DiffData.plusKLine.length - 1].High){ - DiffData.plusKLine[DiffData.plusKLine.length - 1].High = plusDiff; - }else if(plusDiff < DiffData.plusKLine[DiffData.plusKLine.length - 1].Low){ - DiffData.plusKLine[DiffData.plusKLine.length - 1].Low = plusDiff; - } - DiffData.plusKLine[DiffData.plusKLine.length - 1].Close = plusDiff; - - if(minusDiff > DiffData.minusKLine[DiffData.minusKLine.length - 1].High){ - DiffData.minusKLine[DiffData.minusKLine.length - 1].High = minusDiff; - }else if(minusDiff < DiffData.minusKLine[DiffData.minusKLine.length - 1].Low){ - DiffData.minusKLine[DiffData.minusKLine.length - 1].Low = minusDiff; - } - DiffData.minusKLine[DiffData.minusKLine.length - 1].Close = minusDiff; - }else{ - if(Diff > DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].High){ - DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].High = Diff; - }else if(Diff < DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Low){ - DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Low = Diff; - } - DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close = Diff; - } - } - - if(!P_isSetOneKLine){ - if(DiffData.plusKLine.length > 100){ - DiffData.plusKLine.shift(); - } - - if(DiffData.minusKLine.length > 100){ - DiffData.minusKLine.shift(); - } - }else{ - if(DiffDataOneKLine.KLine.length > 100){ - DiffDataOneKLine.KLine.shift(); - } - } -} - -function UseAPI(fun, symbol, param){ - exchange.SetContractType(symbol); - if(typeof(param) == "undefined"){ - return fun(); - }else{ - return fun(param); - } -} - -function GetPositions(){ - var positions = _C(exchange.GetPosition); - for(var i = 0; i < positions.length; i++){ - if(positions[i].ContractType == P_SymbolA){ - ManagerData.APosition = positions[i]; - }else if(positions[i].ContractType == P_SymbolB){ - ManagerData.BPosition = positions[i]; - }else if(i == 2){ - throw "error:" + JSON.stringify(positions); - } - } - if(positions.length == 0){ - ManagerData.APosition = null; - ManagerData.BPosition = null; - } - return positions; -} - -function SellA_BuyB(DiffPrice, Action){ - // GetBestAmount - var Piece = P_piece; - if(Action == OPEN){ - // 检查 是否超出 保证金 - var MarginAndAmount_A = CalcPieceEqualAmount(ManagerData.DepthA.Bids[0].Price, Piece); - var MarginAndAmount_B = CalcPieceEqualAmount(ManagerData.DepthB.Asks[0].Price, Piece); - if(MarginAndAmount_A.NeedMargin + MarginAndAmount_B.NeedMargin + ManagerData.Margin > ManagerData.MaxUsedMargin){ - ManagerData.ErrorStr = "超过最大可用保证金:" + ManagerData.MaxUsedMargin; - ManagerData.ErrorTimeStamp = new Date().getTime(); - return false; - } - // 交易 - _C(exchange.SetContractType, P_SymbolA); - var infoA = P.OpenShort(P_SymbolA, Piece, ManagerData.DepthA.Bids[0].Price); - if(infoA.amount == 0){ - return false; - } - _C(exchange.SetContractType, P_SymbolB); - var dealAmount = infoA.amount; - var infoB = P.OpenLong(P_SymbolB, dealAmount, ManagerData.DepthB.Asks[0].Price); - var slidePrice = retrySlidePrice; - while((dealAmount -= infoB.amount) > 0){ - infoB = P.OpenLong(P_SymbolB, dealAmount, ManagerData.DepthB.Asks[0].Price + slidePrice); - slidePrice += retrySlidePrice; - LogStatus("while(), P_SymbolB:", P_SymbolB, infoB, dealAmount, slidePrice); - } - - // 更新数据 - ManagerData.perAccount = ManagerData.Account; - ManagerData.Account = _C(exchange.GetAccount); - ManagerData.Margin += (ManagerData.perAccount.Stocks - ManagerData.Account.Stocks); - Log("持仓信息:", GetPositions(), "本次使用保证金:", (ManagerData.perAccount.Stocks - ManagerData.Account.Stocks)); - perState = State; - State = PLUS; - }else if(Action == COVER){ - // 全平 - _C(exchange.SetContractType, P_SymbolA); - var infoA = P.Cover(P_SymbolA, ManagerData.DepthA.Bids[0].Price, Math.min(ManagerData.APosition.Amount, Math.max(_N(ManagerData.APosition.Amount * CoverRatio, 0), minCoverAmount)), PD_LONG); - if(infoA == 0){ - return false; - } - _C(exchange.SetContractType, P_SymbolB); - var dealAmount = infoA; - var infoB = P.Cover(P_SymbolB, ManagerData.DepthB.Asks[0].Price, dealAmount, PD_SHORT); - var slidePrice = retrySlidePrice; - while((dealAmount -= infoB) > 0){ - infoB = P.Cover(P_SymbolB, ManagerData.DepthB.Asks[0].Price + slidePrice, dealAmount, PD_SHORT); - slidePrice += retrySlidePrice; - LogStatus("while(), P_SymbolB:", P_SymbolB, infoB, dealAmount, slidePrice); - } - Log("持仓信息:", GetPositions()); - if(ManagerData.APosition == null && ManagerData.BPosition == null){ - perState = State; - State = IDLE; - upRatio = 0; - downRatio = 0; - Log("完全平仓!#FF0000"); - Log("更新最大保证金使用量:", DealManagerData()); - LogProfit(ManagerData.Account.Stocks - ManagerData.initAccount.Stocks); // ceshi - }else{ - ManagerData.perAccount = ManagerData.Account; - ManagerData.Account = _C(exchange.GetAccount); - Log("部分平仓:", infoA); - } - } - return true; -} - -function BuyA_SellB(DiffPrice, Action){ - // GetBestAmount - var Piece = P_piece; - if(Action == OPEN){ - // 检查 是否超出 保证金 - var MarginAndAmount_A = CalcPieceEqualAmount(ManagerData.DepthA.Asks[0].Price, Piece); - var MarginAndAmount_B = CalcPieceEqualAmount(ManagerData.DepthB.Bids[0].Price, Piece); - if(MarginAndAmount_A.NeedMargin + MarginAndAmount_B.NeedMargin + ManagerData.Margin > ManagerData.MaxUsedMargin){ - ManagerData.ErrorStr = "超过最大可用保证金:" + ManagerData.MaxUsedMargin; - ManagerData.ErrorTimeStamp = new Date().getTime(); - return false; - } - // 交易 - _C(exchange.SetContractType, P_SymbolA); - var infoA = P.OpenLong(P_SymbolA, Piece, ManagerData.DepthA.Asks[0].Price); - if(infoA.amount == 0){ - return false; - } - _C(exchange.SetContractType, P_SymbolB); - var dealAmount = infoA.amount; - var infoB = P.OpenShort(P_SymbolB, dealAmount, ManagerData.DepthB.Bids[0].Price); - var slidePrice = retrySlidePrice; - while((dealAmount -= infoB.amount) > 0){ - infoB = P.OpenShort(P_SymbolB, dealAmount, ManagerData.DepthB.Bids[0].Price - slidePrice); - slidePrice += retrySlidePrice; - LogStatus("while(), P_SymbolB:", P_SymbolB, infoB, dealAmount, slidePrice); - } - - // 更新数据 - ManagerData.perAccount = ManagerData.Account; - ManagerData.Account = _C(exchange.GetAccount); - ManagerData.Margin += (ManagerData.perAccount.Stocks - ManagerData.Account.Stocks); - Log("持仓信息:", GetPositions(), "本次使用保证金:", (ManagerData.perAccount.Stocks - ManagerData.Account.Stocks)); - perState = State; - State = MINUS; - }else if(Action == COVER){ - // 全平 - _C(exchange.SetContractType, P_SymbolA); - var infoA = P.Cover(P_SymbolA, ManagerData.DepthA.Asks[0].Price, Math.min(ManagerData.APosition.Amount, Math.max(_N(ManagerData.APosition.Amount * CoverRatio, 0), minCoverAmount)), PD_SHORT); - if(infoA == 0){ - return false; - } - _C(exchange.SetContractType, P_SymbolB); - var dealAmount = infoA; - var infoB = P.Cover(P_SymbolB, ManagerData.DepthB.Bids[0].Price, dealAmount, PD_LONG); - var slidePrice = retrySlidePrice; - while((dealAmount -= infoB) > 0){ - infoB = P.Cover(P_SymbolB, ManagerData.DepthB.Bids[0].Price - slidePrice, dealAmount, PD_LONG); - slidePrice += retrySlidePrice; - LogStatus("while(), P_SymbolB:", P_SymbolB, infoB, dealAmount, slidePrice); - } - Log("持仓信息:", GetPositions()); - if(ManagerData.APosition == null && ManagerData.BPosition == null){ - perState = State; - State = IDLE; - upRatio = 0; // 重置 - downRatio = 0; // 重置 - Log("完全平仓!#FF0000"); - Log("更新最大保证金使用量:", DealManagerData()); - LogProfit(ManagerData.Account.Stocks - ManagerData.initAccount.Stocks); // ceshi - }else{ - ManagerData.perAccount = ManagerData.Account; - ManagerData.Account = _C(exchange.GetAccount); - Log("部分平仓:", infoA); - } - } - return true; -} - -function DealManagerData(){ // 处理 ManagerData - ManagerData.perAccount = ManagerData.Account; - ManagerData.Account = _C(exchange.GetAccount); // 获取 平仓后的 账户信息 - var Position = _C(exchange.GetPosition); // 获取 平仓后的持仓信息 - if(Position.length == 0){ // 如果 平仓完成 ,没有持仓了 重置 ManagerData 的 持仓信息属性 - ManagerData.APosition = null; - ManagerData.BPosition = null; - ManagerData.Margin = 0; // 重置 当前使用的保证金 为 0 - }else{ // 如果有持仓 报错,打印持仓 - Log("平仓后还有持仓!", Position, "#FF0000"); - throw "error!"; - } - ManagerData.MaxUsedMargin = _N(ManagerData.Account.Stocks * ManagerData.MaxUsedRatio, 2); // 计算下一轮 最大的 保证金使用量 - return ManagerData.MaxUsedMargin; -} - -function CalcPieceEqualAmount(Price, Piece){ - return { - EqualAmount : (100 / Price * Piece), - NeedMargin : (100 / Price * Piece) / ManagerData.MarginLevel, - } -} - -function Loop(nowTime){ // 主循环 - var DepthA = UseAPI(exchange.GetDepth, P_SymbolA); - var DepthB = UseAPI(exchange.GetDepth, P_SymbolB); - - var RecordsA = UseAPI(exchange.GetRecords, P_SymbolA, KPeriod); - var RecordsB = UseAPI(exchange.GetRecords, P_SymbolB, KPeriod); - - // 过滤数据 - if(!RecordsA || !RecordsB || !DepthA || !DepthB || DepthA.Bids.length == 0 || DepthA.Asks.length == 0 || - DepthB.Bids.length == 0 || DepthB.Asks.length == 0 || RecordsA.length == 0 || RecordsB.length == 0){ - return; - } - - ManagerData.DepthA = DepthA; - ManagerData.DepthB = DepthB; - - // 更新 差价K线数据 - UpdateDiffData(DepthA, DepthB, RecordsA, RecordsB); - - if(isShowChart == true){ - if(!P_isSetOneKLine){ - $.PlotRecords(DiffData.plusKLine, 'plus'); - }else{ - $.PlotRecords(DiffDataOneKLine.KLine, 'KLine'); - } - } - - // BOLL - if(P_isSetOneKLine && DiffDataOneKLine.KLine.length > 20){ - var boll = TA.BOLL(DiffDataOneKLine.KLine); - var up = boll[0]; - var mid = boll[1]; - var down = boll[2]; - - if(perRecordsTime !== DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time){ - if(isShowChart == true){ - $.PlotLine("up", up[up.length - 2], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 2].Time); - $.PlotLine("mid", mid[mid.length - 2], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 2].Time); - $.PlotLine("down", down[down.length - 2], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 2].Time); - - $.PlotLine("up", up[up.length - 1], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time); - $.PlotLine("mid", mid[mid.length - 1], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time); - $.PlotLine("down", down[down.length - 1], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time); - - // $.PlotHLine(up[up.length - 1], 'UpTrack', "red"); - // $.PlotHLine(down[down.length - 1], 'DownTrack', "green"); - } - perRecordsTime = DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time; - isTradeOnThisBar = false; // 重置 是否当前Bar 交易的标记为 false - isCoverOnthisBar = false; - }else{ - if(isShowChart == true){ - $.PlotLine("up", up[up.length - 1], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time); - $.PlotLine("mid", mid[mid.length - 1], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time); - $.PlotLine("down", down[down.length - 1], DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time); - - // $.PlotHLine(up[up.length - 1], 'UpTrack', "red"); - // $.PlotHLine(down[down.length - 1], 'DownTrack', "green"); - } - } - - - // 突破判断 - // 计算加仓距离 - distance = _N((up[up.length - 1] - down[down.length - 1]) * 0.5, 0); - - if(distance * 2 < 20 && (upRatio == 0 && downRatio == 0)){ // 计算安全间距 - return; - } - - if(DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close > up[up.length - 1]){ - if((State == IDLE || State == PLUS) && (DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close > (up[up.length - 1] + upRatio * distance)) /*&& isTradeOnThisBar == false*/){ // Open PLUS - if(P_isSetTest){ - // 模拟 - $.PlotFlag(nowTime, 'plus', 'P', 'flag', 'red'); - State = PLUS; - exchange.Log(LOG_TYPE_SELL, test.ID++, DepthA.Bids[0].Price, test.amount, "Open:" + P_SymbolA); - exchange.Log(LOG_TYPE_BUY, test.ID++, DepthB.Asks[0].Price, test.amount, "Open:" + P_SymbolB); - test.OpenDiff = DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close; - }else{ - var info = SellA_BuyB(DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close, OPEN); - if(info == false){ - return; - } - $.PlotFlag(nowTime, 'plus', 'P', 'flag', 'red'); - isTradeOnThisBar = true; - upRatio += Add_lv; - } - }else if(State == MINUS /*&& isCoverOnthisBar == false*/){ // Cover MINUS - if(P_isSetTest){ - // 模拟 - $.PlotFlag(nowTime, 'Cover_Minus', 'CM', 'circlepin', 'blue'); - State = IDLE; - exchange.Log(LOG_TYPE_SELL, test.ID++, DepthA.Bids[0].Price, test.amount, "Cover:" + P_SymbolA); - exchange.Log(LOG_TYPE_BUY, test.ID++, DepthB.Asks[0].Price, test.amount, "Cover:" + P_SymbolB); - test.ProfitDiff += DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close - test.OpenDiff; - Log("本次盈亏:" + (DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close - test.OpenDiff)); - LogProfit(test.ProfitDiff); - }else{ - // SellA_BuyB - var info = SellA_BuyB(DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close, COVER); - if(info == false){ - Log("MINUS 平仓失败!"); - return; - } - $.PlotFlag(nowTime, 'Cover_Minus', 'CM', 'circlepin', 'blue'); - isCoverOnthisBar = true; - } - } - }else if(DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close < down[down.length - 1]){ - if((State == IDLE || State == MINUS) && (DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close < (down[down.length - 1] - downRatio * distance)) /*&& isTradeOnThisBar == false*/){ - if(P_isSetTest){ - // 模拟 - $.PlotFlag(nowTime, 'minus', 'M', 'circlepin', 'green'); // DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Time - State = MINUS; - exchange.Log(LOG_TYPE_BUY, test.ID++, DepthA.Asks[0].Price, test.amount, "Open:" + P_SymbolA); - exchange.Log(LOG_TYPE_SELL, test.ID++, DepthB.Bids[0].Price, test.amount, "Open:" + P_SymbolB); - test.OpenDiff = DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close; - }else{ - // BuyA_SellB - var info = BuyA_SellB(DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close, OPEN); - if(info == false){ - return; - } - $.PlotFlag(nowTime, 'minus', 'M', 'circlepin', 'green'); - isTradeOnThisBar = true; - downRatio += Add_lv; - } - }else if(State == PLUS /*&& isCoverOnthisBar == false*/){ - if(P_isSetTest){ - // 模拟 - $.PlotFlag(nowTime, 'Cover_Plus', 'CP', 'flag', 'blue'); - State = IDLE; - exchange.Log(LOG_TYPE_BUY, test.ID++, DepthA.Asks[0].Price, test.amount, "Cover:" + P_SymbolA); - exchange.Log(LOG_TYPE_SELL, test.ID++, DepthB.Bids[0].Price, test.amount, "Cover:" + P_SymbolB); - test.ProfitDiff += test.OpenDiff - DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close; - Log("本次盈亏:" + (test.OpenDiff - DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close)); - LogProfit(test.ProfitDiff); - }else{ - // BuyA_SellB - var info = BuyA_SellB(DiffDataOneKLine.KLine[DiffDataOneKLine.KLine.length - 1].Close, COVER); - if(info == false){ - Log("PLUS 平仓失败!"); - return; - } - $.PlotFlag(nowTime, 'Cover_Plus', 'CP', 'flag', 'blue'); - isCoverOnthisBar = true; - } - } - } - } - -} - -function main(){ - // 初始化工作 - if(isLogReset){ - LogReset(1); - } - Log("最大保证金使用量:", DealManagerData()); - ManagerData.initAccount = ManagerData.Account; - ManagerData.perAccount = ManagerData.Account; - exchange.SetMarginLevel(ManagerData.MarginLevel); // 初始设置杠杆 - - // 设置禁用汇率 - exchange.SetRate(1); - Log("已禁用汇率,显示价格为美元价格!"); - - // 创建交易控制对象 - P = $.NewPositionManager(exchange); - - //主要循环 - while(true){ - var nowTime = new Date().getTime(); - Loop(nowTime); - LogStatus("时间:", _D(nowTime), '\n', P_isSetTest ? JSON.stringify(test) : "Margin: " + ManagerData.Margin, '\n', ManagerData.ErrorStr, _D(ManagerData.ErrorTimeStamp), '\n', - ManagerData.initAccount, '\n', ManagerData.Account, '\n', ManagerData.APosition, '\n', ManagerData.BPosition, '\n', "upRatio:" + upRatio, '\n', "downRatio:" + downRatio, "distance:" + distance); - Sleep(P_Interval); - } -} diff --git "a/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" "b/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" index 944dd3f4..a20dfe72 100644 --- "a/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" +++ "b/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" @@ -93,10 +93,14 @@ def UpdateCMD(self): global listener cmd = GetCommand() if cmd : + cmdList = cmd.split(":") + if len(cmdList) == 2 : # 增加了 对于 主策略 交互的 冲突 检测。 + Log("接收到 TableTemplet 模板以外的 交互命令!", cmdList) + return if listener[cmd] : listener[cmd](cmd) else : - Log("找不到名为:" + cmd + "的命令") + Log("TableTemplet 模板中找不到名为:" + cmd + "的命令") def LogStatus(self, before, end): self.UpdateCMD() diff --git a/README.md b/README.md index c53f0b96..f2542fbe 100644 --- a/README.md +++ b/README.md @@ -4,22 +4,43 @@ > 开源策略列表 + - [数字货币现货交易类库](https://www.botvs.com/strategy/10989) + - [数字货币交易类库 (期货支持OKCoin期货/BitVC, 支持$.CTA函数)](https://www.botvs.com/strategy/57267) + - [五线向上&&突破前高](https://www.botvs.com/strategy/76827) + - [C++ API调用例子](https://www.botvs.com/strategy/61533) + - [python版CTP商品期货交易类库(支持2/3 测试版)](https://www.botvs.com/strategy/24288) + - [商品期货交易类库](https://www.botvs.com/strategy/12961) + - [定期定额投资BTC盈利验证](https://www.botvs.com/strategy/65030) + - [双平台对冲js版本(two platforms hedging-JS)](https://www.botvs.com/strategy/57556) + - [转换任意K线周期管理模板(最近更新20180118)](https://www.botvs.com/strategy/41163) + - [代替废弃的GetMinStock()函数](https://www.botvs.com/strategy/69436) + - [Shannon's Demon (Copy)](https://www.botvs.com/strategy/69034) + - [MA_20180107 (Copy)](https://www.botvs.com/strategy/69033) + - [Python版 TableTemplet (测试版)](https://www.botvs.com/strategy/46031) + - [网格(波段)香农版](https://www.botvs.com/strategy/67495) + - [价值平均定投](https://www.botvs.com/strategy/67128) + - [定投简单版](https://www.botvs.com/strategy/67098) + - [策略框架模板](https://www.botvs.com/strategy/30861) + - [不要怂就是干 (Copy)](https://www.botvs.com/strategy/65114) + - [Shannon's Demon](https://www.botvs.com/strategy/64455) + - [画线类库](https://www.botvs.com/strategy/27293) + - [talib简单应用之查找三只乌鸦](https://www.botvs.com/strategy/62163) + - [回测保存K线到本地CSV](https://www.botvs.com/strategy/61867) + - [02顺大势逆小势策略之代码实现及可行性分析 (Share 1513097042)](https://www.botvs.com/strategy/63223) + - [03基于商品期货的套利策略模型 (Share 1513096985)](https://www.botvs.com/strategy/63221) + - [数字货币现货交易类库c++](https://www.botvs.com/strategy/62140) + - [幽灵交易者策略 (Share 1512580165)](https://www.botvs.com/strategy/62303) + - [bitfinex保证金交易](https://www.botvs.com/strategy/57333) + - [双平台对冲js版本(two platforms hedging-JS) (Copy)](https://www.botvs.com/strategy/61405) + - [2014年的简易短线机器人 (Copy) (Share 1512130985)](https://www.botvs.com/strategy/61398) - [2014年的简易短线机器人](https://www.botvs.com/strategy/1088) - [python版 Dual Thrust OKCoin 期货](https://www.botvs.com/strategy/21856) - - [商品期货交易类库](https://www.botvs.com/strategy/12961) - [简单多品种商品期货均线策略](https://www.botvs.com/strategy/57029) - - [数字货币现货交易类库](https://www.botvs.com/strategy/10989) - - [数字货币交易类库 (期货支持OKCoin期货/BitVC, 支持$.CTA函数)](https://www.botvs.com/strategy/57267) - [测试 默认 参数组功能](https://www.botvs.com/strategy/40155) - - [转换任意K线周期管理模板(最近更新20171113)](https://www.botvs.com/strategy/41163) - [全球10大交易系统之 Aberration 多品种商品期货交易系统](https://www.botvs.com/strategy/25943) - [Dual Thrust 商品期货](https://www.botvs.com/strategy/13011) - [python版 画线类库 (兼容2/3)](https://www.botvs.com/strategy/39066) - - [画线类库](https://www.botvs.com/strategy/27293) - [BotVS 商品期货 量化 测试入门 策略](https://www.botvs.com/strategy/59120) - - [数字货币差价监控分析](https://www.botvs.com/strategy/21337) - - [bitfinex保证金交易](https://www.botvs.com/strategy/57333) - - [双平台对冲js版本(two platforms hedging-JS)](https://www.botvs.com/strategy/57556) - [如何找出一定Bar数量的 K线前期高点、低点 及 Demo 程序](https://www.botvs.com/strategy/58179) - [python版现货数字货币交易类库](https://www.botvs.com/strategy/21104) - [数字货币交易类库 (期货支持OKCoin期货/BitVC)](https://www.botvs.com/strategy/30199) @@ -32,17 +53,12 @@ - [数字货币定投](https://www.botvs.com/strategy/54256) - [双平台对冲 练习用 求交流求指点](https://www.botvs.com/strategy/53512) - [仓位均衡策略](https://www.botvs.com/strategy/54182) - - [OKCoin期货跨期对冲策略](https://www.botvs.com/strategy/34878) - [Hedge_BTC/ETH Demo](https://www.botvs.com/strategy/48536) - [多均线策略](https://www.botvs.com/strategy/47144) - - [策略框架模板](https://www.botvs.com/strategy/30861) - [均线MA指标使用范例](https://www.botvs.com/strategy/46484) - - [Python版 TableTemplet (测试版)](https://www.botvs.com/strategy/46031) - - [python版CTP商品期货交易类库(支持2/3 测试版)](https://www.botvs.com/strategy/24288) - [Python 精简多品种 MACD 趋势策略](https://www.botvs.com/strategy/43965) - [JS版 商品期货 精简多品种 MACD 趋势策略框架](https://www.botvs.com/strategy/44593) - [TableTemplet](https://www.botvs.com/strategy/44319) - - [OKCoin跨期布林对冲](https://www.botvs.com/strategy/43049) - [Ma单均线趋势交易](https://www.botvs.com/strategy/42451) - [KingKeltner趋势策略_低频](https://www.botvs.com/strategy/42283) - [buy-hold 买入持有](https://www.botvs.com/strategy/41786) @@ -55,6 +71,7 @@ - [商品期货结算单平仓盈亏历史查询](https://www.botvs.com/strategy/38083) - [Convert_Record_Cycle](https://www.botvs.com/strategy/37678) - [转换任意K线周期](https://www.botvs.com/strategy/35986) + - [测试-CTP商品期货连接状态 (图表显示)](https://www.botvs.com/strategy/22838) - [API 测试新手入门](https://www.botvs.com/strategy/4) - [实盘账户模拟器](https://www.botvs.com/strategy/35977) - [js R-Breaker](https://www.botvs.com/strategy/36195) diff --git a/Shannon's Demon (Copy).js b/Shannon's Demon (Copy).js new file mode 100644 index 00000000..64235d4a --- /dev/null +++ b/Shannon's Demon (Copy).js @@ -0,0 +1,52 @@ +/* +策略出处: https://www.botvs.com/strategy/69034 +策略名称: Shannon's Demon (Copy) +策略作者: ellajella-0378 +策略描述: + + + + +参数 默认值 描述 +----- ----- -------- +DELAY 30 平衡间隔 +DS 1.04 Sell +DB 1.08 Buy +RSIB 80 RSI Buy +RSIS 20 RSI Sell +*/ + +function onTick(){ + var Account = exchange.GetAccount(); + var Depth = exchange.GetDepth(); + var Buy = Depth.Asks[1].Price; + var Sell = Depth.Bids[1].Price; + var StockValue = Account.Stocks * Buy; + var TotalValue = Account.Balance + StockValue; + var Half = TotalValue / 2; + var Records = exchange.GetRecords(PERIOD_M1); + var RSI = TA.RSI(Records, 14); + //Log("StockValue:", StockValue ," TotalValue:", TotalValue); + var LastRSI = RSI[RSI.length -1]; + //Log(LastRSI); + if (StockValue / Half > DS && LastRSI > RSIS) { + Log("StockValue:", StockValue ," TotalValue:", TotalValue); + Log("StockValue Too High. Re Balancing..."); + var ToBeSold = (Account.Stocks * Buy - Account.Balance) / 2 / Buy; + Log(exchange.Sell(Buy,ToBeSold)); + Sleep(DELAY*1000*5); + } + if (Half / StockValue > DB && LastRSI < RSIB) { + Log("StockValue:", StockValue ," TotalValue:", TotalValue); + Log("StockValue Too Low. Re Balancing..."); + var ToBeBought = (Account.Balance - Account.Stocks * Buy) / 2 / Sell; + Log(exchange.Buy(Sell,ToBeBought)); + Sleep(DELAY*1000*5); + } +} +function main(){ + while(true){ + onTick(); + Sleep(DELAY*1000); + } +} diff --git a/Shannon's Demon.js b/Shannon's Demon.js new file mode 100644 index 00000000..9ea6a5d3 --- /dev/null +++ b/Shannon's Demon.js @@ -0,0 +1,52 @@ +/* +策略出处: https://www.botvs.com/strategy/64455 +策略名称: Shannon's Demon +策略作者: FawkesPan +策略描述: + + + + +参数 默认值 描述 +----- ----- -------- +DELAY 30 平衡间隔 +DS 1.04 Sell +DB 1.08 Buy +RSIB 80 RSI Buy +RSIS 20 RSI Sell +*/ + +function onTick(){ + var Account = exchange.GetAccount(); + var Depth = exchange.GetDepth(); + var Buy = Depth.Asks[1].Price; + var Sell = Depth.Bids[1].Price; + var StockValue = Account.Stocks * Buy; + var TotalValue = Account.Balance + StockValue; + var Half = TotalValue / 2; + var Records = exchange.GetRecords(PERIOD_M1); + var RSI = TA.RSI(Records, 14); + //Log("StockValue:", StockValue ," TotalValue:", TotalValue); + var LastRSI = RSI[RSI.length -1]; + //Log(LastRSI); + if (StockValue / Half > DS && LastRSI > RSIS) { + Log("StockValue:", StockValue ," TotalValue:", TotalValue); + Log("StockValue Too High. Re Balancing..."); + var ToBeSold = (Account.Stocks * Buy - Account.Balance) / 2 / Buy; + Log(exchange.Sell(Buy,ToBeSold)); + Sleep(DELAY*1000*5); + } + if (Half / StockValue > DB && LastRSI < RSIB) { + Log("StockValue:", StockValue ," TotalValue:", TotalValue); + Log("StockValue Too Low. Re Balancing..."); + var ToBeBought = (Account.Balance - Account.Stocks * Buy) / 2 / Sell; + Log(exchange.Buy(Sell,ToBeBought)); + Sleep(DELAY*1000*5); + } +} +function main(){ + while(true){ + onTick(); + Sleep(DELAY*1000); + } +} diff --git "a/bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.js" "b/bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.js" index fa679451..cfb8619d 100644 --- "a/bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.js" +++ "b/bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.js" @@ -40,6 +40,18 @@ $.bitfinexGetPosition = function(){ return position } +//直接使用exchange.GetOrder(id)就可以了,不需要调用模板 +$.bitfinexGetOrder = function(order_id){ + var order = exchanges[bitfinexIndex].IO("api", "POST", "/v1/order/status", "order_id=", parseInt(order_id)) + return order +} + +//直接用exchange.CancelOrder(id)就可以取消订单,不需要调用模板 +$.bitfinexCancelOrder = function(order_id){ + //var result = exchanges[bitfinexIndex].IO("api", "POST", "/v1/order/cancel", "order_id=", parseInt(order_id)) + //return order +} + //返回margin钱包一共可以交易多少USD(虚拟币会换成美元加入计算) $.marginBalance = function(){ var balance = exchanges[bitfinexIndex].IO("api", "POST", "/v1/margin_infos") diff --git "a/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" "b/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" index 51a13f6c..5771dacc 100644 --- "a/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" +++ "b/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" @@ -128,7 +128,7 @@ def Open(e, contractType, direction, opAmount): if needOpen < insDetail['MinLimitOrderVolume']: break depth = _C(e.GetDepth) - amount = min(insDetail['MinLimitOrderVolume'], needOpen) + amount = min(insDetail['MaxLimitOrderVolume'], needOpen) e.SetDirection("buy" if direction == PD_LONG else "sell") orderId = None if direction == PD_LONG: @@ -535,7 +535,7 @@ def Profit(self): # contractType JS 版本有该参数 def CreateNewPositionManager(e = exchange): # 导出函数实现 if e not in exchanges: raise Exception("error exchange", e) - if e.GetName() != 'Futures_CTP': + if (versionMainValue != 3 and e.GetName() != 'Futures_CTP') or (versionMainValue == 3 and e.GetName() != 'Futures_CTP'): raise Exception("error exchange, 本模板适用于CTP商品期货,当前添加的交易所为:", e.GetName()); obj_NewPositionManager = NewPositionManager(e) return obj_NewPositionManager diff --git "a/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" "b/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" new file mode 100644 index 00000000..87742a36 --- /dev/null +++ "b/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" @@ -0,0 +1,31 @@ +/* +策略出处: https://www.botvs.com/strategy/62163 +策略名称: talib简单应用之查找三只乌鸦 +策略作者: Zero +策略描述: + + + +*/ + +/*backtest +start: 2017-11-11 00:00:00 +end: 2017-11-12 12:00:00 +period: 1h +exchanges: [{"eid":"OKCoin_EN","currency":"BTC"}] +*/ + +function main() { + while (true) { + var r = exchange.GetRecords(); + var pos = _.indexOf(talib.CDL3BLACKCROWS(r), -100); + // 找到三只乌鸦的形态而且是在当前最后一个K线形成的 + if (pos != -1 && pos == r.length - 1) { + Log("K线索引:", pos, r.length, "时间:", _D(r[pos].Time)); + // 下个卖单, 这们回测图表会有一个买单的标志 + exchange.Sell(_C(exchange.GetTicker).Buy, 0.1); + throw "找到三只乌鸦"; + } + Sleep(1000); + } +} diff --git "a/\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262 (Copy).js" "b/\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262 (Copy).js" new file mode 100644 index 00000000..a4277892 --- /dev/null +++ "b/\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262 (Copy).js" @@ -0,0 +1,74 @@ +/* +策略出处: https://www.botvs.com/strategy/65114 +策略名称: 不要怂就是干 (Copy) +策略作者: woopoin +策略描述: + +"Talk is cheap. Show me the code" + + +注: ` 策略使用了交易模板类库` + +`希望新手从此策略入门, 一步步学习编写策略, 并体验到模拟与真实环境对交易系统的影响` + +https://dn-filebox.qbox.me/fb4d0c7d773ca83e9d0230927705d419dc0bbeaa.png + + +参数 默认值 描述 +------------- ----- ------- +EnterPeriod 2 入市观察期 +FastPeriod 5 入市快线周期 +SlowPeriod 30 入市慢线周期 +PositionRatio true 仓位比例 +Interval 10 轮询周期(秒) +SlidePrice 0.01 滑动值 + +按钮 默认值 描述 +---- ---------- ---- +简单策略 __button__ 不懂 +*/ + +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); + } +} diff --git "a/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" "b/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" new file mode 100644 index 00000000..51fa946f --- /dev/null +++ "b/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" @@ -0,0 +1,48 @@ +''' +策略出处: https://www.botvs.com/strategy/76827 +策略名称: 五线向上&&突破前高 +策略作者: 围龙小子 +策略描述: + +均线策略(python版)教学性质,实盘慎用。 + +''' + +import types +import peakutils +import os +import time +import numpy +def main(): + MA_LINES = ['5_8','5_13','5_21','5_34','8_13','8_21','8_34','13_21','13_34','21_34'] + initAccount = ext.GetAccount() + reported_price_list = [] + while True: + lines_up = True + for lines in MA_LINES: + data = lines.split('_') + FastPeriod,SlowPeriod = int(data[0]),int(data[1]) + n = ext.Cross(FastPeriod,SlowPeriod) + if n <= 0: + lines_up = False + break + + if lines_up == True: + records = exchange.GetRecords(PERIOD_M30) + current_price = records[-1].get("Close", 0) + times = [record.get("Time", 0) for record in records] + y = [record.get("High", 0) for record in records] + x = [i for i in xrange(1,len(y)+1)] + x, y = numpy.array(x),numpy.array(y) + n_peaks = 2 + prepared = y - peakutils.baseline(y, 3) + idx = peakutils.indexes(prepared, thres=0.03, min_dist=10) + previous_high = y[sorted(idx.tolist()[:10])[-1]] + previous_time = int(str(times[idx.tolist()[-1]])[:-3]) + previous_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(previous_time)) + if current_price >= previous_high: + if previous_high not in reported_price_list: + Log("五线向上,突破前期:",previous_time,"的高点:",previous_high, "当前价格:",current_price) + reported_price_list.append(previous_high) + + Sleep(1000) diff --git "a/\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.js" "b/\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.js" new file mode 100644 index 00000000..d1cbe563 --- /dev/null +++ "b/\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.js" @@ -0,0 +1,37 @@ +/* +策略出处: https://www.botvs.com/strategy/69436 +策略名称: 代替废弃的GetMinStock()函数 +策略作者: hugo_zhou +策略描述: + + + +*/ + +/**************** + 针对 火币pro 获取不同货币对的最小交易量 + 其他平台需要自行添加不同的错误解析代码 +****************/ + +function main() { + SetErrorFilter("limit order amount error"); + //加入你想知道的货币对 + var huobipro = ["BTC_USDT","XRP_USDT","EOS_BTC","OMG_ETH"]; + + for(var i = 0;i= 0){ + var min = parseFloat(error.split(": `")[1]); + _G(exchange.GetName()+exchange.GetCurrency(),min); + } + } + + //从数据库中打印出来 + for(var j = 0;j singleInvestAmount * 0.1) { + exchange.Buy(buy1price, (expectValue - currentValue) / buy1price); + } else if (expectValue - currentValue < - singleInvestAmount * 0.1) { + exchange.Sell(sell1price, (currentValue - expectValue) / sell1price); + } + } +} + diff --git "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS) (Copy).js" "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS) (Copy).js" new file mode 100644 index 00000000..4bfe7fa3 --- /dev/null +++ "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS) (Copy).js" @@ -0,0 +1,225 @@ +/* +策略出处: https://www.botvs.com/strategy/61405 +策略名称: 双平台对冲js版本(two platforms hedging-JS) (Copy) +策略作者: ellajella-0378 +策略描述: + + + + +参数 默认值 描述 +------------ ------ -------- +MinSpreadA 0.51 A->B差价 +MinSpreadB 0.52 B->A差价 +MaxAmount 0.3 最大操作量 +BalanceTime 10 平衡周期(秒) +LoopInterval 200 轮询周期(ms) + +按钮 默认值 描述 +---- ----- ---------- +A->B 0.51 更改价差(A->B) +B->A 0.52 更改价差(B->A) +*/ + +function cancelAll(){ + var ref = false; + for(var e in exchanges){ + while(true){ + var n = 0; + var my_orders = _C(exchanges[e].GetOrders); + for(var order1 in my_orders){ + ref = true; + e.CancelOrder(my_orders[order1].Id); + n += 1; + } + if(n==0){ + break; + } + } + } + return ret +} + +function main(){ + if(exchanges.length != 2){ + throw("Only two exchanges are supported"); + } + + LogReset(); + LogProfitReset(); + cancelAll(); + + var initStocks = 0.0; + var initBalance = 0.0; + var minAmount = 0.1; + var lastTradeTime = 0; + var lastTradeErrExchange = ''; + var accountsCache = []; + var hedgeNum = [0, 0]; + var names = []; + var baseCurrency = exchange.GetCurrency(); + for(var e in exchanges){ + if(exchanges[e].GetCurrency() != baseCurrency){ + throw("It has to be the same currency to hedge:"+baseCurrency); + } + names.push(exchanges[e].GetName()); + var account = _C(exchanges[e].GetAccount); + accountsCache.push(account); + initStocks += account.Stocks; + initBalance += account.Balance; + } + if(baseCurrency == "BTC"){ + minAmount = 0.01 + } else { + minAmount = 0.1 + } + + Log("all balance:", _N(initBalance), "all stocks", _N(initStocks)) + while(true){ + if(accountsCache.length <= 0){ + for(var e in exchanges){ + var account1 = _C(exchanges[e].GetAccount); + accountsCache.push(account1); + } + } + Sleep(LoopInterval); + cmd = GetCommand(); + if(cmd){ + Log("CMD", cmd); + var arr = cmd.split(":"); + if(arr[0]=="A->B"){ + MinSpreadA = parseFloat(arr[1]); + } else if(arr[0]=="B->A"){ + MinSpreadB = parseFloat(arr[1]); + } + } + var depthA = exchanges[0].GetDepth(); + if (!depthA){ + continue; + } + var depthB = exchanges[1].GetDepth(); + if (!depthB){ + continue; + } + var time = new Date(); + if(lastTradeTime > 0 && time.getTime() - lastTradeTime > BalanceTime){ + var needUpdate = cancelAll(); + if (!needUpdate){ + for(var account2 in accountsCache){ + if(accountsCache[account2].FrozenBalance >= 0.1 || accountsCache[account2].FrozenStocks >= 0.001){ + needUpdate = true; + break; + } + } + } + if (needUpdate){ + for(var k in exchanges){ + account3 = _C(exchanges[k].GetAccount); + accountsCache.push(account3); + } + } + var nowStocks = 0.0; + var nowBalance = 0.0; + for(var account4 in accountsCache){ + nowBalance += accountsCache[account4].Balance; + nowStocks += accountsCache[account4].Stocks; + } + var diff = _N(nowStocks-initStocks, 5); + var isReverse; + if(Math.abs(diff) < minAmount){ + LogProfit(_N(nowBalance-initBalance, 3), "all balance", _N(nowBalance), "all stocks", _N(nowStocks), "stock offset:", diff); + lastTradeTime = 0; + } else if(diff > minAmount){ + isReverse = depthA.Bids[0].Price < depthB.Bids[0].Price; + } else if(-diff > minAmount){ + isReverse = depthA.Asks[0].Price > depthB.Asks[0].Price; + } + if(isReverse != null){ + var depths = [depthA, depthB]; + var opAmount; + var kk; + if(isReverse){ + kk = [1, 0]; + } else{ + kk = [0, 1]; + } + for(var pos in kk){ + if(diff > minAmount){ + opAmount = Math.min(diff, accountsCache[pos].Stocks, depths[pos].Bids[0].Amount + depths[pos].Bids[1].Amount); + diff = -opAmount; + if(opAmount >= minAmount){ + exchanges[pos].Sell(depths[pos].Bids[1].Price, opAmount); + } + } else if(-diff >= minAmount){ + opAmount = Math.min(-diff, _N(accountsCache[pos].Balance / depths[pos].Asks[1].Price, 3), depths[pos].Asks[0].Amount + depths[pos].Asks[1].Amount); + diff += opAmount; + if (opAmount >= minAmount){ + exchanges[pos].Buy(depths[pos].Asks[1].Price, opAmount); + } + } + } + if (opAmount != undefined){ + var time1 = new Date(); + lastTradeTime = time1.getTime(); + accountsCache = []; + } + } + continue; + } + var diffA = _N(depthA.Bids[0].Price - depthB.Asks[0].Price, 3) + var diffB = _N(depthB.Bids[0].Price - depthA.Asks[0].Price, 3) + LogStatus(JSON.stringify({type: 'table', title: 'status', cols: ['name', 'money', 'frozenmoney', 'stock', 'frozenstock', 'buyone', 'sellone', 'threshold', 'offset', 'num of times'], rows: [[names[0], accountsCache[0].Balance, accountsCache[0].FrozenBalance, accountsCache[0].Stocks, accountsCache[0].FrozenStocks, depthA.Bids[0].Price, depthA.Asks[0].Price, MinSpreadA, diffA, hedgeNum[0]], [names[1], accountsCache[1].Balance, accountsCache[1].FrozenBalance, accountsCache[1].Stocks, accountsCache[1].FrozenStocks, depthB.Bids[0].Price, depthB.Asks[0].Price, MinSpreadB, diffB, hedgeNum[0]]]})); + HPos = 0; + if (diffA >= MinSpreadA){ + orderH = depthA.Bids[0]; + orderL = depthB.Asks[0]; + exchangeH = 0; + exchangeL = 1; + accountH = accountsCache[0]; + accountL = accountsCache[1]; + } + else if (diffB >= MinSpreadB){ + HPos = 1; + orderH = depthB.Bids[0]; + orderL = depthA.Asks[0]; + exchangeH = 1; + exchangeL = 0; + accountH = accountsCache[1]; + accountL = accountsCache[0]; + } + else{ + continue; + } + + var opPrice = _N((orderH.Price + orderL.Price) / 2.0, 2); + var opAmount = Math.min(MaxAmount, orderH.Amount, orderL.Amount, accountH.Stocks, _N(accountL.Balance / opPrice, 3)); + if(opAmount >= minAmount){ + var tasks = [[exchangeH, "H"], [exchangeL, "L"]]; + if(lastTradeErrExchange == "L"){ + tasks.reverse(); + } + lastTradeErrExchange = ""; + for(var task in tasks){ + if(tasks[task][1] == "H"){ + var id = exchanges[tasks[task][0]].Sell(opPrice, opAmount); + if(id == undefined){ + lastTradeErrExchange = tasks[task][1]; + break; + } + } + if(tasks[task][1] == "L"){ + var id = exchanges[tasks[task][0]].Buy(opPrice, opAmount); + if(id == undefined){ + lastTradeErrExchange = tasks[task][1]; + break; + } + } + } + + var time = new Date(); + lastTradeTime = time.getTime(); + accountsCache = [] + hedgeNum[HPos] += 1 + } + } +} diff --git "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" index 63f826b2..89dab984 100644 --- "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" +++ "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" @@ -37,7 +37,7 @@ function cancelAll(){ } } } - return ret + return ref; } function main(){ diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" index 74627562..024658b6 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" @@ -72,9 +72,10 @@ SyncInterval 5 账户与持仓同步周期(秒) */ /*backtest -start: 2017-08-01 00:00:00 -end: 2017-10-10 00:00:00 +start: 2018-01-15 00:00:00 +end: 2018-01-30 00:00:00 period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] */ var __orderCount = 0 @@ -241,7 +242,7 @@ function Cover(e, contractType, lots) { if (typeof(lots) == 'number' && amountChange >= lots) { break; } - + for (var i = 0; i < positions.length; i++) { if (positions[i].ContractType != contractType) { continue; @@ -442,14 +443,14 @@ var PositionManager = (function() { if (positions[i].ContractType.indexOf('&') != -1) { Log("开始平掉", positions[i]); Cover(this.e, positions[i].ContractType) - Sleep(1000) + Sleep(Interval) } } for (var i = 0; i < positions.length; i++) { if (positions[i].ContractType.indexOf('&') == -1) { Log("开始平掉", positions[i]); Cover(this.e, positions[i].ContractType) - Sleep(1000) + Sleep(Interval) } } } @@ -595,7 +596,7 @@ $.NewTaskQueue = function(onTaskFinish) { arg: typeof(onFinish) !== 'undefined' ? arg : undefined, onFinish: typeof(onFinish) == 'undefined' ? arg : onFinish } - + switch (task.action) { case "buy": task.desc = task.symbol + " 开多仓, 数量 " + task.amount @@ -692,7 +693,11 @@ $.NewTaskQueue = function(onTaskFinish) { } var remain = task.amount; if (isCover && !pos) { - pos = {Amount:0, Cost: 0, Price: 0} + pos = { + Amount: 0, + Cost: 0, + Price: 0 + } } if (pos) { task.dealAmount = pos.Amount - task.preAmount; @@ -785,9 +790,6 @@ $.NewTaskQueue = function(onTaskFinish) { if (processed == 0) { self.tasks = [] } - } else { - // wait for master market update - exchange.IO("wait") } return processed } @@ -796,7 +798,7 @@ $.NewTaskQueue = function(onTaskFinish) { if (typeof(symbol) !== 'string') { return self.tasks.length > 0 } - + for (var i = 0; i < self.tasks.length; i++) { if (self.tasks[i].symbol == symbol && !self.tasks[i].finished) { return true @@ -804,7 +806,7 @@ $.NewTaskQueue = function(onTaskFinish) { } return false } - + self.size = function() { return self.tasks.length } @@ -820,7 +822,7 @@ $.Cross = function(arr1, arr2) { throw "array length not equal"; } var n = 0; - for (var i = arr1.length-1; i >= 0; i--) { + for (var i = arr1.length - 1; i >= 0; i--) { if (typeof(arr1[i]) !== 'number' || typeof(arr2[i]) !== 'number') { break; } @@ -851,7 +853,7 @@ onTick(r, mp, symbol): 无返回值表示什么也不做 */ $.CTA = function(contractType, onTick, interval) { - SetErrorFilter("login") + SetErrorFilter("login|ready|初始化") if (typeof(interval) !== 'number') { interval = 500 } @@ -865,23 +867,39 @@ $.CTA = function(contractType, onTick, interval) { var product = ins2product(ct) for (var i = 0; i < symbols.length; i++) { var tmp = symbols[i].split('/') - if (ins2product(tmp[tmp.length-1]) == product) { + if (ins2product(tmp[tmp.length - 1]) == product) { return tmp[0] } } return null } - var refreshHold = function() { + var refreshHold = function(qSize) { + if (typeof(qSize) === 'undefined') { + qSize = 0 + } while (!e.IO("status")) { + LogStatus(_D(), "Not connect") Sleep(1000) } - + _.each(symbols, function(ins) { var tmp = ins.split('/') if (tmp.length == 2) { - holds[tmp[0]] = {price:0, value:0, amount:0, profit: 0, symbol: tmp[1]} + holds[tmp[0]] = { + price: 0, + value: 0, + amount: 0, + profit: 0, + symbol: tmp[1] + } } else { - holds[ins] = {price:0, value:0, amount:0, profit: 0, symbol: ins} + holds[ins] = { + price: 0, + value: 0, + amount: 0, + profit: 0, + symbol: ins + } } }); var positions = _C(e.GetPosition); @@ -895,12 +913,12 @@ $.CTA = function(contractType, onTick, interval) { return } if (pos.Type == PD_LONG || pos.Type == PD_LONG_YD) { - if (hold.amount < 0) { + if (hold.amount < 0 && qSize == 0) { throw "不能同时持有多仓空仓" } hold.amount += pos.Amount } else { - if (hold.amount > 0) { + if (hold.amount > 0 && qSize == 0) { throw "不能同时持有多仓空仓" } hold.amount -= pos.Amount @@ -929,10 +947,10 @@ $.CTA = function(contractType, onTick, interval) { return account } - var account = refreshHold() + var account = refreshHold(0) var q = $.NewTaskQueue(function(task, ret) { Log("任务结束", task.desc) - account = refreshHold() + account = refreshHold(q.size()) }) var mainCache = [] while (true) { @@ -945,7 +963,6 @@ $.CTA = function(contractType, onTick, interval) { ctChart = tmp[0] ctTrade = tmp[1] } - if (!e.IO("status") || !$.IsTrading(ctChart) || !$.IsTrading(ctTrade) || q.hasTask(ctTrade)) { return } @@ -953,7 +970,7 @@ $.CTA = function(contractType, onTick, interval) { // 正在移仓 return } - + // 先获取行情 var c = e.SetContractType(ctChart) if (!c) { @@ -963,34 +980,47 @@ $.CTA = function(contractType, onTick, interval) { if (!r || r.length == 0) { return } - + // 切换到需要交易的合约上来 var insDetail = e.SetContractType(ctTrade) if (!insDetail) { return } var tradeSymbol = insDetail.InstrumentID - // 处理主力合约切换, 指数合约在交易时也默认映射到主力合约上 if (ctTrade.indexOf('888') !== -1 || ctTrade.indexOf('000') !== -1) { var preMain = '' var isSwitch = false + var positions = null; if (typeof(mainCache[ctTrade]) === 'undefined') { if (!IsVirtual()) { Log(ctTrade, "当前主力合约为:", tradeSymbol) } - } else if (mainCache[ctTrade][0] != tradeSymbol) { - preMain = mainCache[ctTrade][0] - // 开始切换 - var positions = e.GetPosition() + positions = e.GetPosition() if (!positions) { return } + var product = ins2product(ctTrade); + _.each(positions, function(p) { + if (ins2product(p.ContractType) == product) { + mainCache[ctTrade] = [p.ContractType, p.ContractType]; + } + }); + } + if (typeof(mainCache[ctTrade]) !== 'undefined' && mainCache[ctTrade][0] != tradeSymbol) { + preMain = mainCache[ctTrade][0] Log(ctTrade, "主力合约切换为:", tradeSymbol, "之前为:", preMain, "#ff0000") + // 开始切换 + if (!positions) { + positions = e.GetPosition() + if (!positions) { + return + } + } _.each(positions, function(p) { - if (p.contractType == preMain) { + if (p.ContractType == preMain) { var isLong = p.Type == PD_LONG || p.Type == PD_LONG_YD - q.pushTask(e, p.contractType, (isLong ? "closebuy" : "closesell"), p.Amount, function(task, ret) { + q.pushTask(e, p.ContractType, (isLong ? "closebuy" : "closesell"), p.Amount, function(task, ret) { Log("切换合约平仓成功", task.desc, ret) }) q.pushTask(e, tradeSymbol, (isLong ? "buy" : "sell"), p.Amount, function(task, ret) { @@ -1000,7 +1030,7 @@ $.CTA = function(contractType, onTick, interval) { } }) } - mainCache[ctTrade] = [tradeSymbol, preMain] + mainCache[ctTrade] = [tradeSymbol, preMain] if (isSwitch) { // Wait switch compeleted Log("开始移仓", preMain, "移到", tradeSymbol) @@ -1009,7 +1039,14 @@ $.CTA = function(contractType, onTick, interval) { } var hold = holds[ctChart]; - var n = onTick({records: r, symbol: tradeSymbol, account: account, position: hold, positions: holds}) + var n = onTick({ + records: r, + symbol: tradeSymbol, + detail: insDetail, + account: account, + position: hold, + positions: holds + }) var callBack = null if (typeof(n) == 'object' && typeof(n.length) == 'number' && n.length > 1) { if (typeof(n[1]) == 'function') { @@ -1042,10 +1079,10 @@ $.CTA = function(contractType, onTick, interval) { } }) q.poll() - + var now = new Date().getTime() - if ((now - lastUpdate) > (SyncInterval*1000)) { - account = refreshHold() + if ((now - lastUpdate) > (SyncInterval * 1000)) { + account = refreshHold(q.size()) } var delay = interval - (now - ts) if (delay > 0) { diff --git "a/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.py" "b/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.py" new file mode 100644 index 00000000..7f57dac2 --- /dev/null +++ "b/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.py" @@ -0,0 +1,46 @@ +''' +策略出处: https://www.botvs.com/strategy/61867 +策略名称: 回测保存K线到本地CSV +策略作者: botvsing +策略描述: + + + +''' + +''' +/*backtest +start: 2017-10-01 +end: 2017-11-16 +period: 1440 +periodBase: 15 +mode: 0 +*/ +''' + +#需要用的pandas库,并且用自己的托管回测才能保存到本地 +#import numpy as np +import pandas as pd + +#保存路径 +path = 'C:\\Users\\Public\\Documents\\' + +def main(): + df=pd.DataFrame() + while True: + records = _C(exchange.GetRecords) + df_new = pd.DataFrame(records) #把records转为dataframe + df_new['Time'] = pd.to_datetime(df_new['Time'],unit='ms')+pd.Timedelta('8 h') + df_new.index = df_new['Time'] + if df.empty or df_new['Time'].min() >= df['Time'].max(): + df=df.combine_first(df_new) + Log(df['Time'].max()) + #确定最后一次时间,用于保存数据 + if df_new['Time'].max() == pd.Timestamp('2017-11-15 23:45:00'): + Log('保存数据') + df=df.combine_first(df_new) + df.to_csv(path+'records15.csv',index=False) + break + #休眠时间是选择周期 + Sleep(15*60*1000) + diff --git "a/\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2 (Copy).py" "b/\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2 (Copy).py" deleted file mode 100644 index 88301238..00000000 --- "a/\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2 (Copy).py" +++ /dev/null @@ -1,236 +0,0 @@ -''' -策略出处: https://www.botvs.com/strategy/37664 -策略名称: 均线-趋势_数字货币策略V0.2 (Copy) -策略作者: victoro -策略描述: - -@太极 QQ7650371 -#均线/趋势 策略 -#通过判断 在死叉下底后回弹多少买入 -#在金叉上扬至顶后下降多少卖出 - - -参数 默认值 描述 --------------- ------------------------------------------------------------------------------ ------------------ -FastPeriod 2 开仓快线周期 -SlowPeriod 4 开仓慢线周期 -EnterPeriod true 开仓观察期 -x ------------------------------------------------------------------------------ 分割符号 -ExitFastPeriod 2 平仓快线周期 -ExitSlowPeriod 4 平仓慢线周期 -ExitPeriod 2 平仓观察期 -xx ------------------------------------------------------------------------------ 分割符号 -PositionRatio 0.5 仓位比例 -Interval 10 轮询周期(秒) -xxx ------------------------------------------------------------------------------ 分割符号 -MAType 0 均线类型: TA.EMA|TA.MA -''' - -#!/usr/local/bin/python -#-*- coding: UTF-8 -*- -#均线/趋势 策略 -#通过判断 在死叉下底后回弹多少买入 -#在金叉上扬至顶后下降多少卖出 - - -# FastPeriod=3 #开仓快线周期 -# SlowPeriod=7 #开仓慢线周期 -# EnterPeriod=1 #开仓观察期 -# ExitFastPeriod=3 #平仓线周期 -# ExitSlowPeriod=7 #平仓慢线周期 -# ExitPeriod=2 #平仓观察期 -# PositionRatio=0.5 #仓位比例 -# Interval=10 #轮询周期 -# MAType=0 #均线类型 TA.EMA|TA.MA - - -import types -array = [TA.EMA,TA.MA] -_MACalcMethod = array[MAType] -def Cross(a,b): #计算均线方法 - crossNum = 0 - arr1 = [] - arr2 = [] - if(type(a) == types.ListType and type(b) == types.ListType): - arr1 = a - arr2 = b - else: - records = null - while True: - records = exchange.GetRecords() - if(records and len(records) > a and len(records) > b): - break - Sleep(Interval) - arr1 = _MACalcMethod(records,a) - arr2 = _MACalcMethod(records,b) - if(len(arr1) != len(arr2)): - raise Exception("array length not equal") - for i in range(len(arr1) - 1,-1,-1): - if((type(arr1[i]) != types.IntType and type(arr1[i]) != types.FloatType) or (type(arr2[i]) != types.IntType and type(arr2[i]) != types.FloatType) ): - break - if(arr1[i] < arr2[i]): - if(crossNum > 0): - break - crossNum -= 1 - elif(arr1[i] > arr2[i]): - if(crossNum < 0): - break - crossNum += 1 - else: - break - return crossNum - -import datetime -def Caltime(date1,date2): - try: - date1=time.strptime(date1,"%Y-%m-%d %H:%M:%S") - date2=time.strptime(date2,"%Y-%m-%d %H:%M:%S") - date1=datetime.datetime(date1[0],date1[1],date1[2],date1[3],date1[4],date1[5]) - date2=datetime.datetime(date2[0],date2[1],date2[2],date2[3],date2[4],date2[5]) - return date2-date1 - except Exception,ex: - Log('except Exception Caltime:',ex) - return "except Exception" - -import time -start_timexx =time.localtime(time.time()) #time.clock() -start_time=time.strftime("%Y-%m-%d %H:%M:%S",start_timexx) -buy_price=0 #买入价格 -buy_qty=0 #买入数量 -gains=0 #盈利 - -def my_buy(): #开仓 - try: - global buy_price,buy_qty - initAccount = ext.GetAccount() #交易模板的导出函数, 获得账户状态,保存策略运行前账户初始状态 - opAmount=1 - #开仓之前判断有币没有没有先进行买入 - if int(initAccount.Stocks)>1: - if buy_price<1: - buy_price=_C(exchange.GetTicker).Last - buy_qty=initAccount.Stocks - Log('开仓信息1 仓内还有比:',initAccount.Stocks,'进行清空','--开仓详情:',initAccount) - return 1 - if int(initAccount.Stocks)<1: - if int(str(initAccount.Stocks).replace('0.',''))>=1: - if buy_price<1: - buy_price=_C(exchange.GetTicker).Last - buy_qty=initAccount.Stocks - Log('开仓信息2 仓内还有比:',initAccount.Stocks,'进行清空','--开仓详情:',initAccount) - return 1 - - #if int(initAccount.Stocks)<1: - if int(str(initAccount.Stocks).replace('0.',''))==0: - #opAmount=1 - opAmount = _N(initAccount.Balance*PositionRatio,3) #买入数量 - Log("开仓没有币先进行 开仓买入%s元"%(str(opAmount))) #生成LOG日志 - # else: - # opAmount = _N(initAccount.Stocks * PositionRatio,3) #获取交易数量 - # else: - # opAmount = _N(initAccount.Stocks * PositionRatio,3) #获取交易数量 - Dict = ext.Buy(opAmount) #买入ext.Buy - if(Dict):#确认开仓成功 - buy_price=Dict['price'] #买入价格 #{'price': 4046.446, 'amount': 1.5} - buy_qty=Dict['amount'] #买入数量 - print_log(1,initAccount,Dict) - return 1 - return 0 - - except Exception,ex: - Log('except Exception my_buy:',ex) - return 0 - -outAccount = ext.GetAccount() #初始化信息 -def print_log(k_p,Account,Dict): - try: - global outAccount - name="" - if k_p: - LogProfit(_N(gains,4),'开仓信息 钱:',Account.Balance,'--币:',Account.Stocks,'--开仓详情:',Dict) - name="开仓" - else: - LogProfit(_N(gains,4),'平仓信息 钱:',Account.Balance,'--币:',Account.Stocks,'--平仓详情:',Dict) - name="平仓" - endAccount = ext.GetAccount() #初始化信息 - date1=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time())) - LogStatus("初始化投入2016/9/16 投入资金2000元\r\n", - "本次初始化状态:",outAccount, - "\r\n当前运 行状态:",endAccount, - "\r\n本次开始运行时间:%s 已运行:%s\r\n"%(start_time,Caltime(start_time,date1)), - "本次盈利:%s\r\n"%(str(gains)), - "当前状态:%s--钱:%s--币:%s\r\n"%(str(name),str(Account.Balance),str(Account.Stocks)), - "更新时间:%s"%(date1) - ) # 测试 - except Exception,ex: - Log('except Exception print_log:',ex) - - -def my_sell(): #平仓 - try: - global buy_price,buy_qty,gains,start_time - nowAccount = ext.GetAccount() #交易模板的导出函数 获取账户信息 - if _C(exchange.GetTicker).Last>buy_price+4: #当前价格一定要大于 开仓价格 - Dict = ext.Sell(nowAccount.Stocks) - if(Dict): - sell_gains=(Dict['price']-buy_price)*Dict['amount'] - gains=gains+sell_gains - buy_price=0 #买入价格 - buy_qty=0 #买入数量 - print_log(0,nowAccount,Dict) - return 1 - return 0 - except Exception,ex: - Log('except Exception my_sell:',ex) - return 0 - -def main(): - global outAccount - STATE_IDLE = -1 #空闲状态 - state = STATE_IDLE #初始化 状态 为 空闲 - - Log("run ",outAccount) #输出初始账户信息 - SetErrorFilter("GetAccount|GetRecords|GetTicker") #屏蔽错误内容 - - b=0 #开仓 - b1=0 #检测次数 - a=0 #平仓 - a1=0 #检测次数 - while True: - if(state == STATE_IDLE): #判断状态是否 为空闲 触发开仓 - #开仓 - n = Cross(FastPeriod,SlowPeriod) #模板函数获取EMA指标快线、慢线交叉结果 - if n<0: #确定当前为死叉 - b1+=1 - if b>=int(n): #说明现在还是在下跌涨趋势 - b=int(n) - else: #开始下跌 开仓 - if(int(n)>=int(b)+int(EnterPeriod)): #确认上行走势 至自己定义的点 - if my_buy(): #开仓 - b=0 - b1=0 - state = PD_SHORT - # if(b1>=10):#小波动操作开仓 - # b1=0 - # if my_buy(): - # b=0 - # state = PD_SHORT - else:#平仓 - n = Cross(ExitFastPeriod,ExitSlowPeriod) #模板函数获取EMA指标快线、慢线交叉结果 - if n>0: #确定当前为金叉 - a1+=1 - if a<=int(n): #说明现在还是在上涨趋势 - a=int(n) - else: #开始下跌 平仓 - if(int(n)<=int(a)-int(ExitPeriod)): #确认下行走势 至自己定义的点 - if my_sell(): #平仓 - a=0 - a1=0 - state = STATE_IDLE #更改状态 为空闲 触发开仓 - # if(a1>=10): #小波动操作平仓 - # a1=0 - # if my_sell(): - # a=0 - # state = STATE_IDLE #更改状态 为空闲 触发开仓 - Sleep(Interval * 1000) - - diff --git "a/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.js" "b/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.js" new file mode 100644 index 00000000..1baa1d28 --- /dev/null +++ "b/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.js" @@ -0,0 +1,76 @@ +/* +策略出处: https://www.botvs.com/strategy/67098 +策略名称: 定投简单版 +策略作者: 小码哥 +策略描述: + + + + +参数 默认值 描述 +------------------ ----- ----- +singleInvestAmount 0.1 单次买入量 +*/ + +// botvs@620e5a1b33965b615ef40e1d29cd2c44 + +/*backtest + start: 2017-12-01 + end: 2018-01-01 + period: 60 + mode: 2 +*/ + +function dateFormat(date, format) { + var o = { + "M+": date.getMonth() + 1, //月份 + "d+": date.getDate(), //日 + "h+": date.getHours(), //小时 + "m+": date.getMinutes(), //分 + "s+": date.getSeconds(), //秒 + "q+": Math.floor((date.getMonth() + 3) / 3), //季度 + "S": date.getMilliseconds() //毫秒 + }; + if (/(y+)/.test(format)) { + format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length)); + } + + for (var k in o) { + if (new RegExp("(" + k + ")").test(format)) { + format = format.replace(RegExp.$1, (RegExp.$1.length == 1) ? + (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); + } + } + + return format; +} + + +function main() { + Log(exchange.GetAccount()); + + //最近一次投资的日期 + var lastInvestDate = ''; + + while (true) { + //每次轮询,间隔时间为60秒 + Sleep(60 * 1000); + + //如果当前日期和最近一次投资日期相同,说明当天已经投过了,跳过 + var date = dateFormat(new Date(), "yyyy-MM-dd"); + if (date == lastInvestDate) { + continue; + } + + lastInvestDate = date; + Log("日期: " + date); + + //获取当前深度 + var depth = exchange.GetDepth(); + + //以买1价挂一个买入单 + var buy1price = depth.Bids[0].Price; + exchange.Buy(buy1price, singleInvestAmount / buy1price); + } +} + diff --git "a/\345\271\275\347\201\265\344\272\244\346\230\223\350\200\205\347\255\226\347\225\245 (Share 1512580165).js" "b/\345\271\275\347\201\265\344\272\244\346\230\223\350\200\205\347\255\226\347\225\245 (Share 1512580165).js" new file mode 100644 index 00000000..8b9d8cd9 --- /dev/null +++ "b/\345\271\275\347\201\265\344\272\244\346\230\223\350\200\205\347\255\226\347\225\245 (Share 1512580165).js" @@ -0,0 +1,181 @@ +/* +策略出处: https://www.botvs.com/strategy/62303 +策略名称: 幽灵交易者策略 (Share 1512580165) +策略作者: ellajella-0378 +策略描述: + +#### 前言 +正如幽灵交易者的名字,该策略的核心思路是,在真实下单交易之前,先虚拟出一个交易,如果这个虚拟的交易是亏损的,那么下一次才启动真实的交易。 + +. + +#### 策略简介 +* 该策略思路源自于交易者的观察,交易者从自己的交易记录中发现,如果上一次交易是盈利的,那么下一次交易亏损的概率比较大。因此在设计策略时,人为的控制了这些可能会亏损的交易。 + +* 具体在策略中,我们将引入虚拟交易和与之对应的真实下单模块。也就是说,虚拟交易一直在运行,而真实下单模块直到上一笔虚拟交易是亏损的,并且达到指定的交易条件的情况下才执行。 + +. + +#### 策略原始需求 +* K线数据 +![此处输入图片的描述][1] + +* 短期指数平均线 +* 长期指数平均线 +![此处输入图片的描述][2] + +* RSI 指标 +![此处输入图片的描述][3] + +* 唐奇安通道 +![此处输入图片的描述][4] + +. + +#### 入场条件 +* 多头开仓:如果当前没有持仓,并且上次虚拟交易时发生过一次亏损,并且短期均线在长期均线之上,并且 RSI 低于超卖值,并且价格创新高。 +* 空头开仓:如果当前没有持仓,并且上次虚拟交易时发生过一次亏损,并且短期均线在长期均线之下,并且 RSI 高于超买值,并且价格创新低。 + +. + +#### 出场条件 +* 多头平仓:如果当前持有多单,并且价格下破唐奇安通道下轨。 +* 空头平仓:如果当前持有空单,并且价格上破唐奇安通道上轨。 + +. + +#### 回测绩效 +![此处输入图片的描述][5] + +. + +#### 策略进阶 +* 改变出场方式 +* 本策略是通过唐奇安通道上下轨进行止损出场的,也可以采用最大浮动亏损百分比进行止损。 +* 改变入场方式 +* 本策略每次真实入场前是基于前一次的虚拟盈亏,也可以考虑设置多次虚拟盈亏结果决定是否入场。 + +. + +#### 策略特点 +* 该策略中的亮点是虚拟交易与实盘交易完全隔离,当虚拟交易亏损后,实盘交易才入场。 + +* 将均线与 RSI 相结合,这是区别以往策略的又一亮点,即当行情进入超卖区不做空,当行情进入超买区不做多。 + +. + +#### 特别提示 +市场唯一不变的就是一直在变,并且未来不可预测,过去的回测结果并不代表未来。 + + + + [1]: https://dn-filebox.qbox.me/75ce917bea3ca3131c13e718539cb45972942565.png + [2]: https://dn-filebox.qbox.me/b70fb37d684b32135ad8e3b6f0827230e5ca3ce7.png + [3]: https://dn-filebox.qbox.me/dfe151d32bd350c5713bf39b7f7940361eee1e40.png + [4]: https://dn-filebox.qbox.me/236fb56dc1ad9119cc38350270710ec6591cb2ba.png + [5]: https://dn-filebox.qbox.me/e5dc7e6c903d0a0b43f04483e0ac0607a1212eb3.png + + +参数 默认值 描述 +------------ ----------- ----- +contractType rb000/rb888 合约类型 +fastLength 25 短期均线 +slowLength 100 长期均线 +rsiLength 15 RSI周期 +Donchian 20 唐奇安周期 +*/ + +/*backtest +start: 2017-01-01 09:00:00 +end: 2017-11-27 15:00:00 +period: 1h +*/ + +var into = 0; // 入场价格 +var out = 0; // 出场价格 +var myPosition = 0; // 虚拟持仓 +var myProfit = 0; // 虚拟利润 +var uu = 30; // 超卖 +var nn = 70; // 超买 + +// 语法固定格式,调用main主函数 +function main() { + // 调用商品期货交易类库中的CTA框架 + $.CTA(contractType, function(st) { + var mp = st.position.amount; + + //获取K线数组 + var j = st.records; + //指标运算参考的最大K线数量 + if (j.length < Math.max(fastLength, slowLength, rsiLength)) { + return + } + var h0 = j[j.length - 1].High; + var h1 = j[j.length - 2].High; + var l0 = j[j.length - 1].Low; + var l1 = j[j.length - 2].Low; + var o0 = j[j.length - 1].Open; + var c0 = j[j.length - 1].Close; + + //短期指数平均线数组和长期指数平均线数组 + var fastMas = talib.MA(j, fastLength); + var slowMas = talib.MA(j, slowLength); + var fastMa1 = fastMas[fastMas.length - 2]; + var slowMa1 = slowMas[slowMas.length - 2]; + + //获取RSI数组 + var rsis = talib.RSI(j, rsiLength); + var rsi1 = rsis[rsis.length - 2]; + + //获取唐奇安通道 + var highest = TA.Highest(j, Donchian, "High"); + var lowest = TA.Lowest(j, Donchian, "Low"); + + // 平多 + if (l0 <= lowest) { + if (myPosition > 0) { + out = Math.min(o0, lowest); + myProfit = into - out; + myPosition = 0; + } + if (mp > 0) { + return -1; + } + } + + // 平空 + if (h0 >= highest) { + if (myPosition < 0) { + out = Math.max(o0, highest); + myProfit = into - out; + myPosition = 0; + } + if (mp < 0) { + return 1; + } + } + + // 开多 + if (fastMa1 > slowMa1 && rsi1 < nn && h0 >= h1) { + if (myPosition === 0) { + into = Math.max(o0, h1); + myPosition = 1; + } + if (myProfit < 0 && mp < 1) { + return 1; + } + } + + // 开空 + if (fastMa1 < slowMa1 && rsi1 > uu && l0 <= l1) { + if (myPosition === 0) { + into = Math.min(o0, l1); + myPosition = -1; + } + if (myProfit < 0 && mp > -1) { + return -1; + } + } + + }); +} diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" index a1c5f50a..edf9d79f 100644 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" @@ -37,6 +37,18 @@ https://dn-filebox.qbox.me/c230753d3fd584c15ad3e39e33f970aafffe722f.png https://dn-filebox.qbox.me/a74f74b34e32897868086e6b771f81fd1468306e.png https://dn-filebox.qbox.me/1671268eba20870c7820542448dc0ef541d65a5b.png +- ### 注意: + + - #### 使用期货 功能下单时: + 注意不要忘记 先设置 合约类型 :exchange.SetContractType("this_week") 否则会报错。 + ``` + var p = $.NewPositionManager() + // this_week 即 当周合约 开多仓 , PositionManager.prototype.OpenLong = function(contractType, shares, price) + exchange.SetContractType("this_week") + p.OpenLong("this_week", 1, 1000) + // 这样就 1000 美元价格 开多仓 合约 1张 + ``` + 参数 默认值 描述 -------------- ----- -------------------------- diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\345\267\256\344\273\267\347\233\221\346\216\247\345\210\206\346\236\220.js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\345\267\256\344\273\267\347\233\221\346\216\247\345\210\206\346\236\220.js" deleted file mode 100644 index 777918b4..00000000 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\345\267\256\344\273\267\347\233\221\346\216\247\345\210\206\346\236\220.js" +++ /dev/null @@ -1,471 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/21337 -策略名称: 数字货币差价监控分析 -策略作者: 小小梦 -策略描述: - -只支持两个交易所, 可自定义差价的类型, 支持2.77托管者的自定义图表功能 - - -参数 默认值 描述 ------------- --------------------------------------------------------------------------- -------- -TickInterval 500 检测频率(毫秒) -StrOnePair spot:Huobi:spot;spot:OKCoin:spot;false;60;5;0;0 组合1 -StrTwoPair future:Futures_OKCoin:this_week;spot:OKCoin:spot;false;60;5;0;0 组合2 -StrThreePair future:Futures_OKCoin:this_week;future:Futures_OKCoin:quarter;true;60;5;0;0 组合3 -StrFourPair null 组合4 -StrSixPair null 组合6 -StrFivePair null 组合5 -ResetChart false 是否清除上次图表 -*/ - -/* -1、初步设计为4个组合 -2、计算 对冲空间 -3、多线程 -*/ -// 参数 -// var StrOnePair = "spot:Huobi:spot;spot:OKCoin:spot;false;60"; -// var StrTwoPair = "future:Futures_OKCoin:this_week;spot:OKCoin:spot;false;60"; -// var StrThreePair = "future:Futures_OKCoin:this_week;future:Futures_OKCoin:quarter;true;60"; -// var StrFourPair = "future:Futures_BitMEX:XBTUSD;future:Futures_OKCoin:this_week;true;60"; - -// 全局变量 -var NotEnable = "null"; -var ArrayPairs = []; -var ArrayStrPairs = [StrOnePair, StrTwoPair, StrThreePair, StrFourPair, StrFivePair, StrSixPair]; -var isFirst = true; -var ChartObj = null; -var chart = null; -var OK_futureRate = 0; -var IsCheckDelivery = false; -var checkTime = 0; -var residualTime = 0; -var checkPreTime = 0; -var strDelivery = ""; -var JGHoursCorrect = 8; // 检测交割剩余小时,在实盘中需要修正 8小时。 模拟时该值设置为0 -var tbls = null; - -// 函数实现 -function CheckDelivery(nowTime, Symbol) { - var contractInfo = null; - if(checkTime <= 0){ - var contractName = ""; - var ContractIndex = 0; - if(Symbol === "this_week"){ - ContractIndex = 0; - }else if(Symbol === "next_week"){ - ContractIndex = 1; - }else if(Symbol === "quarter"){ - ContractIndex = 2; - } - - // 更新汇率 - for(var exchangeIndex = 0; exchangeIndex < exchanges.length; exchangeIndex++){ - var e_name = exchanges[exchangeIndex].GetName(); - if(e_name == "Futures_OKCoin"){ - OK_futureRate = _C(exchanges[exchangeIndex].GetUSDCNY); // 每次交割后 更新汇率 - } - } - - while (contractName == "") { - //var contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=this_week"); //只是检测this_week ,避免重复调用提高效率 - switch(ContractIndex){ - case 0: contractInfo = HttpQuery("https://www.okex.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=this_week"); // 原地址修改为: www.okex.com - break; - case 1: contractInfo = HttpQuery("https://www.okex.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=next_week"); - break; - case 2: contractInfo = HttpQuery("https://www.okex.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=quarter"); - break; - default: Log("contractInfo:", contractInfo); - //throw "switch NumContractType Error!"; - } //根据 contractType 类型 选择读取合约交割日期 - if (!contractInfo || contractInfo.length === 0) { - Sleep(100); - continue; - } - try { - contractName = (JSON.parse(contractInfo))[0].contract_name; - } catch (e) { - Log("CheckDelivery Error",contractInfo, e); - return 0; - } - } - var nowDateTime = new Date(); - contractName = contractName.split("BTC")[1]; //抽取BTC后的字符串 重新赋值 - var strMonth = contractName[0] + contractName[1]; - var strDay = contractName[2] + contractName[3]; - var strYear = nowDateTime.getFullYear() + ""; //获取 年份字符串 - - // 处理跨年问题 - var nowMonth = nowDateTime.getMonth(); // 获取月份 - if(strMonth < nowMonth){ - strYear = (strYear - 0) + 1; - strYear = strYear + ""; - } - - var strDate = strYear + '-' + strMonth + '-' + strDay + ' ' + "16:00:00"; - var deliveryTime = (new Date(strDate)).getTime(); // + 16 * 60 * 60 * 1000; - nowTime = nowDateTime.getTime(); - residualTime = (deliveryTime - nowTime) / 1000 / 60 / 60 - JGHoursCorrect; //单位是小时 - checkTime = (deliveryTime - nowTime) - JGHoursCorrect * 1000 * 60 * 60; //还差多少毫秒交割 - checkPreTime = nowTime; //记录开始的时间 - Log("合约", Symbol, "交割日期获取:", strDate); - }else{ - checkTime -= nowTime - checkPreTime; //减去消耗的时间 - checkPreTime = nowTime; - residualTime = checkTime / 1000 / 60 / 60; // 计算距离交割多少小时 - } - - return _N(residualTime, 3); -} - - -function FindExchange(StrExchangeName){ - for(var i = 0; i < exchanges.length; i++){ - if(StrExchangeName == exchanges[i].GetName()){ - return exchanges[i]; - } - if(i == exchanges.length){ - throw "没有找到 名称为:" + StrExchangeName + "的交易所对象"; - } - } -} - -function CalcAvgDiff(pair){ - var nowTime = new Date().getTime(); - if(nowTime - pair.AvgDiffUpdateTime > 1000 * pair.UpdateCycle){ - // 更新返回值 - var AvgPlus = _N(pair.SamplePlus.sum / pair.SamplePlus.count, 2); - var AvgMinus = _N(pair.SampleMinus.sum / pair.SampleMinus.count, 2); - - // 重置 - pair.AvgDiffUpdateTime = nowTime; - pair.SamplePlus.sum = 0; - pair.SamplePlus.count = 0; - pair.SampleMinus.sum = 0; - pair.SampleMinus.count = 0; - return {APlus : AvgPlus, AMinus : AvgMinus}; - }else{ - // 累计数值 - pair.SamplePlus.sum += pair.Plus; - pair.SamplePlus.count += 1; - pair.SampleMinus.sum += pair.Minus; - pair.SampleMinus.count += 1; - return false; - } -} - -function init(){ - for(var i = 0; i < ArrayStrPairs.length; i++){ - // Log(ArrayStrPairs[i]) // 测试 - if(ArrayStrPairs[i] == NotEnable){ // 过滤 - continue; - } - var pair = {}; - var exchangeOfPair = ArrayStrPairs[i].split(";"); - - if(exchangeOfPair.length !== 7){ - throw "参数错误:" + ArrayStrPairs[i]; - } - pair.exchangeA = FindExchange((exchangeOfPair[0].split(":"))[1]); // 设置 组合对象的 交易所属性 - pair.exchangeB = FindExchange((exchangeOfPair[1].split(":"))[1]); - - pair.NameA = (exchangeOfPair[0].split(":"))[1]; - pair.NameB = (exchangeOfPair[1].split(":"))[1]; - - if(pair.NameA == "Futures_OKCoin"){ - OK_futureRate = _C(pair.exchangeA.GetUSDCNY); - IsCheckDelivery = true; - } - if(pair.NameB == "Futures_OKCoin"){ - OK_futureRate = _C(pair.exchangeB.GetUSDCNY); - IsCheckDelivery = true; - } - - pair.SymbolA = (exchangeOfPair[0].split(":"))[2]; - pair.SymbolB = (exchangeOfPair[1].split(":"))[2]; - - pair.TypeA = (exchangeOfPair[0].split(":"))[0]; - pair.TypeB = (exchangeOfPair[1].split(":"))[0]; - - pair.DepthA = null; - pair.DepthB = null; - - pair.Plus = null; - pair.Minus = null; - - pair.AvgDiff = null; - pair.ID = i; - - pair.AvgDiffUpdateTime = new Date().getTime(); // 计算 均值更新时间 - pair.SamplePlus = {sum : 0, count : 0}; // 储存样本数据 - pair.SampleMinus = {sum : 0, count : 0}; // 储存样本数据 - pair.UpdateCycle = parseInt(exchangeOfPair[3]); // 更新周期秒数 - pair.GetDepthCycle = parseInt(exchangeOfPair[4]); // 获取深度 GetDepth 调用周期 2017.10.12新增 - pair.GetDepthUpdateTime = 0; // 记录 深度 更新时间 2017.10.12新增 - pair.plusAvg = 0; - pair.minusAvg = 0; - pair.Plus_count = 0; - pair.Minux_count = 0; - pair.max = null; - pair.min = null; - - pair.customRate = parseInt(exchangeOfPair[5]) // spot:OKCoin_EN:spot;future:Futures_OKCoin:this_week;true;60;5;0 默认 0 是 不启动 自定义现货汇率, 现货 汇率 - pair.customRate_futures = parseInt(exchangeOfPair[6]) // 期货 汇率 - - pair.isUseUSDRate = null; - if(exchangeOfPair[2] == "false"){ - pair.isUseUSDRate = false; - }else if(exchangeOfPair[2] == "true"){ - pair.isUseUSDRate = true; - }else{ - throw "error isUseUSDRate : " + pair.isUseUSDRate; - } - - /* - if(pair.TypeA == "future" || pair.isUseUSDRate == true){ - pair.PreRate = pair.exchangeA.GetUSDCNY(); - }else if(pair.TypeB == "future" || pair.isUseUSDRate == true){ - pair.PreRate = pair.exchangeB.GetUSDCNY(); - }else{ - pair.PreRate = pair.exchangeA.SetRate(); - } - */ - - ArrayPairs.push(pair); - Log("组合 pair: ", pair.exchangeA.GetName(), pair.exchangeB.GetName(), "#FF0000"); // ceshi - } - // 测试 - // Log(ArrayPairs); // ceshi -} - -function ToTables(time){ - // 处理图表数据 - var tbl_base = { - type : "table", - title : "pair基础数据", - cols : ["ID", "NameA - NameB", "SymbolA - SymbolB", "UpdCycle", "isUSD", "Collect"], - rows : [], - }; - - var tbl_value = { - type : "table", - title : "pair行情数据", - cols : ["ID", "NameA - NameB", "SymbolA - SymbolB", "A_Bids1", "B_Asks1", "Plus", "A_Asks1", "B_Bids1", "Minus"], - rows : [], - }; - - var tbl_Statistics = { - type : "table", - title : "pair统计数据", - cols : ["ID", "NameA - NameB", "SymbolA - SymbolB", "最大差价", "最小差价", "正溢价均值", "负溢价均值"], - rows : [], - } - - // 写入数据 迭代 写入 : NameA , SymbolA , TypeA , DepthA , Plus , Minus , time - AvgDiffUpdateTime ,UpdateCycle, isUseUSDRate - _.each(ArrayPairs, function(pair){ - var col1 = [pair.ID + " ", pair.NameA + "/" + pair.NameB, pair.SymbolA + "/" + pair.SymbolB, pair.UpdateCycle, pair.isUseUSDRate, (time - pair.AvgDiffUpdateTime) + "ms"]; - tbl_base.rows.push(col1); - - var col2 = [pair.ID + " ", pair.NameA + "/" + pair.NameB, pair.SymbolA + "/" + pair.SymbolB, pair.DepthA.Bids[0].Price, pair.DepthB.Asks[0].Price, pair.Plus, pair.DepthA.Asks[0].Price, pair.DepthB.Bids[0].Price, pair.Minus]; - tbl_value.rows.push(col2); - - var col3 = [pair.ID + " ", pair.NameA + "/" + pair.NameB, pair.SymbolA + "/" + pair.SymbolB, pair.max, pair.min, pair.plusAvg, pair.minusAvg] - tbl_Statistics.rows.push(col3); - }); - - return [tbl_base, tbl_value, tbl_Statistics]; -} - -function loop(beginTime){ - _.each(ArrayPairs, function(pair){ - var DepthA = null; // 临时储存 - var DepthB = null; // 临时储存 - - // 判断是否需要更新 - if(new Date().getTime() - pair.GetDepthUpdateTime < 1000 * pair.GetDepthCycle){ - return - }else{ - pair.GetDepthUpdateTime = new Date().getTime() // 记录 更新时间 - } - - if(pair.TypeA == "spot" && pair.isUseUSDRate == false){ // 如果当前组合 A 为现货 并且 不使用美元计价,直接获取数据 - if(pair.customRate !== 0){ - // Log("切换韩元汇率:", pair.customRate, pair.exchangeA.GetRate(), typeof(pair.customRate)) // ceshi - pair.exchangeA.SetRate(pair.customRate) - // Log(pair.exchangeA.SetRate(1/1115), "#FF0000") // ceshi - } - DepthA = pair.exchangeA.GetDepth(); - }else if(pair.TypeA == "future" && pair.isUseUSDRate == false){ // 如果当前组合 A 为期货 并且 不使用美元计价,需要判断是否为OKEX ,使用OKEX自己的汇率转换为RMB计价 - if(pair.NameA !== "Futures_OKCoin"){ - if(pair.customRate_futures !== 0){ - pair.exchangeA.SetRate(pair.customRate_futures) - } - pair.exchangeA.SetContractType(pair.SymbolA); - DepthA = pair.exchangeA.GetDepth(); - }else{ - if(pair.customRate_futures == 0){ - pair.PreRate = pair.exchangeA.SetRate(OK_futureRate); - }else{ - pair.PreRate = pair.exchangeA.SetRate(pair.customRate_futures) - } - pair.exchangeA.SetContractType(pair.SymbolA); - DepthA = pair.exchangeA.GetDepth(); - pair.exchangeA.SetRate(pair.PreRate); - } - }else if(pair.TypeA == "spot" && pair.isUseUSDRate == true){ // 如果当前组合 A 为现货 并且 使用美元计价, 切换禁用底层转换, 获取数据后,恢复。 - pair.PreRate = pair.exchangeA.SetRate(1); - DepthA = pair.exchangeA.GetDepth(); - pair.exchangeA.SetRate(pair.PreRate); - }else if(pair.TypeA == "future" && pair.isUseUSDRate == true){ // 如果当前组合 A 为期货 并且 使用美元计价, 切换禁用底层转换, 获取数据后,恢复。 - pair.PreRate = pair.exchangeA.SetRate(1); - pair.exchangeA.SetContractType(pair.SymbolA); - DepthA = pair.exchangeA.GetDepth(); - pair.exchangeA.SetRate(pair.PreRate); - } - - if(pair.TypeB == "spot" && pair.isUseUSDRate == false){ - if(pair.customRate !== 0){ - // Log("切换韩元汇率:", pair.customRate, pair.exchangeB.GetRate(), typeof(pair.customRate)) // ceshi 切换韩元汇率: 1115 1000 number - pair.exchangeB.SetRate(pair.customRate) - // Log(pair.exchangeB.SetRate(1/1115), "#FF0000") // ceshi undefined - } - DepthB = pair.exchangeB.GetDepth(); - }else if(pair.TypeB == "future" && pair.isUseUSDRate == false){ - if(pair.NameB !== "Futures_OKCoin"){ - if(pair.customRate_futures !== 0){ - pair.exchangeB.SetRate(pair.customRate_futures) - } - pair.exchangeB.SetContractType(pair.SymbolB); - DepthB = pair.exchangeB.GetDepth(); - }else{ - if(pair.customRate_futures == 0){ - pair.PreRate = pair.exchangeB.SetRate(OK_futureRate); - }else{ - pair.PreRate = pair.exchangeB.SetRate(pair.customRate_futures) - } - pair.exchangeB.SetContractType(pair.SymbolB); - DepthB = pair.exchangeB.GetDepth(); - pair.exchangeB.SetRate(pair.PreRate); - } - }else if(pair.TypeB == "spot" && pair.isUseUSDRate == true){ - pair.PreRate = pair.exchangeB.SetRate(1); - DepthB = pair.exchangeB.GetDepth(); - pair.exchangeB.SetRate(pair.PreRate); - }else if(pair.TypeB == "future" && pair.isUseUSDRate == true){ - pair.PreRate = pair.exchangeB.SetRate(1); - pair.exchangeB.SetContractType(pair.SymbolB); - DepthB = pair.exchangeB.GetDepth(); - pair.exchangeB.SetRate(pair.PreRate); - } - - // 过滤 数据,确定数据没有问题再赋值给 对象持久化。 - if(!DepthA || !DepthB || DepthA.Asks.length == 0 || DepthA.Bids.length == 0 || - DepthB.Asks.length == 0 || DepthB.Bids.length == 0){ - return; - } - - // 过滤后给数据赋值 - pair.DepthA = DepthA; - pair.DepthB = DepthB; - - pair.Plus = _N(pair.DepthA.Bids[0].Price - pair.DepthB.Asks[0].Price, 2); - pair.Minus = _N(pair.DepthA.Asks[0].Price - pair.DepthB.Bids[0].Price, 2); - - // 统计 平均、最大、最小 - if(pair.min == null){ - pair.min = pair.Minus - }else{ - pair.min = Math.min(pair.min, pair.Minus) - } - if(pair.max == null){ - pair.max = pair.Plus - }else{ - pair.max = Math.max(pair.max, pair.Plus) - } - - if(pair.Plus > 0){ - pair.plusAvg = ((pair.plusAvg * pair.Plus_count) + pair.Plus) / (pair.Plus_count + 1) - pair.Plus_count++ - } - - if(pair.Minus < 0){ - pair.minusAvg = ((pair.minusAvg * pair.Minux_count) + pair.Minus) / (pair.Minux_count + 1) - pair.Minux_count++ - } - - - - // 调用计算函数 计算均值,间隔时间输出 - var AvgDiff = CalcAvgDiff(pair); - - if(AvgDiff !== false){ // 根据周期 设置 更新图像 - $.PlotLine("pairID:" + pair.ID + " : Plus" /*pair.NameA + "/" + pair.NameB + ":Plus"*/, AvgDiff.APlus, beginTime); - $.PlotLine("pairID:" + pair.ID + " : Minus" /*pair.NameA + "/" + pair.NameB + ":Minus"*/, AvgDiff.AMinus, beginTime); - } - - // 首次执行一些操作 - if(isFirst){ - chart = $.PlotLine("pairID:" + pair.ID + " : Plus" /*pair.NameA + "/" + pair.NameB + ":Plus"*/, pair.Plus); - chart = $.PlotLine("pairID:" + pair.ID + " : Minus" /*pair.NameA + "/" + pair.NameB + ":Minus"*/, pair.Minus); - if(pair.isUseUSDRate){ - for(var key in ChartObj.series){ - if(ChartObj.series[key].name == pair.NameA + "/" + pair.NameB + ":Plus" || ChartObj.series[key].name == pair.NameA + "/" + pair.NameB + ":Minus"){ - ChartObj.series[key].yAxis = 1; - } - } - } - } - }); - - // 结束首次 - if(isFirst){ - chart.update(ChartObj); - if(ResetChart){ - chart.reset(); - } - isFirst = false; - } - tbls = ToTables(beginTime); -} - - -function main(){ - // 图标初始设置 - ChartObj = $.GetCfg(); - // 处理 指标轴 - ChartObj.yAxis = [{ - title: {text: 'RMB计价'},//标题 - style: {color: '#4572A7'},//样式 - opposite: false, //生成右边Y轴 - }, - { - title:{text: "美元计价"}, - opposite: true, //生成右边Y轴 ceshi - } - ]; - - while(true){ - var beginTime = new Date().getTime(); - loop(beginTime); - Sleep(TickInterval); - if(IsCheckDelivery && (!IsVirtual())){ - var numDelivery = CheckDelivery(beginTime, "this_week"); - strDelivery = "距离当周合约交割剩余:" + numDelivery + " 小时! OK期货汇率:" + OK_futureRate; - } - var endTime = new Date().getTime(); - LogStatus("轮询耗时:" + (endTime - beginTime) + "ms" + '\n`' + JSON.stringify(tbls) + '`' + '\n' + strDelivery); - } -} - - - - - - - - - - - diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" index 9c8fbf3a..572c121e 100644 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" @@ -122,7 +122,7 @@ $.withdraw = function(e, currency, address, amount, fee, password) { throw "bitfinex not support " + currency; } var withdraw_type = cMap[currency]; - ret = e.IO("api", "POST", "/v1/withdraw", "withdraw_type=" + withdraw_type + "&walletselected=exchange&address=" + address + "&amount=" + amount); + ret = e.IO("api", "POST", "/v1/withdraw", "withdraw_type=" + withdraw_type + "&walletselected=exchange&address=" + address + "&amount='" + amount + "'"); if (ret && ret.length == 1 && typeof(ret[0].withdrawal_id) !== 'undefined') { withdraw_id = ret[0].withdrawal_id; } diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.js" new file mode 100644 index 00000000..259b6127 --- /dev/null +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.js" @@ -0,0 +1,317 @@ +/* +策略出处: https://www.botvs.com/strategy/62140 +策略名称: 数字货币现货交易类库c++ +策略作者: 小小梦 +策略描述: + +使用了botvs最新支持的c++编写策略,如果使用有问题,欢迎在下面留言,我会经常来巡逻的! +如果托管者在2017年12月之后没有更新,请更新下托管者 + + +参数 默认值 描述 +---------- ------- ----------------------- +OpMode 0 下单方式: 吃单|挂单 +MaxSpace 0.5 挂单失效距离 +SlidePrice 0.1 下单滑动价(元) +MaxAmount 0.8 开仓最大单次下单量 +RetryDelay 500 失败重试(毫秒) +MAType 0 均线算法: EMA|MA|AMA(自适应均线) +MinStock 0.001 最小交易量 +*/ + +#include +#include +#include +#include + +using namespace std; +double min(double a, double b, double c){ + double d = a < b ? a : b; + return d < c ? d : c; +} + +struct withdraw_ret{ + json ret; + string withdraw_id; +}; + +withdraw_ret withdraw (Exchange &e, string ¤cy, string &address,string &amount, string &fee, string &password){ + string withdraw_id; + json ret; + transform(currency.begin(), currency.end(), currency.begin(),::tolower); + if(e.GetName() == "OKCoin_EN"){ + ret = e.IO("api", "POST", "/api/v1/withdraw.do", "symbol="+currency+"_usd&chargefee=" + fee + "&trade_pwd=" + password + "&withdraw_address=" + address + "&withdraw_amount=" + amount); + if (!ret.is_null() && !ret.is_boolean() && !(ret["withdraw_id"].is_null())) { + withdraw_id = ret["withdraw_id"]; + } else { + string err = GetLastError(); + if (!err.empty() && err.find("10031") != -1) { + Log("OKCoin_EN 需6个网络确认后方能提现"); + } + } + } else if(e.GetName() == "Huobi"){ + if (currency == "bch") { + currency = "bcc"; + } + ret = e.IO("api", "POST", "/v1/dw/withdraw-virtual/create", "currency="+currency+"&fee=" + fee + "&address=" + address + "&amount=" + amount); + if (!ret.is_null() && !ret.is_boolean() && !ret["withdraw_id"].is_null()) { + withdraw_id = ret["data"]; + } + } else if(e.GetName() == "Bithumb"){ + string cu; + transform(currency.begin(), currency.end(), cu.begin(),::toupper); + ret = e.IO("api", "POST", "/trade/btc_withdrawal", "currency="+cu+"&address=" + address + "&units=" + amount); + if (!ret.is_null() && !ret.is_boolean() && ret["status"].get() == "0") { + withdraw_id = "9999"; + } + } else if(e.GetName() == "GateIO"){ + ret = e.IO("api", "POST", "/api2/1/private/withdraw", "currency="+currency+"&address=" + address + "&amount=" + amount); + if (!ret.is_null() && !ret.is_boolean() && ret["code"].get() == "0") { + withdraw_id = "9999"; + } + } else if(e.GetName() == "ZB"){ + ret = e.IO("api", "POST", "/api/withdraw", "method=withdraw&itransfer=0¤cy="+currency+"&receiveAddr=" + address + "&amount=" + amount+"&fees="+fee+"&safePwd="+password); + if (!ret.is_null() && !ret.is_boolean() && ret["code"].get() == "0") { + withdraw_id = ret["id"]; + } + } else if(e.GetName() == "Bitfinex"){ + vector cMap = {"btc","ltc","eth","zec","etc","xmr","omni","usd","dash","xrp","eos"}; + vector cMap2 = {"bitcoin","litecoin","litecoin","ethereum","ethereumc","zcash","monero","mastercoin","wire","dash","ripple","eos"}; + int cMap_index = -1; + for(int i = 0;i() == "true") { + withdraw_id = ret["result"]["uuid"]; + } + } else if(e.GetName() == "Binance"){ + ret = e.IO("api", "POST", "/wapi/v1/withdraw.html", "amount=" + amount + "&asset=" + currency + "&address=" + address); + if (!ret.is_null() && !ret.is_boolean() && ret["success"].get() == "true") { + withdraw_id = "9999"; + } + } else if("OKEX"){ + ret = e.IO("api", "POST", "/api/v1/withdraw.do", "target=address&withdraw_amount=" + amount + "&symbol="+currency+"_usd&withdraw_address=" + address+"&chargefee="+fee+"&trade_pwd="+password); + if (!ret.is_null() && !ret.is_boolean() && ret["result"].get() == "true") { + withdraw_id = ret["withdraw_id"]; + } + } else{ + throw("不支持的操作"); + } + return {ret, withdraw_id}; +} + +void CancelPendingOrders(Exchange &e,size_t orderType){ + while(true){ + auto orders = e.GetOrders(); + if(orders.size() <= 0){ + Sleep(RetryDelay); + continue; + } + size_t processed = 0; + for(size_t j = 0;j < orders.size();j++){ + if(typeid(orderType) == typeid(size_t) && orders[j].Type != orderType){ + continue; + } + e.CancelOrder(orders[j].Id, orders[j]); + processed++; + if (j < (orders.size() - 1)) { + Sleep(RetryDelay); + } + } + if (processed == 0) { + break; + } + } +} + +Account GetAccount(Exchange &e, bool waitFrozen = false){ + Account account; + bool alreadyAlert = false; + while(true){ + account = _C(e.GetAccount); + if (!waitFrozen || (account.FrozenStocks < MinStock && account.FrozenBalance < 0.01)) { + break; + } + if (!alreadyAlert) { + alreadyAlert = true; + Log("发现账户有冻结的钱或币", account); + } + Sleep(RetryDelay); + } + return account; +} + +Order StripOrders(Exchange &e, TId &orderId){ + Order order; + while(true){ + size_t dropped = 0; + auto orders = _C(e.GetOrders); + for(size_t i = 0; i < orders.size(); i++){ + if (orders[i].Id.s == orderId.s) { + order = orders[i]; + } else{ + string extra; + if (orders[i].DealAmount > 0) { + extra = "成交: " + to_string(orders[i].DealAmount); + } else{ + extra = "未成交"; + } + e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); + dropped++; + } + } + if(dropped == 0){ + break; + } + Sleep(RetryDelay); + } + return order; +} + +MarketOrder Trade(Exchange &e,size_t tradeType,double tradeAmount,size_t mode,double slidePrice,double maxAmount,double maxSpace,size_t retryDelay) { + auto initAccount = GetAccount(e, true); + auto nowAccount = initAccount; + TId orderId; + double prePrice = 0; + double dealAmount = 0; + double diffMoney = 0; + bool isFirst = true; + //0为买,1为卖 + size_t tradeFunc = tradeType == ORDER_TYPE_BUY ? 0 : 1; + bool isBuy = tradeType == ORDER_TYPE_BUY; + while(true){ + auto ticker = _C(e.GetTicker); + double tradePrice = 0.0; + if(isBuy){ + tradePrice = _N((mode == 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4); + } else{ + tradePrice = _N((mode == 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4); + } + if(orderId.Valid){ + if (isFirst) { + isFirst = false; + } else { + nowAccount = GetAccount(e, true); + } + double doAmount = 0.0; + if (isBuy) { + diffMoney = _N(initAccount.Balance - nowAccount.Balance, 4); + dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 4); + doAmount = min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance - 10) / tradePrice, 4)); + } else{ + diffMoney = _N(nowAccount.Balance - initAccount.Balance, 4); + dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); + doAmount = min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); + } + if (doAmount < MinStock) { + break; + } + prePrice = tradePrice; + if(tradeFunc == 0){ + orderId = e.Buy(tradePrice, doAmount, ticker); + } else { + orderId = e.Sell(tradePrice, doAmount, ticker); + } + if (!orderId) { + CancelPendingOrders(e, tradeType); + } + } else{ + if (mode == 0 || (abs(tradePrice - prePrice) > maxSpace)) { + orderId.Valid = false; + } + auto order = StripOrders(e, orderId); + if (order.is_null()) { + orderId.Valid = false; + } + } + Sleep(retryDelay); + } + if (dealAmount <= 0) { + MarketOrder ret; + return ret; + } + return { _N(diffMoney / dealAmount, 4), dealAmount }; +} + +MarketOrder Buy(Exchange &e, double amount){ + return Trade(e, ORDER_TYPE_BUY, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); +} + +MarketOrder Buy(double e, double amount){ + amount = e; + return Trade(exchange, ORDER_TYPE_BUY, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); +} + +MarketOrder Sell(Exchange &e,double amount) { + return Trade(e, ORDER_TYPE_SELL, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); +} + +MarketOrder Sell(double e,double amount) { + amount = e; + return Trade(exchange, ORDER_TYPE_SELL, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); +} + +size_t Cross(size_t a, size_t b){ + size_t crossNum = 0; + vector arr1; + vector arr2; + Records records; + while (true) { + records = _C(exchange.GetRecords); + if (records.size() > a && records.size() > b) { + break; + } + Sleep(RetryDelay); + } + if(MAType == 0){ + arr1 = TA.EMA(records, a); + arr2 = TA.EMA(records, b); + } else if(MAType == 1){ + arr1 = TA.MA(records, a); + arr2 = TA.MA(records, b); + } else{ + arr1 = talib.KAMA(records, a); + arr2 = talib.KAMA(records, b); + } + if(sizeof(arr1) != sizeof(arr2)){ + Log("array length not equal"); + throw("array length not equal"); + } + crossNum = _Cross(arr1, arr2); + return crossNum; +} + +void main(){ + auto i = exchange.IO("api", "GET", "/v1/pubticker/btcusd", ""); + Log(i["bid"]); + +} diff --git "a/\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.js" "b/\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.js" index 3da91278..75177771 100644 --- "a/\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.js" +++ "b/\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.js" @@ -1,7 +1,7 @@ /* 策略出处: https://www.botvs.com/strategy/30573 策略名称: 比特币现货阶梯差价对冲 -策略作者: roushasha +策略作者: 我要发 策略描述: 阶梯差价对冲,新手策略 diff --git "a/\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).js" "b/\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).js" new file mode 100644 index 00000000..9c0132f6 --- /dev/null +++ "b/\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).js" @@ -0,0 +1,167 @@ +/* +策略出处: https://www.botvs.com/strategy/22838 +策略名称: 测试-CTP商品期货连接状态 (图表显示) +策略作者: 小小梦 +策略描述: + +测试CTP商品期货连接状态 +1、图标显示 + + +参数 默认值 描述 +---------------- ----- ------- +testContractType MA701 测试的合约类型 +*/ + +//获取多个品种的信息 SR', 'CF', 'RM', 'MA', 'PTA', 'ZC', 'FG', 'IO + +var ChartCfg = { + __isStock: true, + title: { + text: 'CTP商品期货 交易所连接状态记录' + }, + xAxis:{type: 'datetime'}, + yAxis: { + //tickInterval: 1, + //tickAmount: 3, + max: 1.5, + min: -1.5, + plotLines: [{ + value: 0, + color: 'red', + width: 5, + label: { + text: '已连接', + align: 'center' + }, + }, { + value: 0, + color: 'green', + width: 5, + label: { + text: '未连接', + align: 'center' + }, + }] + }, + series: [{ + type: 'line', + name: '连接状态', + id: 'state', + data: [] + }, { + type: 'flags', + onSeries: 'state', + data: [], + }] +}; + + + +var ContractArray = ['SR701', 'CF701', 'RM701', 'MA701', 'ZC701', 'FG701']; // +function GetSomeContractMarketInfo(ContractArray){ + var array = []; //储存获取的信息 + _.each(ContractArray,function(ContractType){ + exchange.SetContractType(ContractType); + array.push({TypeName : ContractType ,ticker : exchange.GetTicker()}); + }); + + for(var i = 0 ; i < array.length; i++){ + Log(array[i]); + } + return array; +} + +var table = null; +function main() { + Log("测试CTP商品期货连接状态"); + SetErrorFilter("login|ready"); + //初始化图表 + table = $.TableInit(3,6); + table.a0 = "实时状态:exchange.IO('status') ↓"; + table.b0 = "test ContractType ↓"; + table.c0 = "infomation ↓"; + table.b2 = "ticker ↓#FF0000"; + table.b4 = "records[-1] ↓#FF0000"; + table.c2 = "Account ↓#FF0000"; + + //初始化 图 + chart = Chart(ChartCfg); + ChartCfg.yAxis.plotLines[0].value = 1.1; + ChartCfg.yAxis.plotLines[1].value = -1.1; + chart.reset(); + + var state = null; + var isAlert = false; + var ConnectAlert = false; + var info = exchange.SetContractType(testContractType);//设置合约 + Log("info:",info); + exchange.IO("mode",0);//设置行情 为立即返回模式 + var lastState = null; + while(true){ + state = exchange.IO("status"); + if((state === true && lastState === false)){ + info = exchange.SetContractType(testContractType); + while(info === null){ + state = exchange.IO("status"); + info = exchange.SetContractType(testContractType); + //LogStatus("state:",state,"lastState:",lastState,"info:",info," 登录 ,重新 设置 合约类型!"); + table.a1 = state; + table.b1 = testContractType; + table.c1 = "等待登录 ,重新 设置 合约类型。"; + if(state === false && lastState === true){ + chart.add(0,[(new Date()).getTime(),-1]); + }else if(state === true && lastState === false){ + chart.add(0,[(new Date()).getTime(),1]); + } + chart.update(ChartCfg); + Sleep(1000 * 60); + } + } + if(state === true){ + var ticker = exchange.GetTicker(); + var records = exchange.GetRecords(); + //LogStatus("exchange.IO('status') `s state is:",state,"\n",ticker,"\n",records?records[records.length - 1] : records,"\n",exchange.GetAccount(),"\n",new Date(),"\n",info); + table.a1 = state; + table.b1 = testContractType; + table.b3 = ticker; + if(records === null){ + table.b5 = "null"; + }else if(records.length > 0){ + table.b5 = records[records.length - 1]; + table.c1 = "records.length:" + records.length; + } + table.c3 = exchange.GetAccount(); + if(ConnectAlert === false){ + Log("state:",state,"info:",info,"#99CC32"); + ConnectAlert = true; + } + //LogStatus("exchange.IO('status') `s state is:",state); + //GetSomeContractMarketInfo(ContractArray); + isAlert = false; + }else{ + //LogStatus("exchange.IO('status') `s state is:",state,"time:",new Date(),"\n",info); + table.a1 = state; + if(isAlert === false){ + Log("state:",state,"info:",info,"#FF0000"); + Log("CTP商品期货测试微信提醒!state:" + state + "@"); + info = null; + isAlert = true; + } + ConnectAlert = false; + } + //Log(exchange.IO("status")); + //Log("ceshi"); + //记录状态到图表 + if(state === false && lastState === true){ + chart.add(0,[(new Date()).getTime(),-1]); + }else if(state === true && lastState === false){ + chart.add(0,[(new Date()).getTime(),1]); + } + + chart.update(ChartCfg); + $.UpdateLogStatus("time:" + (new Date())); //更新 状态栏 图表内容 + lastState = state; //当前状态更新到上次状态 + Sleep(1000 * 5); + } +} diff --git "a/\346\265\213\350\257\225.py" "b/\346\265\213\350\257\225.py" deleted file mode 100644 index 9c49b7af..00000000 --- "a/\346\265\213\350\257\225.py" +++ /dev/null @@ -1,15 +0,0 @@ -''' -策略出处: https://www.botvs.com/strategy/40045 -策略名称: 测试 -策略作者: 程序员 -策略描述: - -我的第一个botvs策略,测试 - -''' - -import time -def main(): - while True: - Log(exchange.GetAccount()) - time.sleep(60) diff --git "a/\347\224\273\347\272\277\347\261\273\345\272\223.js" "b/\347\224\273\347\272\277\347\261\273\345\272\223.js" index 386f1867..8ffd49a4 100644 --- "a/\347\224\273\347\272\277\347\261\273\345\272\223.js" +++ "b/\347\224\273\347\272\277\347\261\273\345\272\223.js" @@ -42,6 +42,7 @@ var labelIdx = [] var preBarTime = 0 var preFlagTime = 0 var preDotTime = [] +var hasPrimary = false; var cfg = { tooltip: { @@ -143,12 +144,13 @@ $.PlotRecords = function(records, title) { series.push({ type: 'candlestick', name: typeof(title) == 'undefined' ? '' : title, - id: 'primary', + id: (hasPrimary ? 'records_' + seriesIdx : 'primary'), data: [] }); chart.update(cfg) labelIdx["candlestick"] = seriesIdx } + hasPrimary = true; if (typeof(records.Time) !== 'undefined') { var Bar = records; if (Bar.Time == preBarTime) { @@ -185,6 +187,7 @@ $.PlotLine = function(label, dot, time) { labelIdx[label] = seriesIdx; series.push({ type: 'line', + id: (hasPrimary ? 'line_' + seriesIdx : 'primary'), yAxis: 0, showInLegend: true, name: label, @@ -193,6 +196,7 @@ $.PlotLine = function(label, dot, time) { valueDecimals: 5 } }) + hasPrimary = true; chart.update(cfg) } if (typeof(time) == 'undefined') { diff --git "a/\347\255\226\347\225\245001-szc.py" "b/\347\255\226\347\225\245001-szc.py" deleted file mode 100644 index cb172477..00000000 --- "a/\347\255\226\347\225\245001-szc.py" +++ /dev/null @@ -1,79 +0,0 @@ -''' -策略出处: https://www.botvs.com/strategy/34216 -策略名称: 策略001-szc -策略作者: 丧尸来来 -策略描述: - -实盘策略 - -''' - -import types -import time -import platform - -def main(): - perTime = 0 - amount_buy = 0 - amount_sell = 0 - diffMoney = 0 - dealAmount = 0 - price_buy = 0 - price_sell = 0 - price_stop_win = 0 - price_stop_lose = 0 - initAccount = ext.GetAccount() - while True: - LogStatus("现在时间:", _D(time.time())) - records = exchange.GetRecords(PERIOD_M30) - tiaojian = ext.szc() - nowAccount = ext.GetAccount() - if(not records or len(records) < 20): - continue - else: - if(perTime != records[-1]["Time"]): - perTime = records[-1]["Time"] - if nowAccount['Balance']>=100: - if tiaojian > 0: - Log("--------------------------------------------------------------") - nowAccount = ext.GetAccount() - amount_buy = _N(nowAccount.Balance,2) - exchange.Buy(-1, amount_buy) - lastAccount = ext.GetAccount() - diffMoney = _N(abs(nowAccount.Balance - lastAccount.Balance),4) - dealAmount = _N(abs(lastAccount.Stocks - nowAccount.Stocks),4) - price_buy = _N(diffMoney / dealAmount, 2) - Log("成交价:", price_buy) - Log("止损价:", price_stop_lose) - price_stop_lose = price_buy * 0.95 - price_stop_win = price_buy * 1.05 - else: - pass - elif nowAccount['Stocks']>=0.01: - price_now = _C(exchange.GetTicker).Last - if price_now > price_stop_win: - if tiaojian < 0: - nowAccount = ext.GetAccount() - amount_sell = _N(nowAccount.Stocks,2) - exchange.Sell(-1, amount_sell) - lastAccount = ext.GetAccount() - diffMoney = _N(abs(nowAccount.Balance - lastAccount.Balance),4) - dealAmount = _N(abs(lastAccount.Stocks - nowAccount.Stocks),4) - price_sell = _N(diffMoney / dealAmount, 2) - Log("成交价:", price_sell) - LogProfit(_N(lastAccount.Balance - initAccount.Balance, 2),'钱:',_N(lastAccount.Balance, 2),'币:',_N(lastAccount.Stocks,3)) - else: - pass - elif price_now < price_stop_lose: - Log("当前价:", _C(exchange.GetTicker).Last) - Log("止损!!!") - nowAccount = ext.GetAccount() - amount_sell = _N(nowAccount.Stocks,2) - exchange.Sell(-1, amount_sell) - lastAccount = ext.GetAccount() - LogProfit(_N(lastAccount.Balance - initAccount.Balance, 2),'钱:',_N(lastAccount.Balance, 2),'币:',_N(lastAccount.Stocks,3)) - else: - pass - else: - pass - Sleep(2000) diff --git "a/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" "b/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" index 4df890e3..24fba127 100644 --- "a/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" +++ "b/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" @@ -16,6 +16,9 @@ var TASK_ST = 4; var TASK_COVER = 5; */ +使用说明: +https://www.botvs.com/bbs-topic/634 + 参数 默认值 描述 ---------- ----- ----------- @@ -619,6 +622,9 @@ function onTick2() { } function main() { + if(exchanges.length != 2){ + throw "测试 用策略 逻辑函数 有2个 onTick1 , onTick2 ,需要添加2个 交易所对象才能跑起来!" + } $.Relation_Exchange_onTick(exchanges[0], onTick1); $.Relation_Exchange_onTick(exchanges[1], onTick2); $.Trend(); // 不用传参数。 diff --git "a/\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.js" "b/\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.js" new file mode 100644 index 00000000..b2f9cdf6 --- /dev/null +++ "b/\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.js" @@ -0,0 +1,98 @@ +/* +策略出处: https://www.botvs.com/strategy/67495 +策略名称: 网格(波段)香农版 +策略作者: 小码哥 +策略描述: + + + + +参数 默认值 描述 +--------------- ----- ----- +targetBaseRatio 0.5 仓位价值比 +minTradeLimit 0.001 最小交易量 +*/ + + +/*backtest + start: 2017-10-01 + end: 2018-01-01 + period: 60 + mode: 2 +*/ +function dateFormat(date, format) { + var o = { + "M+": date.getMonth() + 1, //月份 + "d+": date.getDate(), //日 + "h+": date.getHours(), //小时 + "m+": date.getMinutes(), //分 + "s+": date.getSeconds(), //秒 + "q+": Math.floor((date.getMonth() + 3) / 3), //季度 + "S": date.getMilliseconds() //毫秒 + }; + if (/(y+)/.test(format)) { + format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length)); + } + + for (var k in o) { + if (new RegExp("(" + k + ")").test(format)) { + format = format.replace(RegExp.$1, (RegExp.$1.length == 1) ? + (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); + } + } + + return format; +} + +function main() { + // {"Balance":10,"Stocks":0,"FrozenBalance":0,"FrozenStocks":0} + var initAccount = exchange.GetAccount(); + Log(initAccount); + + var initBalance = initAccount.Balance; + Log("初始净值: " + initBalance); + + //最近一次投资的日期 + var lastInvestDate = ''; + + //初始买1和卖1的价格 + var depth = exchange.GetDepth(); + var initPrice = depth.Bids[0].Price; + + while (true) { + //每次轮询,间隔时间为60秒 + Sleep(60 * 1000); + + var account = exchange.GetAccount(); + + var date = dateFormat(new Date(), "yyyy-MM-dd"); + if (date != lastInvestDate) { + lastInvestDate = date; + + //净值 + var value = account.Balance + account.FrozenBalance + buy1price * (account.Stocks + account.FrozenStocks); + Log("净值: " + (Math.round(100 * value) / 100)); + + //是否跑赢持币不动 + var r = 100 * ((value / initBalance) - (buy1price / initPrice)); + Log("r: " + (Math.round(100 * r) / 100) + "%"); + } else { + //continue; + } + + //当前买1和卖1的价格 + depth = exchange.GetDepth(); + var buy1price = depth.Bids[0].Price; + var sell1price = depth.Asks[0].Price; + + var T1 = (account.Stocks * buy1price + account.Balance) * targetBaseRatio / buy1price; + var T2 = (account.Stocks * sell1price + account.Balance) * targetBaseRatio / sell1price; + + if (account.Stocks - T2 > minTradeLimit) {//涨了,要卖掉一些 + exchange.Sell(buy1price, account.Stocks - T2); + } else if (T1 - account.Stocks > minTradeLimit) {//跌了,要买入,补仓 + exchange.Buy(sell1price, T1 - account.Stocks); + } + } +} + diff --git "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020171113).js" "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180118).js" similarity index 98% rename from "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020171113).js" rename to "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180118).js" index c955bdee..5d8079eb 100644 --- "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020171113).js" +++ "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180118).js" @@ -1,6 +1,6 @@ /* 策略出处: https://www.botvs.com/strategy/41163 -策略名称: 转换任意K线周期管理模板(最近更新20171113) +策略名称: 转换任意K线周期管理模板(最近更新20180118) 策略作者: 中本姜(青铜机器人) 策略描述: @@ -55,6 +55,8 @@ UI_NewCycleForMS 1000*60*60*2 合成周期毫秒数 period: 60 */ /* +20180118 + 屏蔽掉一些log输出 更新于20171114 a. 解决Open找不到问题,是record数组访问越界造成的,访问越界是之前的K线有问题导致的。 更新于20171113 @@ -240,7 +242,8 @@ function _RecordsManager(NewCycleForMS, Name) { BaseCycle = records[records.length - 1].Time - records[records.length - 2].Time; } if(NewCycleForMS % BaseCycle !== 0){ - Log("目标周期‘", NewCycleForMS, "’不是 基础周期 ‘", BaseCycle, "’ 的整倍数,无法合成!"); + //Log(EasyReadTime(records[records.length - 1].Time), EasyReadTime(records[records.length - 2].Time)); + //Log("目标周期‘", NewCycleForMS, "’不是 基础周期 ‘", BaseCycle, "’ 的整倍数,无法合成!"); return null; } if(NewCycleForMS / BaseCycle > records.length){ diff --git "a/\351\241\272\345\212\277_\351\253\230\351\242\221_\344\272\244\346\230\223_\346\265\213\350\257\2251.py" "b/\351\241\272\345\212\277_\351\253\230\351\242\221_\344\272\244\346\230\223_\346\265\213\350\257\2251.py" deleted file mode 100644 index 983a5a86..00000000 --- "a/\351\241\272\345\212\277_\351\253\230\351\242\221_\344\272\244\346\230\223_\346\265\213\350\257\2251.py" +++ /dev/null @@ -1,298 +0,0 @@ -''' -策略出处: https://www.botvs.com/strategy/21742 -策略名称: 顺势_高频_交易_测试1 -策略作者: 太极 -策略描述: - -历史成交价均价 减去 当前历史成交价 大于指定数值 开仓 (也相当于快周期减去慢周期判断上涨趋势) -开仓价格 大于 (当前成交价 加上 指定数值) 平仓 -开仓价格 小于 (当前成交价 减去 指定数值) 强行平仓操作(止损) -以此循环 -代码编写 QQ:7650371 太极 -整体思路提供 QQ:461355382 趋势操作有理 - - -参数 默认值 描述 -------------- ----- ------------------- -Interval_s 60 轮询(周期采集/秒) -Time_size 20 采集样本数(周期交易价格) -PositionRatio 0.5 仓位比例 -EnterPeriod true 开仓观察期(行情价 大于 当前) -ExitPeriod true 平仓观察期(开仓买入 大于 当前) -stop_Period -30 止损(强行平仓 买入价格 小于 当前) -min_size 20 秒级 采集样本数(交易价格) -''' - -#!/usr/local/bin/python -#-*- coding: UTF-8 -*- -#Interval_s=5 #轮询(采集周期/秒) -# Time_size=10 #采集样本数(交易价格) -#min_size=10 #秒级 采集样本数(交易价格) -# PositionRatio=0.1 #仓位比例 -# EnterPeriod=1 #开仓观察期(行情价 大于 当前) -# ExitPeriod=1 #平仓观察期(开仓买入 大于 当前) -# stop_Period=5 #强行平仓 - -# 历史成交价均价 减去 当前历史成交价 大于指定数值 开仓 (也相当于快周期减去慢周期判断上涨趋势) -# 开仓价格 大于 (当前成交价 加上 指定数值) 平仓 -# 开仓价格 小于 (当前成交价 减去 指定数值) 强行平仓操作(止损) -# 以此循环 -# 代码编写 QQ:7650371 太极 -# 整体思路提供 QQ:461355382 趋势操作有理 - -def add_min_list(Ticker_list,name): #添加秒级历史数据 - try: - #global min_size - #ticker = _C(exchange.GetTicker).Last#Ticker 市场行情 最后成交价 - if (int(name)>10): - if len(Ticker_list)>=min_size: - Ticker_list.pop(0) #返回并清除第一个数组 - Ticker_list.append(name) #追加元素 - else: - Ticker_list.append(name) #追加元素 - return 1,Ticker_list - except BaseException, e: - return 0,[] - -def add_list(Ticker_list,name): #添加数据 - try: - global Time_size - #ticker = _C(exchange.GetTicker).Last#Ticker 市场行情 最后成交价 - if (int(name)>10): - if len(Ticker_list)>=Time_size: - Ticker_list.pop(0) #返回并清除第一个数组 - Ticker_list.append(name) #追加元素 - else: - Ticker_list.append(name) #追加元素 - return 1,Ticker_list - except BaseException, e: - return 0,[] - -def Volume_min_averages(Ticker_listxxx): #添加秒级历史数据 - try: - Volume=0 - if len(Ticker_listxxx)1: - if buy_price<1: - buy_price=_C(exchange.GetTicker).Last - buy_qty=initAccount.Stocks - Log('开仓信息1 仓内还有比:',initAccount.Stocks,'进行清空','--开仓详情:',initAccount) - return 1 - if int(initAccount.Stocks)<1: - if int(str(initAccount.Stocks).replace('0.',''))>=3: - if buy_price<1: - buy_price=_C(exchange.GetTicker).Last - buy_qty=initAccount.Stocks - Log('开仓信息2 仓内还有比:',initAccount.Stocks,'进行清空','--开仓详情:',initAccount) - return 1 - - #if int(str(initAccount.Stocks).replace('0.',''))==0: - opAmount = _N(initAccount.Balance*PositionRatio,3) #买入数量 - Log("开仓没有币先进行 开仓买入%s元"%(str(opAmount))) #生成LOG日志 - - Dict = ext.Buy(opAmount) #买入ext.Buy - if(Dict):#确认开仓成功 - buy_price=Dict['price'] #买入价格 #{'price': 4046.446, 'amount': 1.5} - buy_qty=Dict['amount'] #买入数量 - #LogProfit(_N(gains,4),'开仓信息 钱:',initAccount.Balance,'--币:',initAccount.Stocks,'--开仓详情:',Dict) - print_log(1,initAccount) - return 1 - return 0 - - except Exception,ex: - Log('except Exception my_buy:',ex) - return 0 - -def my_sell(): #平仓 - try: - global buy_price,buy_qty,gains,ExitPeriod - nowAccount = ext.GetAccount() #交易模板的导出函数 获取账户信息 - if nowAccount.Stocks<=0.003: #保证满足交易量 - Log('不满足最小交易量:',nowAccount.Stocks) - return 1 - if _N(_C(exchange.GetTicker).Last,2)>buy_price+ExitPeriod: #当前价格一定要大于 开仓价格 - Dict = ext.Sell(nowAccount.Stocks) - #Dict ={"price":_C(exchange.GetTicker).Last} - if(Dict): - sell_gains=(Dict['price']-buy_price)*Dict['amount'] - gains=gains+sell_gains - buy_price=0 #买入价格 - buy_qty=0 #买入数量 - LogProfit(_N(gains,4),'平仓信息 钱:',nowAccount.Balance,'--币:',nowAccount.Stocks,'--平仓详情:',Dict)#收益曲线 - print_log(0,nowAccount) - return 1 - else: - current_Last = _N(_C(exchange.GetTicker).Last,2) ##当前价格 - data="不具备平仓条件:买入-当前=差价:%s-%s=%s"%(buy_price,current_Last,_N(buy_price-current_Last,2)) - print_log(0,nowAccount,data) - return 0 - except Exception,ex: - Log('except Exception my_sell:',ex) - return 0 - -def stop_sell(): #强行平仓 - try: - global buy_price,buy_qty,gains,ExitPeriod - nowAccount = ext.GetAccount() #交易模板的导出函数 获取账户信息 - if nowAccount.Stocks<=0.003: #保证满足交易量 - Log('不满足最小交易量:',nowAccount.Stocks) - return 1 - Dict = ext.Sell(nowAccount.Stocks) - #Dict ={"price":_C(exchange.GetTicker).Last} - if(Dict): - sell_gains=(Dict['price']-buy_price)*Dict['amount'] - gains=gains+sell_gains - buy_price=0 #买入价格 - buy_qty=0 #买入数量 - LogProfit(_N(gains,4),'止损/强行/平仓信息 钱:',nowAccount.Balance,'--币:',nowAccount.Stocks,'--平仓详情:',Dict)#收益曲线 - print_log(0,nowAccount) - return 1 - return 0 - except Exception,ex: - Log('except Exception stop_sell:',ex) - return 0 - -outAccount = ext.GetAccount() #初始化信息 -def print_log(k_p,Account,data=""): - try: - global outAccount - name="" - if k_p: - name="开仓" - else: - name="平仓" - - endAccount = ext.GetAccount() #初始化信息 - date1=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time())) - LogStatus("初始化投入2016/9/24 投入0.2个币=等于行情800RMB\r\n", - "本次初始化状态:",outAccount, - "\r\n当前运 行状态:",endAccount, - "\r\n本次开始运行时间:%s 已运行:%s\r\n"%(start_time,Caltime(start_time,date1)), - "本次盈亏:%s(RMB)\r\n"%(str(gains)), - "当前状态:%s--钱:%s--币:%s\r\n"%(str(name),str(Account.Balance),str(Account.Stocks)), - "更新时间:%s\r\n"%(date1), - "%s"%(data) - ) # 测试 - except Exception,ex: - Log('except Exception print_log:',ex) -######################################################## -def main(): - state = 3 - n=0 - min_n=0 - Log("run ",outAccount) #输出初始账户信息 - Ticker_list=[] #历史均价 - min_list=[] #分钟级均价 - #BotVS目前不支持多线程方法只能用下面的方法代替 - #循环以秒为单位 - #Interval_s到整的时候更新采集 - min_size_list=[] #秒级 采集样本 - current_Last=0 #当前历史均价 - while True: - ticker = _C(exchange.GetTicker).Last#Ticker 市场行情 最后成交价 - nowAccount = ext.GetAccount() #交易模板的导出函数 获取账户信息 - #current_Last = _N(_C(exchange.GetTicker).Last,2) ##当前价格 - history_Last=_N(Volume_averages(Ticker_list),2) #历史均价 - ############################################################ - #更新秒级历史数据 min_size=10 #秒级 采集样本数(交易价格) - add_bool,f_list=add_min_list(min_size_list,ticker) #添加秒级历史数据 - if add_bool: - min_size_list=f_list - current_Last=int(_N(Volume_min_averages(min_size_list),2)) #当前历史均价 - #Log('秒级历史均价数组:',min_size_list) - #Log('秒级历史均价11:',current_Last) - - #更新历史数据 - if n=int(Interval_s): #重置 - min_Last=_N(Volume_averages(min_list),2) #分钟级历史均价 - add_bool,f_list=add_list(Ticker_list,min_Last) #更新数据 - if add_bool: - Ticker_list=f_list - min_list=[] #分钟级均价 清空 - #Log('历史数据Ticker_list:',len(Ticker_list)) - n=0 - if (int(history_Last)>10 and int(current_Last)>10): - data="历史平均-当前=差价:%s-%s=%s"%(history_Last,current_Last,_N(history_Last-current_Last,2)) - print_log(0,nowAccount,data) - Log('当前数据:',data) - else: - Log('正在收集数据:',current_Last) - ############################################################ - if (int(history_Last)>10 and int(current_Last)>10): - end_Last=_N(history_Last-current_Last,2) - #止损操作(已经买入了 当前价格下跌到一定值后 进行止损) - if (state == 1): # - stop_Last=current_Last-buy_price - if (stop_Last=EnterPeriod: - if (state == 3): # - data="小于当前行情价开仓:历史平均-当前=差价:%s-%s=%s"%(history_Last,current_Last,end_Last) - print_log(0,nowAccount,data) - state = 0 - ################################################# - if (state == 0): # - if my_buy(): #开仓 - #Log('开仓') - state = 1 - if (state == 1): # - if my_sell(): #平仓 - #Log('平仓') - state = 3 - ################################################# - - Sleep(1000) - - - - diff --git "a/\351\241\272\345\212\277_\351\253\230\351\242\221_\344\272\244\346\230\223_\346\265\213\350\257\2252\342\200\224\342\200\224\345\244\261\350\264\245.py" "b/\351\241\272\345\212\277_\351\253\230\351\242\221_\344\272\244\346\230\223_\346\265\213\350\257\2252\342\200\224\342\200\224\345\244\261\350\264\245.py" deleted file mode 100644 index 671647d5..00000000 --- "a/\351\241\272\345\212\277_\351\253\230\351\242\221_\344\272\244\346\230\223_\346\265\213\350\257\2252\342\200\224\342\200\224\345\244\261\350\264\245.py" +++ /dev/null @@ -1,215 +0,0 @@ -''' -策略出处: https://www.botvs.com/strategy/21938 -策略名称: 顺势_高频_交易_测试2——失败 -策略作者: 太极 -策略描述: - -主要趋势为多的开平单的条件 -开仓 :大周期差值(-0.04--0.08) - MA20>现价格>MA60 -同时具备以条件的2条才开多单仓,否则开空仓 - -平仓:小周期差值>0.4 - 小周期最低价格>MA3 - 现价格=int(Interval_s): #重置 - n=0 - #PERIOD_M1 指1分钟,#PERIOD_M5 指5分钟,#PERIOD_M15 指15分钟,#PERIOD_M30 指30分钟,#PERIOD_H1 指1小时,#PERIOD_D1 指一天 - ticker = _C(exchange.GetRecords,PERIOD_M1)#Record 收盘价 - #Log('当前数据:',ticker) - minutes1_time=int(out_time(Enter_large_cycle)) #开仓 大周期 获取当前时间 获取时间戳 - minutes2_time=int(out_time(Enter_Small_cycle)) #开仓 小周期 获取当前时间 获取时间戳 - - minutes3_time=int(out_time(Exit_large_cycle)) #平仓 大周期 - minutes4_time=int(out_time(Exit_Small_cycle)) #平仓 小周期 - - - timeB1=str(int(minutes1_time)) - timeB2=timeB1[:len(timeB1)] #我们设定的收盘时间 大周期 - #timeB_time=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(int(timeB2))) #时间戳 转换成日期 - - timeC1=str(int(minutes2_time)) - timeC2=timeC1[:len(timeC1)] #我们设定的收盘时间 大周期 - - timeD1=str(int(minutes3_time)) - timeD2=timeC1[:len(timeD1)] #我们设定的收盘时间 - - timeE1=str(int(minutes4_time)) - timeE2=timeC1[:len(timeE1)] #我们设定的收盘时间 - - for colour in ticker: - timeA1=str(int(colour.Time)) - timeA2=timeA1[:len(timeA1)-3] #收盘时间 - #timeA_time=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(int(timeA2))) #时间戳 转换成日期 - #开仓数据 - if int(timeA2)>int(timeB2): #收盘时间大于我们设定的时间及为 真 - #Log('大周期:',timeA_time,"|",timeA2,",",timeB_time,"|",timeB2) - Close1_list.append(colour.Close) #大周期 - if int(timeA2)>int(timeC2): #收盘时间大于我们设定的时间及为 真 - #Log('小周期:',timeA_time,"|",timeA2,",",timeC_time,"|",timeC2) - Close2_list.append(colour.Close) #小周期 - #平仓数据 - if int(timeA2)>int(timeD2): #收盘时间大于我们设定的时间及为 真 - Close3_list.append(colour.Close) #平仓 大周期 - if int(timeA2)>int(timeE2): #收盘时间大于我们设定的时间及为 真 - Close4_list.append(colour.Close) #平仓 大周期 - ######################################################################### - #开仓条件 - if (len(Close1_list)+1>=Enter_large_cycle and len(Close2_list)+1>=Enter_Small_cycle): - #说明数据收集完毕准备开始操作 - minu1_Close=_N(Volume_averages(Close1_list,Enter_large_cycle),2) #大周期 历史均价 - minu2_Close=_N(Volume_averages(Close2_list,Enter_Small_cycle),2) #小周期 历史均价 - if (minu1_Close>10 and minu2_Close>10): - value1_data=Close2_Close(Close1_list) #大周期 差值 - value2_data=Close2_Close(Close2_list) #小周期 差值 - data="大周期 差值:%s小周期 差值:%s当前成交价:%s大周期均价:%s小周期均价:%s"%\ - (str(value1_data),str(value2_data),str(tickerx),str(minu1_Close),str(minu2_Close)) - Log(data) - data=" 大周期:%s>= 大周期 差值:%s>=小周期:%s"%\ - (str(float(large1_Period)),str(float(value1_data)),str(float(large2_Period))) - Log("数据:",data) - if (float(large1_Period)>=float(value1_data) and float(value1_data)>=float(large2_Period)): #判断这个差值在这个区间内则开仓 - Log("ssssssssssssssssssssss",state) - if (state == 3): # - data="开仓当前大周期差值:%s"%(str(value1_data)) - Log(data) - #print_log(0,nowAccount,data) - state = 0 - ######################################################################### - if (state == 0): # - #if my_buy(): #开仓 - Log('开仓现在价格:',tickerx) - Log('开仓') - state = 1 - if (state == 1): # - value3_data=Close2_Close(Close3_list) #小周期 差值 - value4_data=Close2_Close(Close4_list) #小周期 差值 - # 小周期差值>0.4 or 小周期最低价格>MA3 or 现价格(成交价)Small1_Period or value2_data>value3_data or tickerx10): - if len(Ticker_list)>=min_size: - Ticker_list.pop(0) #返回并清除第一个数组 - Ticker_list.append(name) #追加元素 - else: - Ticker_list.append(name) #追加元素 - return 1,Ticker_list - except BaseException, e: - return 0,[] - -######################################################## -def Caltime(date1,date2): - try: - date1=time.strptime(date1,"%Y-%m-%d %H:%M:%S") - date2=time.strptime(date2,"%Y-%m-%d %H:%M:%S") - date1=datetime.datetime(date1[0],date1[1],date1[2],date1[3],date1[4],date1[5]) - date2=datetime.datetime(date2[0],date2[1],date2[2],date2[3],date2[4],date2[5]) - return date2-date1 - except Exception,ex: - Log('except Exception Caltime:',ex) - return "except Exception" - -outAccount = ext.GetAccount() #初始化信息 -outtickerx = _C(exchange.GetTicker).Last#Ticker 市场行情 最后成交价 -def print_log(k_p,data=""): - try: - name="" - if k_p: - name="开仓" - else: - name="平仓" - global outAccount,outtickerx - tickerx = _C(exchange.GetTicker).Last#Ticker 市场行情 最后成交价 - endAccount = ext.GetAccount() #当前账户信息 - ###################################### - #盈利计算方法 - #盈利计算方法 浮动利润: 按 (现在币 - 初始币)x 现在的价格 + (现在的钱 - 初始的钱) - diff_stocks=endAccount.Stocks-outAccount.Stocks #比的差值 - diff_balance=endAccount.Balance-outAccount.Balance #钱的差值 - new_end_balance=diff_stocks * tickerx + diff_balance #实现盈亏 #当前的盈利 - #盈利计算方法 账面利润 : (现在币 x 现在价格+现在钱) - (初始币 x 初始价格 + 初始钱) - new_end_balance2=(endAccount.Stocks*tickerx+endAccount.Balance)-(outAccount.Stocks*outtickerx+outAccount.Balance) - #当前账户RMB - end_rmb=(endAccount.Stocks*tickerx)+endAccount.Balance - ###################################### - - - date1=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time())) - LogStatus("初始化投入2016/9/24 投入0.2个币=等于行情800RMB\r\n", - "本次初始化状态:",outAccount, - "\r\n当前运 行状态:",endAccount, - "\r\n本次开始运行时间:%s 已运行:%s\r\n"%(start_time,Caltime(start_time,date1)), - "浮动利润:%s(RMB)\r\n"%(str(_N(new_end_balance,3))), - "账面利润:%s(RMB)\r\n"%(str(_N(new_end_balance2,3))), - "当前状态:%s--钱:%s--币:%s=%s(RMB)\r\n"%(str(name),str(endAccount.Balance),str(endAccount.Stocks),str(end_rmb)), - "更新时间:%s\r\n"%(date1), - "%s"%(data) - ) # 测试 - except Exception,ex: - Log('except Exception print_log:',ex) - - -def my_buy(): #开仓 - try: - global buy_price,buy_qty - initAccount = ext.GetAccount() #交易模板的导出函数, 获得账户状态,保存策略运行前账户初始状态 - opAmount=1 - #开仓之前判断有币没有没有先进行买入 - if int(initAccount.Stocks)>1: - if buy_price<1: - buy_price=_C(exchange.GetTicker).Last - buy_qty=initAccount.Stocks - Log('开仓信息1 仓内还有比:',initAccount.Stocks,'进行清空','--开仓详情:',initAccount) - return 1 - if int(initAccount.Stocks)<1: - if initAccount.Stocks>=0.03: #保证满足交易量 - # Log('不满足最小交易量:',initAccount.Stocks) - #return 1 #当前价格一定要大于 开仓价格 - #if int(str(initAccount.Stocks).replace('0.',''))>=3: - if buy_price<1: - buy_price=_C(exchange.GetTicker).Last - buy_qty=initAccount.Stocks - Log('开仓信息2 仓内还有比:',initAccount.Stocks,'进行清空','--开仓详情:',initAccount) - return 1 - - #if int(str(initAccount.Stocks).replace('0.',''))==0: - #这个地方有缺陷 仓位比例有缺陷 - #账户总钱数/开仓比例 *当前行情价 - tickerx = _C(exchange.GetTicker).Last#Ticker 市场行情 最后成交价 - scale=(initAccount.Balance/PositionRatio)*tickerx - opAmount = _N(scale,3) #买入数量 - Log("开仓没有币先进行 开仓买入%s元"%(str(opAmount))) #生成LOG日志 - - Dict = ext.Buy(opAmount) #买入ext.Buy - if(Dict):#确认开仓成功 - buy_price=Dict['price'] #买入价格 #{'price': 4046.446, 'amount': 1.5} - buy_qty=Dict['amount'] #买入数量 - #LogProfit(_N(gains,4),'开仓信息 钱:',initAccount.Balance,'--币:',initAccount.Stocks,'--开仓详情:',Dict) - print_log(1) - return 1 - return 0 - except Exception,ex: - Log('except Exception my_buy:',ex) - return 0 - -def my_sell(): #平仓 - try: - global buy_price,buy_qty,gains,ExitPeriod - nowAccount = ext.GetAccount() #交易模板的导出函数 获取账户信息 - if nowAccount.Stocks<=0.03: #保证满足交易量 - Log('不满足最小交易量:',nowAccount.Stocks) - return 1 #当前价格一定要大于 开仓价格 - Dict = ext.Sell(nowAccount.Stocks) - #Dict ={"price":_C(exchange.GetTicker).Last} - if(Dict): - sell_gains=(Dict['price']-buy_price)*Dict['amount'] - gains=gains+sell_gains - buy_price=0 #买入价格 - buy_qty=0 #买入数量 - LogProfit(_N(gains,4),'平仓信息 钱:',nowAccount.Balance,'--币:',nowAccount.Stocks,'--平仓详情:',Dict)#收益曲线 - print_log(0) - return 1 - return 0 - except Exception,ex: - Log('except Exception my_sell:',ex) - return 0 -######################################################## - - -def main(): - global buy_price - n=0 - state = 3 #开仓状态 - value1_data=0 #大周期 差值 - value2_data=0 #小周期 差值 - Log("run ",outAccount) #输出初始账户信息 - Close1_list=[] #开仓 大周期 - Close2_list=[] #开仓 小周期 - - Close3_list=[] #平仓 大周期 - Close4_list=[] #平仓 小周期 - - min_size=10 #获取秒级数据量 - min_list=[] #秒级均价 - min_size_list=[] #秒级 采集样本 - current_Last=0 #当前历史均价 - - b=0 #开仓 - a=0 #平仓 - while True: - try: - #nowAccountx = ext.GetAccount() #交易模板的导出函数 获取账户信息 - tickerx = _C(exchange.GetTicker).Last#Ticker 市场行情 最后成交价 - - # add_bool,f_list=add_min_list(min_size_list,tickerx,min_size) #添加秒级历史数据 - # if add_bool: - # min_size_list=f_list - # current_Last=int(_N(Volume_min_averages(min_size_list),2)) #当前历史均价 - #更新历史数据 - if n=int(Interval_s): #重置 - n=0 - ########################### - #PERIOD_M1 指1分钟,#PERIOD_M5 指5分钟,#PERIOD_M15 指15分钟,#PERIOD_M30 指30分钟,#PERIOD_H1 指1小时,#PERIOD_D1 指一天 - ticker = _C(exchange.GetRecords,PERIOD_M1)#Record 收盘价 - #Log('当前数据:',ticker) - minutes1_time=int(out_time(Enter_large_cycle)) #开仓 大周期 获取当前时间 获取时间戳 - minutes2_time=int(out_time(Enter_Small_cycle)) #开仓 小周期 获取当前时间 获取时间戳 - - minutes3_time=int(out_time(Exit_large_cycle)) #平仓 大周期 - minutes4_time=int(out_time(Exit_Small_cycle)) #平仓 小周期 - - timeB1=str(int(minutes1_time)) - timeB2=timeB1[:len(timeB1)] #我们设定的收盘时间 大周期 - #timeB_time=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(int(timeB2))) #时间戳 转换成日期 - - timeC1=str(int(minutes2_time)) - timeC2=timeC1[:len(timeC1)] #我们设定的收盘时间 大周期 - - timeD1=str(int(minutes3_time)) - timeD2=timeC1[:len(timeD1)] #我们设定的收盘时间 - - timeE1=str(int(minutes4_time)) - timeE2=timeC1[:len(timeE1)] #我们设定的收盘时间 - - for colour in ticker: - timeA1=str(int(colour.Time)) - timeA2=timeA1[:len(timeA1)-3] #收盘时间 - #timeA_time=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(int(timeA2))) #时间戳 转换成日期 - #开仓数据 - if int(timeA2)>int(timeB2): #收盘时间大于我们设定的时间及为 真 - #Log('大周期:',timeA_time,"|",timeA2,",",timeB_time,"|",timeB2) - Close1_list.append(colour.Close) #大周期 - if int(timeA2)>int(timeC2): #收盘时间大于我们设定的时间及为 真 - #Log('小周期:',timeA_time,"|",timeA2,",",timeC_time,"|",timeC2) - Close2_list.append(colour.Close) #小周期 - #平仓数据 - if int(timeA2)>int(timeD2): #收盘时间大于我们设定的时间及为 真 - Close3_list.append(colour.Close) #平仓 大周期 - if int(timeA2)>int(timeE2): #收盘时间大于我们设定的时间及为 真 - Close4_list.append(colour.Close) #平仓 大周期 - ######################################################################### - #开仓条件 - if (len(Close1_list)+1>=Enter_large_cycle and len(Close2_list)+1>=Enter_Small_cycle): - #说明数据收集完毕准备开始操作 - minu1_Close=_N(Volume_averages(Close1_list,Enter_large_cycle),2) #大周期 历史均价 - minu2_Close=_N(Volume_averages(Close2_list,Enter_Small_cycle),2) #小周期 历史均价 - if (minu1_Close>10 and minu2_Close>10): - minuN_Close=_N(minu2_Close-minu1_Close,3) - data="小周期均价减去大周期均价:%s"%(str(minuN_Close)) - print_log(0,data) - if (float(large1_Period)>=float(minuN_Close) and float(minuN_Close)>=float(large2_Period)): #判断这个差值在这个区间内则开仓 - #Log("ssssssssssssssssssssss",state) - if (state == 3): # - state = 0 #开仓 - ######################################################################### - EnterPeriod=1 #开仓观察期 - ExitPeriod=1 #平仓观察期 - if (state == 0): # - n = tickerx - #data="开仓 xxx检测成交价%s"% \ - # (str(tickerx)) - #Log(data) - #if n<0: #确定当前为死叉 - #if b>=int(n): #说明现在还是在下跌涨趋势 - if ((n >= b-0.5) and (n <=b+0.5)): - b=int(n) - else: #开始下跌 开仓 - if(int(n)>=int(b)+int(EnterPeriod)): #确认上行走势 至自己定义的点 - if my_buy(): #开仓 - #buy_price=tickerx - data="开仓 当前成交价%s"% \ - (str(tickerx)) - Log(data) - b=0 - state = 1 - if (state == 1): # - n = tickerx - #if n>0: #确定当前为金叉 - #计算2个值的差值 还是 +- 指定范围 - #if a<=int(n): #说明现在还是在上涨趋势 - if ((n >= a-0.5) and (n <=a+0.5)): - a=int(n) - else: #开始下跌 平仓 - #if(int(n)<=int(a)-int(ExitPeriod)): #确认下行走势 至自己定义的点 - if tickerx>buy_price+ExitPeriod: # - if my_sell(): #平仓 - data="平仓 开仓价格%s 当前成交价%s"% \ - (str(buy_price),str(tickerx)) - Log(data) - a=0 - state = 3 - if Exit_stop: #当完成这个开仓周期后 暂停几个周期不开仓 - Log('完成当前一次交易----暂停几个周期不开仓') - Sleep((Interval_s*Exit_stop)* 1000) - ################################################# - - - #Log('xxxx大周期:',len(Close1_list)) - #Log('xxxx小周期:',len(Close2_list)) - Close1_list=[] #大周期 清空 - Close2_list=[] #小周期 清空 - - Close3_list=[] #平仓 大周期 - Close4_list=[] #平仓 小周期 - except Exception,ex: - Log('except Exception main:',ex) - Sleep(1000) - - - From 93c402bc7c2f37e4d0859a6b7d24b0325a12af4c Mon Sep 17 00:00:00 2001 From: root Date: Wed, 18 Apr 2018 20:51:05 +0800 Subject: [PATCH 04/19] init --- ...3\347\224\250\344\276\213\345\255\220.cpp" | 0 ...44\346\230\223\347\255\226\347\225\245.js" | 7 +- ...4\351\234\207\350\215\241\345\236\213).js" | 275 ----------- ...21\345\212\250\346\255\242\346\215\237.js" | 199 -------- README.md | 43 +- ...07\346\240\207\344\271\260\345\215\226.js" | 120 ----- ...46\346\210\267\345\205\254\345\274\200.js" | 89 ++++ ...Thrust OKCoin \346\234\237\350\264\247.py" | 8 +- ...13\350\257\225\347\211\210\357\274\211.py" | 5 +- ...11\345\217\252\344\271\214\351\270\246.js" | 6 +- ...20\347\240\224\347\251\266\343\200\221.js" | 126 +++++ ...01\347\240\264\345\211\215\351\253\230.py" | 2 +- ...66\345\267\256\344\273\267\345\233\276.js" | 111 +++++ ...346\211\230 - \344\271\260\345\205\245.js" | 86 ++-- ...346\211\230 - \345\215\226\345\207\272.js" | 74 +-- ...07\350\241\241\347\255\226\347\225\245.js" | 8 +- ...44\346\230\223\347\261\273\345\272\223.js" | 10 +- ...15\347\255\226\347\225\245 Dual Thrust.js" | 178 ------- ...60\345\215\226\347\255\226\347\225\245.js" | 155 ------- ...5\256\232\345\245\227\345\210\251 V2.1.js" | 305 ------------ ...(\344\271\260\344\270\200\344\273\267).js" | 26 +- ...6\344\273\267\345\245\227\345\210\251).js" | 252 ---------- ...56\200\345\215\225\347\211\210 (Copy).js" | 76 +++ ...73\345\234\272\345\215\226\345\215\225.js" | 48 +- ...345\217\260API\346\265\213\350\257\225.js" | 33 -- ...347\225\245 - \345\257\271\346\225\262.js" | 63 +-- ...46\230\223\347\261\273\345\272\223c++.cpp" | 0 ...\245 \345\205\274\345\256\271OK-VC-796.js" | 434 ------------------ ...\261\225\347\244\272Python\347\211\210.py" | 73 +++ ...46\346\210\267\344\275\231\351\242\235.js" | 59 --- ...25\350\276\271\347\275\221\346\240\274.js" | 10 +- ...07\350\215\241\347\255\226\347\225\245.js" | 60 +-- 32 files changed, 632 insertions(+), 2309 deletions(-) rename "C++ API\350\260\203\347\224\250\344\276\213\345\255\220.js" => "C++ API\350\260\203\347\224\250\344\276\213\345\255\220.cpp" (100%) delete mode 100644 "Dual Thrust (\345\217\257\345\201\232\345\244\232\345\201\232\347\251\272\357\274\214\351\234\207\350\215\241\345\236\213).js" delete mode 100644 "MACD\344\275\216\344\271\260\351\253\230\345\215\226\350\207\252\345\212\250\350\267\237\345\215\225\346\273\221\345\212\250\346\255\242\346\215\237.js" delete mode 100644 "RSI\346\214\207\346\240\207\344\271\260\345\215\226.js" create mode 100644 "okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.js" create mode 100644 "\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.js" create mode 100644 "\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.js" delete mode 100644 "\345\233\275\345\244\226\347\237\245\345\220\215\347\255\226\347\225\245 Dual Thrust.js" delete mode 100644 "\345\235\207\347\272\277\344\271\260\345\215\226\347\255\226\347\225\245.js" delete mode 100644 "\345\244\232\345\271\263\345\217\260\345\257\271\345\206\262\347\250\263\345\256\232\345\245\227\345\210\251 V2.1.js" delete mode 100644 "\345\245\227\345\210\251\350\275\257\344\273\266(\345\267\256\344\273\267\345\245\227\345\210\251).js" create mode 100644 "\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210 (Copy).js" delete mode 100644 "\345\271\263\345\217\260API\346\265\213\350\257\225.js" rename "\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.js" => "\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.cpp" (100%) delete mode 100644 "\346\234\237\350\264\247\345\201\232\345\270\202\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245 \345\205\274\345\256\271OK-VC-796.js" create mode 100644 "\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.py" delete mode 100644 "\347\273\237\350\256\241BitVC\345\212\250\346\200\201\346\235\203\347\233\212-OKCoin\345\267\262\347\273\217\345\256\236\347\216\260\347\233\210\344\272\217-796\350\264\246\346\210\267\344\275\231\351\242\235.js" diff --git "a/C++ API\350\260\203\347\224\250\344\276\213\345\255\220.js" "b/C++ API\350\260\203\347\224\250\344\276\213\345\255\220.cpp" similarity index 100% rename from "C++ API\350\260\203\347\224\250\344\276\213\345\255\220.js" rename to "C++ API\350\260\203\347\224\250\344\276\213\345\255\220.cpp" diff --git "a/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" "b/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" index ade34246..11d5c650 100644 --- "a/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" +++ "b/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" @@ -45,9 +45,10 @@ KeepRatio 10 */ /*backtest -start: 2016-03-01 -end: 2016-12-30 -period: 60 +start: 2016-03-01 00:00:00 +end: 2016-12-30 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] */ var _bot = $.NewPositionManager(); diff --git "a/Dual Thrust (\345\217\257\345\201\232\345\244\232\345\201\232\347\251\272\357\274\214\351\234\207\350\215\241\345\236\213).js" "b/Dual Thrust (\345\217\257\345\201\232\345\244\232\345\201\232\347\251\272\357\274\214\351\234\207\350\215\241\345\236\213).js" deleted file mode 100644 index 7ee7c399..00000000 --- "a/Dual Thrust (\345\217\257\345\201\232\345\244\232\345\201\232\347\251\272\357\274\214\351\234\207\350\215\241\345\236\213).js" +++ /dev/null @@ -1,275 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/351 -策略名称: Dual Thrust (可做多做空,震荡型) -策略作者: Zero -策略描述: - -Dual Thrust - - -参数 默认值 描述 -------------------- ----- ---------- -NPeriod 4 计算周期 -Ks 0.5 上轨系数 -Kx 0.5 下轨系数 -Interval 2000 出错重试间隔(毫秒) -SlidePrice 0.01 滑动价(元) -StopLoss 0.8 止损点 -StopProfitThreshold 0.9 止盈系数(0-1) -EnableGoingShort true 允许做空 -LoopInterval true 轮询间隔(秒) -AmountOnce 0.2 单笔交易数量 -*/ - - -function adjustFloat(v) { - return Math.floor(v*1000)/1000; -} - -function GetOrders() { - var orders = null; - while (!(orders = exchange.GetOrders())) { - Sleep(Interval); - } - return orders; -} - -function CancelPendingOrders() { - while (true) { - var orders = GetOrders(); - if (orders.length == 0) { - return; - } - - for (var j = 0; j < orders.length; j++) { - exchange.CancelOrder(orders[j].Id, orders[j]); - if (j < (orders.length-1)) { - Sleep(Interval); - } - } - } -} - -function GetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(Interval); - } - return account; -} - -function GetTicker(e) { - if (typeof(e) == 'undefined') { - e = exchange; - } - var ticker; - while (!(ticker = e.GetTicker())) { - Sleep(Interval); - } - return ticker; -} - - -function Highest(records, attr, n) { - var v = 0; - for (var pos = records.length - n; pos < records.length; pos++) { - v = Math.max(v, records[pos][attr]); - } - return v; -} - -function Lowest(records, attr, n) { - var v = -1; - for (var pos = records.length - n; pos < records.length; pos++) { - if (v == -1) { - v = records[pos][attr]; - } else { - v = Math.min(v, records[pos][attr]); - } - } - return v; -} - -function updateProft(accountInit, accountNow, ticker) { - var netNow = accountNow.Balance + accountNow.FrozenBalance + ((accountNow.Stocks + accountNow.FrozenStocks) * ticker.Buy); - var netInit = accountInit.Balance + accountInit.FrozenBalance + ((accountInit.Stocks + accountInit.FrozenStocks) * ticker.Buy); - LogProfit(adjustFloat(netNow - netInit)); -} - -var STATE_WAIT_IDLE = 0; -var STATE_WAIT_BUY = 1; -var STATE_WAIT_SELL = 2; -var STATE_BUY = 3; -var STATE_SELL = 4; - -var State = STATE_WAIT_IDLE; -var InitAccount = null; -var LastBuyPrice = 0; -var LastSellPrice = 0; -var LastHighPrice = 0; -var LastLowPrice = 0; -var LastRecord = null; -var Goingshort = false; -var LastEpoch = 0; - -function onTick(exchange) { - var oldState = State; - - if (State == STATE_WAIT_IDLE) { - var records = exchange.GetRecords(); - if (!records || records.length <= NPeriod) { - return; - } - var Bar = records[records.length-1]; - if (LastEpoch == 0) { - LastEpoch = Bar.Time; - } - if (LastEpoch == Bar.Time) { - return; - } - - var Range = 0; - var HH = Highest(records, 'High', NPeriod); - var HC = Highest(records, 'Close', NPeriod); - var LL = Lowest(records, 'Low', NPeriod); - var LC = Lowest(records, 'Close', NPeriod); - - if ((HH - LC) >= (HC - LL)) { - Range = HH - LC; - } else { - Range = HC - LL; - } - - if (Bar.High >= (Bar.Open + (Ks * Range))) { - Goingshort = false; - State = STATE_BUY; - LastEpoch = Bar.Time; - Log('开始做多'); - } else if (Bar.Low <= (Bar.Open - (Kx * Range))) { - Goingshort = true; - State = STATE_SELL; - LastEpoch = Bar.Time; - Log('开始做空'); - } else { - return; - } - } - - var ticker = GetTicker(); - - // 重新设置这两个参数 - if (oldState == STATE_WAIT_IDLE && State != STATE_WAIT_IDLE) { - LastLowPrice = ticker.Last; - LastHighPrice = ticker.Last; - } - - // 做多 - if (!Goingshort) { - if (State == STATE_WAIT_SELL) { - var ratioStopLoss = Math.abs((LastHighPrice - ticker.Last) / LastHighPrice) * 100; - var ratioStopProfit = Math.abs((ticker.Last - LastBuyPrice) / LastBuyPrice) * 100; - var ratioMaxUp = Math.abs((LastHighPrice - LastBuyPrice) / LastBuyPrice) * 100; - if (ticker.Last < LastBuyPrice && ratioStopLoss >= StopLoss) { - State = STATE_SELL; - Log("开始止损, 当前下跌点数:", adjustFloat(ratioStopLoss), "当前价格", ticker.Last, "对比价格", adjustFloat(LastHighPrice)); - } else if (ticker.Last > LastBuyPrice && ticker.Last < LastHighPrice && ratioStopProfit <= (ratioMaxUp*StopProfitThreshold)) { - State = STATE_SELL; - Log("开始止赢, 当前上涨点数:", adjustFloat(ratioStopProfit), "当前价格", ticker.Last, "对比价格", adjustFloat(LastBuyPrice)); - } - LastHighPrice = Math.max(LastHighPrice, ticker.Last); - } - } else { - if (State == STATE_WAIT_BUY) { - var ratioStopLoss = Math.abs((ticker.Last - LastLowPrice) / LastLowPrice) * 100; - var ratioStopProfit = Math.abs((LastSellPrice - ticker.Last) / LastSellPrice) * 100; - var ratioMaxDown = Math.abs((LastSellPrice - LastLowPrice) / LastSellPrice) * 100; - if (ticker.Last > LastSellPrice && ratioStopLoss >= StopLoss) { - State = STATE_BUY; - Log("开始止损, 当前上涨点数:", adjustFloat(ratioStopLoss), "当前价格", ticker.Last, "对比价格", adjustFloat(LastSellPrice)); - } else if (ticker.Last < LastSellPrice && ticker.Last > LastLowPrice && ratioStopProfit <= (ratioMaxDown*StopProfitThreshold)) { - State = STATE_BUY; - Log("开始止盈, 当前下跌点数:", adjustFloat(ratioStopProfit), "当前价格", ticker.Last, "对比价格", adjustFloat(LastLowPrice)); - } - LastHighPrice = Math.max(LastHighPrice, ticker.Last); - LastLowPrice = Math.min(LastLowPrice, ticker.Last); - } - - } - - if (State != STATE_BUY && State != STATE_SELL) { - return; - } - var orders = GetOrders(); - if (orders.length > 0) { - if (((State == STATE_BUY) && (LastBuyPrice >= (ticker.Buy-SlidePrice))) || ((State == STATE_SELL) && (LastSellPrice <= (ticker.Sell-SlidePrice)))) { - return; - } - } - // Buy or Sell, Cancel pending orders first - CancelPendingOrders(); - // Wait Ticker Update - Sleep(3000); - var account = GetAccount(); - // Update Ticker - ticker = GetTicker(); - - // 做多 - if (!Goingshort) { - if (State == STATE_BUY) { - var price = ticker.Buy + SlidePrice; - var amount = adjustFloat(Math.min(AmountOnce, account.Balance / price)); - if (amount >= exchange.GetMinStock()) { - if (exchange.Buy(price, amount)) { - LastBuyPrice = LastHighPrice = price; - } - } else { - State = STATE_WAIT_SELL; - } - } else { - var sellAmount = Math.min(AmountOnce, account.Stocks - InitAccount.Stocks); - if (sellAmount > exchange.GetMinStock()) { - exchange.Sell(ticker.Sell - SlidePrice, sellAmount); - LastSellPrice = price; - } else { - // No stocks, wait buy and log profit - updateProft(InitAccount, account, ticker); - State = STATE_WAIT_IDLE; - } - } - } else { - if (State == STATE_BUY) { - var price = ticker.Buy + SlidePrice; - var amount = adjustFloat(Math.min(AmountOnce, account.Balance / price, InitAccount.Stocks - account.Stocks)); - if (amount >= exchange.GetMinStock()) { - exchange.Buy(price, amount); - LastBuyPrice = price; - } else { - updateProft(InitAccount, account, ticker); - State = STATE_WAIT_IDLE; - } - } else { - var price = ticker.Sell - SlidePrice; - var sellAmount = Math.min(AmountOnce, account.Stocks); - if (sellAmount > exchange.GetMinStock()) { - exchange.Sell(price, sellAmount); - LastSellPrice = LastLowPrice = price; - } else { - // No stocks, wait buy and log profit - State = STATE_WAIT_BUY; - } - } - } -} - -function main() { - InitAccount = GetAccount(); - LoopInterval = Math.min(1, LoopInterval); - Log('交易平台:', exchange.GetName(), InitAccount); - - EnableGoingShort = EnableGoingShort && (InitAccount.Stocks > exchange.GetMinStock()); - LoopInterval = Math.max(LoopInterval, 1); - while (true) { - onTick(exchange); - Sleep(LoopInterval*1000); - } -} diff --git "a/MACD\344\275\216\344\271\260\351\253\230\345\215\226\350\207\252\345\212\250\350\267\237\345\215\225\346\273\221\345\212\250\346\255\242\346\215\237.js" "b/MACD\344\275\216\344\271\260\351\253\230\345\215\226\350\207\252\345\212\250\350\267\237\345\215\225\346\273\221\345\212\250\346\255\242\346\215\237.js" deleted file mode 100644 index b04d9f7f..00000000 --- "a/MACD\344\275\216\344\271\260\351\253\230\345\215\226\350\207\252\345\212\250\350\267\237\345\215\225\346\273\221\345\212\250\346\255\242\346\215\237.js" +++ /dev/null @@ -1,199 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/3 -策略名称: MACD低买高卖自动跟单滑动止损 -策略作者: Zero -策略描述: - -交叉后前一柱指金叉后的第一柱的值, 交叉后前一柱指金叉前的最后一个柱的值, 滑动价格指下单时加的价格,比如买单会现价加上这个价格,卖单会减去这个价格 - - -参数 默认值 描述 ------------- ------ ------- -ac1 0.005 交叉后第一柱 -bc1 -1e-06 交叉后前一柱 -SlidePrice 0.3 滑动价格 -TrailingStop 0.5 止损点 -orderTimeout 30 买单超时(秒) -*/ - - -Fixed = function(v) { - return Math.floor(v*1000)/1000; -}; - -// for orders -WaitOrder = function(exchange, orderId, timeoutToCancel) { - var ts = (new Date()).getTime(); - while (true) { - Sleep(3000); - var orderInfo = exchange.GetOrder(orderId); - if (!orderInfo) { - continue; - } - if (orderInfo.Status == ORDER_STATE_CLOSED || orderInfo.Status == ORDER_STATE_CANCELED) { - return orderInfo; - } - if (((new Date()).getTime() - ts) > timeoutToCancel) { - exchange.CancelOrder(orderId); - } - } -}; - -Buy = function(exchange, maxPrice, slidePrice, balanceRatio, timeoutS) { - var ts = (new Date()).getTime(); - var account; - var dealAmount = 0.0; - var usedBlance = 0.0; - var maxBalanceUse = 0.0; - var isFirst = true; - do { - if (isFirst) { - isFirst = false; - } else { - Sleep(3000); - } - - var ticker = exchange.GetTicker(); - if (!ticker) { - continue; - } - - var buyPrice = ticker.Sell + slidePrice; - - // Price too high, wait... - if (buyPrice > maxPrice) { - continue; - } - - // Initialize at first - if (!account) { - account = exchange.GetAccount(); - if (!account) { - continue; - } - // Initialize maxBalanceUse - maxBalanceUse = account.Balance * balanceRatio; - } - - var buyAmount = Fixed((maxBalanceUse - usedBlance) / buyPrice); - if (buyAmount < exchange.GetMinStock()) { - break; - } - - orderId = exchange.Buy(buyPrice, buyAmount); - if (!orderId) { - Log(buyPrice, buyAmount, maxBalanceUse, usedBlance); - continue; - } - - var orderInfo = WaitOrder(exchange, orderId, timeoutS); - dealAmount += orderInfo.DealAmount; - usedBlance += orderInfo.Price * orderInfo.DealAmount; - if (orderInfo.Status == ORDER_STATE_CLOSED) { - break; - } - } while (((new Date()).getTime() - ts) < timeoutS); - - return {amount: dealAmount, price: (dealAmount > 0 ? usedBlance / dealAmount : 0)}; -}; - -Sell = function(exchange, sellAmount, slidePrice) { - // Account info must set - var account = exchange.GetAccount(); - while (!account) { - Sleep(2000); - account = exchange.GetAccount(); - } - - sellAmount = Math.min(sellAmount, account.Stocks); - - var cash = 0.0; - var remain = sellAmount; - - while (remain >= exchange.GetMinStock()) { - var ticker = exchange.GetTicker(); - if (!ticker) { - Sleep(2000); - continue; - } - var sellPrice = ticker.Buy - slidePrice; - var sellOrderId = exchange.Sell(sellPrice, remain); - if (!sellOrderId) { - Sleep(2000); - continue; - } - var orderInfo = WaitOrder(exchange, sellOrderId, 10000); - remain -= orderInfo.DealAmount; - cash += orderInfo.Price * orderInfo.DealAmount; - } - return {amount: sellAmount, price: (sellAmount > 0 ? cash / sellAmount : 0)}; -}; - -var BuyInfo; -var BanlanceRatio = 1.0; -var Profit = 0.0; -var timeAtBuy = 0; - -function onTick(exchange) { - var ticker = exchange.GetTicker(); - var records = exchange.GetRecords(); - if (!ticker || !records || records.length < 45) { - return; - } - - var ticks = []; - for (var i = 0; i < records.length; i++) { - ticks.push(records[i].Close); - } - - var macd = TA.MACD(records, 12, 26, 9); - var dif = macd[0]; - var dea = macd[1]; - var his = macd[2]; - - var op = 0; - if (!BuyInfo) { - if (dif[ticks.length-1] > 0 && his[ticks.length-1] > ac1 && his[ticks.length-2] < bc1) { - op = 1; - } - } else { - if (records[records.length-2].Time > timeAtBuy && records[records.length-1].Close < records[records.length-1].Open - 0.5 - && records[records.length-2].Close < records[records.length-2].Open - 0.5 - && records[records.length-1].Close < records[records.length-2].Close - 0.5) { - op = 2; - } else if (records[records.length-2].Time > timeAtBuy && BuyInfo.price > records[records.length-1].Close && records[records.length-1].Close < records[records.length-1].Open - 0.5) { - op = 2; - } else if ((BuyInfo.price < ticker.Last || dif[ticks.length-1] < 0) && his[ticks.length-1] <= 0) { - op = 2; - } else if ((BuyInfo.price > ticker.Last) && ((BuyInfo.price - ticker.Last) / BuyInfo.price > TrailingStop)) { - op = 2; - } - } - - if (op == 1) { - var info = Buy(exchange, ticker.Sell + (SlidePrice * 3), SlidePrice, BanlanceRatio, orderTimeout * 1000); - if (info.amount > 0) { - BuyInfo = info; - timeAtBuy = records[records.length-1].Time; - } - } else if (op == 2) { - var info = Sell(exchange, BuyInfo.amount, SlidePrice); - if (info.amount > 0) { - Profit += info.amount * (info.price - BuyInfo.price); - LogProfit(Profit); - BuyInfo = null; - } - } -} - -function main() { - var account = exchange.GetAccount(); - if (account) { - Log(exchange.GetName(), exchange.GetCurrency(), account); - } - - while (true) { - onTick(exchange); - Sleep(30000); - } -} diff --git a/README.md b/README.md index f2542fbe..ee2a169c 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,28 @@ > 开源策略列表 + - [python版CTP商品期货交易类库(支持2/3 测试版)](https://www.botvs.com/strategy/24288) + - [商品期货交易类库](https://www.botvs.com/strategy/12961) + - [网格变形策略之单边网格](https://www.botvs.com/strategy/629) + - [talib简单应用之查找三只乌鸦](https://www.botvs.com/strategy/62163) + - [内外盘期货品种实时差价图](https://www.botvs.com/strategy/82929) + - [测试多图表展示Python版](https://www.botvs.com/strategy/84042) + - [定投简单版 (Copy)](https://www.botvs.com/strategy/83805) + - [okex-BTC合约账户公开](https://www.botvs.com/strategy/83189) + - [抢盘口做市策略 - 对敲](https://www.botvs.com/strategy/304) + - [冰山委托 - 卖出](https://www.botvs.com/strategy/241) + - [冰山委托 - 买入](https://www.botvs.com/strategy/236) + - [趋势跟踪震荡策略](https://www.botvs.com/strategy/179) + - [多平台强制滑动平仓(买一价)](https://www.botvs.com/strategy/99) + - [定点进场下单定点离场卖单](https://www.botvs.com/strategy/64) + - [【001】单平台均衡策略 【研究】](https://www.botvs.com/strategy/82325) + - [CTP商品期货多品种海龟交易策略](https://www.botvs.com/strategy/17289) + - [python版 Dual Thrust OKCoin 期货](https://www.botvs.com/strategy/21856) + - [五线向上&&突破前高](https://www.botvs.com/strategy/76827) + - [单平台均衡策略](https://www.botvs.com/strategy/345) - [数字货币现货交易类库](https://www.botvs.com/strategy/10989) - [数字货币交易类库 (期货支持OKCoin期货/BitVC, 支持$.CTA函数)](https://www.botvs.com/strategy/57267) - - [五线向上&&突破前高](https://www.botvs.com/strategy/76827) - [C++ API调用例子](https://www.botvs.com/strategy/61533) - - [python版CTP商品期货交易类库(支持2/3 测试版)](https://www.botvs.com/strategy/24288) - - [商品期货交易类库](https://www.botvs.com/strategy/12961) - [定期定额投资BTC盈利验证](https://www.botvs.com/strategy/65030) - [双平台对冲js版本(two platforms hedging-JS)](https://www.botvs.com/strategy/57556) - [转换任意K线周期管理模板(最近更新20180118)](https://www.botvs.com/strategy/41163) @@ -24,7 +40,6 @@ - [不要怂就是干 (Copy)](https://www.botvs.com/strategy/65114) - [Shannon's Demon](https://www.botvs.com/strategy/64455) - [画线类库](https://www.botvs.com/strategy/27293) - - [talib简单应用之查找三只乌鸦](https://www.botvs.com/strategy/62163) - [回测保存K线到本地CSV](https://www.botvs.com/strategy/61867) - [02顺大势逆小势策略之代码实现及可行性分析 (Share 1513097042)](https://www.botvs.com/strategy/63223) - [03基于商品期货的套利策略模型 (Share 1513096985)](https://www.botvs.com/strategy/63221) @@ -34,7 +49,6 @@ - [双平台对冲js版本(two platforms hedging-JS) (Copy)](https://www.botvs.com/strategy/61405) - [2014年的简易短线机器人 (Copy) (Share 1512130985)](https://www.botvs.com/strategy/61398) - [2014年的简易短线机器人](https://www.botvs.com/strategy/1088) - - [python版 Dual Thrust OKCoin 期货](https://www.botvs.com/strategy/21856) - [简单多品种商品期货均线策略](https://www.botvs.com/strategy/57029) - [测试 默认 参数组功能](https://www.botvs.com/strategy/40155) - [全球10大交易系统之 Aberration 多品种商品期货交易系统](https://www.botvs.com/strategy/25943) @@ -44,7 +58,6 @@ - [如何找出一定Bar数量的 K线前期高点、低点 及 Demo 程序](https://www.botvs.com/strategy/58179) - [python版现货数字货币交易类库](https://www.botvs.com/strategy/21104) - [数字货币交易类库 (期货支持OKCoin期货/BitVC)](https://www.botvs.com/strategy/30199) - - [CTP商品期货多品种海龟交易策略](https://www.botvs.com/strategy/17289) - [一目均衡](https://www.botvs.com/strategy/55839) - [StochRSI(和okcoin一致)](https://www.botvs.com/strategy/56119) - [使用 BotVS 构建一个机械化策略](https://www.botvs.com/strategy/40357) @@ -65,7 +78,6 @@ - [知乎专栏 实例文章策略](https://www.botvs.com/strategy/40266) - [BitMEX 简单测试](https://www.botvs.com/strategy/40289) - [商品期货查看账户详细信息](https://www.botvs.com/strategy/37793) - - [网格变形策略之单边网格](https://www.botvs.com/strategy/629) - [股票证券查询买卖示例](https://www.botvs.com/strategy/5541) - [测试多图表展示](https://www.botvs.com/strategy/38203) - [商品期货结算单平仓盈亏历史查询](https://www.botvs.com/strategy/38083) @@ -127,18 +139,13 @@ - [模板库使用例子](https://www.botvs.com/strategy/10991) - [价值0.418](https://www.botvs.com/strategy/10744) - [传统期货差价监控 (CTP)](https://www.botvs.com/strategy/5379) - - [期货做市高频交易策略 兼容OK/VC/796](https://www.botvs.com/strategy/1484) - [融资融币统计](https://www.botvs.com/strategy/8954) - [【Demo】如何利用“策略交互“动态调整策略参数](https://www.botvs.com/strategy/8379) - [【Demo】速度测试 websocket vs rest](https://www.botvs.com/strategy/7547) - [平台价格比较1.0](https://www.botvs.com/strategy/8266) - - [MACD低买高卖自动跟单滑动止损](https://www.botvs.com/strategy/3) - - [均线买卖策略](https://www.botvs.com/strategy/143) - - [趋势跟踪震荡策略](https://www.botvs.com/strategy/179) - [多平台账户统计](https://www.botvs.com/strategy/7827) - [计划委托买入](https://www.botvs.com/strategy/638) - [计划委托卖出](https://www.botvs.com/strategy/747) - - [RSI指标买卖](https://www.botvs.com/strategy/31) - [阶梯下单 - 可设置触发价格](https://www.botvs.com/strategy/639) - [单点狙击高频加仓自动反手解套算法 V1.2](https://www.botvs.com/strategy/2406) - [796期货反手加倍算法](https://www.botvs.com/strategy/3648) @@ -148,24 +155,12 @@ - [多线程获取多个交易的账户信息](https://www.botvs.com/strategy/3297) - [OKCoin期货条件触发委托带止损](https://www.botvs.com/strategy/2169) - [监视并显示多个平台的全部资产总和的变化](https://www.botvs.com/strategy/443) - - [多平台对冲稳定套利 V2.1](https://www.botvs.com/strategy/57) - - [抢盘口做市策略 - 对敲](https://www.botvs.com/strategy/304) - - [Dual Thrust (可做多做空,震荡型)](https://www.botvs.com/strategy/351) - - [统计BitVC动态权益/OKCoin已经实现盈亏/796账户余额](https://www.botvs.com/strategy/1483) - [BTC/LTC 地址监视, 短信通知](https://www.botvs.com/strategy/1295) - - [冰山委托 - 卖出](https://www.botvs.com/strategy/241) - - [冰山委托 - 买入](https://www.botvs.com/strategy/236) - [统计K线回测是否存在趋势](https://www.botvs.com/strategy/1125) - [价格波动报警](https://www.botvs.com/strategy/885) - [取消所有订单](https://www.botvs.com/strategy/280) - [新手入门之 - 下买单卖单](https://www.botvs.com/strategy/796) - [短信通知接口测试](https://www.botvs.com/strategy/653) - [抢盘口做市策略 - 高频逼近型](https://www.botvs.com/strategy/348) - - [国外知名策略 Dual Thrust](https://www.botvs.com/strategy/153) - - [单平台均衡策略](https://www.botvs.com/strategy/345) - - [套利软件(差价套利)](https://www.botvs.com/strategy/275) - - [多平台强制滑动平仓(买一价)](https://www.botvs.com/strategy/99) - [每1分钟统计各个平台间的差价(by JackConan)](https://www.botvs.com/strategy/98) - - [平台API测试](https://www.botvs.com/strategy/71) - - [定点进场下单定点离场卖单](https://www.botvs.com/strategy/64) - [统计各个平台间的最大差价(by JackConan)](https://www.botvs.com/strategy/86) diff --git "a/RSI\346\214\207\346\240\207\344\271\260\345\215\226.js" "b/RSI\346\214\207\346\240\207\344\271\260\345\215\226.js" deleted file mode 100644 index a04b8153..00000000 --- "a/RSI\346\214\207\346\240\207\344\271\260\345\215\226.js" +++ /dev/null @@ -1,120 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/31 -策略名称: RSI指标买卖 -策略作者: Zero -策略描述: - -RSI简单买卖测试, 默认 70-100卖出,0-30买入 - - -参数 默认值 描述 ----------- ----- --------- -RSIPeriod 14 RSI周期 -SlidePrice 0.3 下单滑动值 -RSIBuyL false RSI买入点(低) -RSIBuyH 30 RSI买入点(高) -RSISellL 70 RSI卖出点(低) -RSISellH 100 RSI卖出点(高) -Interval 1000 出错重试(毫秒) -*/ - -function adjustFloat(v) { - return Math.floor(v*1000)/1000; -} - -function cancelPendingOrders() { - while (true) { - var orders = exchange.GetOrders(); - if (orders) { - if (orders.length == 0) { - break; - } - for (var j = 0; j < orders.length; j++) { - exchange.CancelOrder(orders[j].Id); - Sleep(Interval); - } - } else { - Sleep(Interval); - } - } -} - -var STATE_WAIT_BUY = 0; -var STATE_WAIT_SELL = 1; -var STATE_BUY = 2; -var STATE_SELL = 3; -var STATE_WAIT_SELL_ALL = 4; - - -var State = STATE_WAIT_BUY; - -var InitAccount; - -function MustGetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(2000); - } - return account; -} - -function onTick(exchange) { - var records = exchange.GetRecords(); - if (!records || records.length < (RSIPeriod + 5)) { - return; - } - - rsi = TA.RSI(records, RSIPeriod); - var rsiValue = rsi[records.length - 1]; - if (State == STATE_WAIT_BUY && rsiValue >= RSIBuyL && rsiValue <= RSIBuyH) { - State = STATE_BUY; - } else if (State == STATE_WAIT_SELL && rsiValue >= RSISellL && rsiValue <= RSISellH) { - State = STATE_SELL; - } else if (State != STATE_WAIT_SELL_ALL){ - return; - } - - // Buy or Sell, Cancel pending orders first - cancelPendingOrders(); - - var account = MustGetAccount(); - var ticker = exchange.GetTicker(); - if (!account || !ticker) { - return; - } - - if (State == STATE_BUY) { - var price = ticker.Last + SlidePrice; - var amount = adjustFloat(account.Balance / price); - if (amount >= exchange.GetMinStock()) { - if (exchange.Buy(price, amount)) { - State = STATE_WAIT_SELL; - } - } - } else { - if (account.Stocks > exchange.GetMinStock()) { - // STATE_WAIT_SELL or STATE_WAIT_SELL_ALL - State = STATE_WAIT_SELL_ALL; - exchange.Sell(ticker.Last - SlidePrice, account.Stocks); - } else { - // No stocks, wait buy and log profit - LogProfit(account.Balance - InitAccount.Balance); - Log(account); - State = STATE_WAIT_BUY; - } - } -} - -function main() { - InitAccount = MustGetAccount(); - Log(InitAccount); - if (InitAccount.Stocks > 0) { - throw "必须空仓介入"; - return; - } - - while (true) { - onTick(exchange); - Sleep(30000); - } -} diff --git "a/okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.js" "b/okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.js" new file mode 100644 index 00000000..60c4135f --- /dev/null +++ "b/okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.js" @@ -0,0 +1,89 @@ +/* +策略出处: https://www.botvs.com/strategy/83189 +策略名称: okex-BTC合约账户公开 +策略作者: leviyuan +策略描述: + + + +*/ + +var exchangeRate = 6.4, + usdprice = 1000 + +var chartCfg = [{ + title: { + text: "账户监控" + }, + xAxis: { + type: 'datetime' + }, + series: [{ + name: "账户当前资金价值", + data: [] + }, { + name: "本周起始BTC的当前价值", + data: [] + }] +}] + +function GetWebJson(url) { + for (var i = 0; i < 10; i++) { + try { + return JSON.parse(HttpQuery(url)) + } catch (e) { + Sleep(500) + } + } +} + +function main() { + exchange.SetRate(1) + LogReset() + + var chart = Chart(chartCfg) + chart.reset() + + var nxttime = new Date().getTime() + while (true) { + var accountinfo = _C(exchange.GetAccount) + try { + var bdata = GetWebJson("https://api-otc.huobipro.com/v1/otc/trade/list/public?coinId=2&tradeType=0¤tPage=1&payWay=&country=&merchant=1&online=1&range=0").data + var sdata = GetWebJson("https://api-otc.huobipro.com/v1/otc/trade/list/public?coinId=2&tradeType=1¤tPage=1&payWay=&country=&merchant=1&online=1&range=0").data + var count = 0, + rate = 0 + for (var k = 0; k < 3; k++) { + count += bdata[k].tradeCount + count += sdata[k].tradeCount + rate += bdata[k].price * bdata[k].tradeCount + rate += sdata[k].price * sdata[k].tradeCount + } + exchangeRate = rate / count + } catch (e) {} + try { + usdprice = GetWebJson("https://www.okex.com/api/v1/future_index.do?symbol=btc_usd").future_index + } catch (e) {} + var rmb = accountinfo.Info.info.btc.account_rights * usdprice * exchangeRate + var startcount = accountinfo.Info.info.btc.account_rights - accountinfo.Info.info.btc.profit_real - accountinfo.Info.info.btc.profit_unreal + + // 刷新图表 + chart.add(0, [new Date().getTime(), rmb]) + chart.add(1, [new Date().getTime(), startcount * exchangeRate * usdprice]) + + var message = "合约账户当前权益:฿" + accountinfo.Info.info.btc.account_rights + "btc\n" + + "本周已实现盈亏:฿" + accountinfo.Info.info.btc.profit_real + "btc\n" + + "未实现盈亏:฿" + accountinfo.Info.info.btc.profit_unreal + "btc\n" + + "火币OTC汇率:" + exchangeRate.toFixed(2) + "\n" + + "BTC价格指数:$" + usdprice + "\n" + + "折算RMB价格:¥" + (usdprice * exchangeRate).toFixed(0) + "\n" + + "资产折合:¥" + rmb.toFixed(0) + "/ $" + (rmb / exchangeRate).toFixed(0) + "\n" + + "账户保证金率:" + (accountinfo.Info.info.btc.risk_rate * 100).toFixed(1) + "%\n" + + _D(new Date().getTime()) + LogStatus(message) + + var nowtime = new Date().getTime() + while (nxttime < nowtime) + nxttime += 30 * 60 * 1000 + Sleep(nxttime - nowtime) + } +} diff --git "a/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" "b/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" index 2bebfe21..102be53f 100644 --- "a/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" +++ "b/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" @@ -101,9 +101,9 @@ def Trade(currentState,nextState): Log(_C(exchange.GetPosition)) # ceshi exchange.SetDirection("closebuy" if currentState == STATE_LONG else "closesell") while True: - # ID = pfn( (ticker['Last'] - slidePrice) if currentState == STATE_LONG else (ticker['Last'] + slidePrice), AmountOP) # xiugai 限价单 + ID = pfn( (ticker['Last'] - slidePrice) if currentState == STATE_LONG else (ticker['Last'] + slidePrice), AmountOP) # xiugai 限价单 # ID = pfn(-1, AmountOP) # xiugai 市价单 - ID = pfn(AmountOP) # xiugai 市价单 + # ID = pfn(AmountOP) # xiugai 市价单 Sleep(Interval) Log(exchange.GetOrder(ID)) # xiugai ClosePrice = (exchange.GetOrder(ID))['AvgPrice'] # @@ -124,9 +124,9 @@ def Trade(currentState,nextState): exchange.SetDirection("buy" if nextState == STATE_LONG else "sell") Log(_C(exchange.GetAccount)) while True: - # pfn( (ticker['Last'] + slidePrice) if nextState == STATE_LONG else (ticker['Last'] - slidePrice), AmountOP) # 限价单 + ID = pfn( (ticker['Last'] + slidePrice) if nextState == STATE_LONG else (ticker['Last'] - slidePrice), AmountOP) # 限价单 # ID = pfn(-1, AmountOP) # 市价单 - ID = pfn(AmountOP) # 市价单 + # ID = pfn(AmountOP) # 市价单 Sleep(Interval) Log(exchange.GetOrder(ID)) # xiugai CancelPendingOrders() diff --git "a/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" "b/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" index 5771dacc..2f9d66c3 100644 --- "a/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" +++ "b/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" @@ -412,11 +412,12 @@ def pollTask(self, task): task["e"].SetDirection("closebuy_today" if positions[i]["Type"] == PD_LONG else "closebuy") amount = min(amount, depth["Bids"][0]["Amount"]) orderId = task["e"].Sell(_N(depth["Bids"][0]["Price"] - slidePrice, 2), amount, task["symbol"], "平今" if positions[i]["Type"] == PD_LONG else "平昨", "Bid", depth["Bids"][0]) + remain -= amount elif (task["action"] == "closesell" and (positions[i]["Type"] == PD_SHORT or positions[i]["Type"] == PD_SHORT_YD)): task["e"].SetDirection("closesell_today" if positions[i]["Type"] == PD_SHORT else "closesell") amount = min(amount, depth["Asks"][0]["Amount"]) orderId = task["e"].Buy(_N(depth["Asks"][0]["Price"] + slidePrice, 2), amount, task["symbol"], "平今" if positions[i]["Type"] == PD_SHORT else "平昨", "Ask", depth["Asks"][0]) - remain -= amount + remain -= amount else: if task["action"] == "buy": task["e"].SetDirection("buy") @@ -598,7 +599,7 @@ def IsTrading(symbol): [21, 0, 23, 30] ], [ - ['SR', 'CF', 'RM', 'MA', 'TA', 'ZC', 'FG', 'IO'], + ['SR', 'CF', 'RM', 'MA', 'TA', 'ZC', 'FG', 'OI'], [21, 0, 23, 30] ], ] diff --git "a/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" "b/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" index 87742a36..ffaa3f3b 100644 --- "a/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" +++ "b/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" @@ -9,9 +9,9 @@ */ /*backtest -start: 2017-11-11 00:00:00 -end: 2017-11-12 12:00:00 -period: 1h +start: 2017-12-05 00:00:00 +end: 2017-12-06 12:00:00 +period: 5m exchanges: [{"eid":"OKCoin_EN","currency":"BTC"}] */ diff --git "a/\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.js" "b/\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.js" new file mode 100644 index 00000000..cb06479d --- /dev/null +++ "b/\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.js" @@ -0,0 +1,126 @@ +/* +策略出处: https://www.botvs.com/strategy/82325 +策略名称: 【001】单平台均衡策略 【研究】 +策略作者: 风利 +策略描述: + +这个需要建仓,比如账户有5000块钱,跟1个币,如果币的价值大于账户的余额5000了并且差价超过阀值,比如币现在值6000块钱,就卖掉(6000-5000)/6000/2个币,说明币升值了,把钱兑换回来,如果币贬值了,比如4000块钱了,就买入(5000-4000)/4000/2个币, 币跌的时候买一些回来,如果再涨了,就再卖掉,好像天平一样,两边不同的对冲,所以我命名为均衡策略 + + +参数 默认值 描述 +------------ ----- ---------- +threshold 10 阀值 +Interval 2000 出错重试间隔(毫秒) +LoopInterval 60 轮询间隔(秒) +*/ + + +/* 单平台策略*/ + + +function adjustFloat(v) { // 处理数据的自定义函数 ,可以把参数 v 处理 返回 保留3位小数(floor向下取整) + return Math.floor(v*1000)/1000; // 先乘1000 让小数位向左移动三位,向下取整 整数,舍去所有小数部分,再除以1000 , 小数点向右移动三位,即保留三位小数。 +} + + + +function GetTicker() { //定义获取行情函数,获取卖一价,买一价,最后成交价,成交量,时间等 + var ticker; + while (!(ticker = exchange.GetTicker())) { + Sleep(Interval); + } + return ticker; +} + + +function GetAccount() { //定义获得账户信息,持币数目,资金量 + var account; + while (!(account = exchange.GetAccount())) { + Sleep(Interval); + } + return account; +} + + + +function CancelPendingOrders() { //定义函数取消挂单的订单 + var ret = false; + while (true) { + var orders = null; + while (!(orders = exchange.GetOrders())) { + Sleep(Interval); + } + + if (orders.length == 0) { + return ret; + } + + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id); + ret = true; + if (j < (orders.length-1)) { + Sleep(Interval); + } + } + } + return ret; +} + + + +function updateProft(accountInit, accountNow, ticker) { //更新自己账户的收益情况 + LogProfit(accountNow.Balance + accountNow.FrozenBalance + ((accountNow.Stocks + accountNow.FrozenStocks - accountInit.Stocks - accountInit.FrozenStocks) * ticker.Buy) - accountInit.Balance - accountInit.FrozenBalance); +} + +var STATE_WAIT_IDLE = 0; //定义变量操作状态默认值为 0 +var STATE_WAIT_BUY = 1; //定义变量操作状态等待买入状态为1 +var STATE_WAIT_SELL = 2; //定义变量操作状态等待卖出状态为2 + +var State = STATE_WAIT_IDLE; //定义变量State 默认状态为0 +var InitAccount = null; //定义账户初始状态为NULL + +function onTick() { //定义函数onTick 为判定逻辑操作买入与卖出状态 + var opSuccess = false; //定义变量opSuccess 起始状态为 false + if (State != STATE_WAIT_IDLE) { //判断函数如果 初始状态不为0,为真,也就是现在有买入挂单,与卖出挂单 + opSuccess = !CancelPendingOrders(); //并且变量操作没有执行取消挂单操作 + State = STATE_WAIT_IDLE; //定义变量State 默认为默认状态(等待状态) + } + + var portfolio = GetAccount(); //定义变量 portfolio 是获取账户信息 + var ticker = GetTicker(); //定义变量 Ticker 是获得行情信息 + + if (opSuccess) { //如果opSuccess为真的话,就是跟新自己的收益 + updateProft(InitAccount, portfolio, ticker); + } + + // 下面是策略逻辑的精髓所在 + + var diff = portfolio.Balance - (portfolio.Stocks * ticker.Sell); //定义变量diff 账户的收益=账户金额- 账户数量*卖一价 + + if (diff > threshold) { //如果差额大于 阈值 threshold(默认值为10) + var amount = adjustFloat(diff / 2 / ticker.Buy); + if (amount < 0.001) { + return; + } + exchange.Buy(ticker.Buy*1.1, amount); + State = STATE_WAIT_BUY; + } else if (diff <= -threshold) { + var amount2 = adjustFloat(Math.abs(diff) / 2 / ticker.Sell); + if (amount2 < 0.001) { + return; + } + exchange.Sell(ticker.Sell*0.9, amount2); //这里添加了滑价,所以其中的价格为*0.9 这也这样的方式需要优化 + State = STATE_WAIT_SELL; + } +} + + + +function main() { //这里调用了主函数进行操作 + InitAccount = GetAccount(); + LoopInterval = Math.max(LoopInterval, 1); //这里使用JS内置函数Math.max() 方法可返回两个指定的数中带有较大的值的那个数。 + while (1) { + onTick(); + Sleep(LoopInterval * 1000); + } +} diff --git "a/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" "b/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" index 51fa946f..019edd3d 100644 --- "a/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" +++ "b/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" @@ -28,7 +28,7 @@ def main(): break if lines_up == True: - records = exchange.GetRecords(PERIOD_M30) + records = exchange.GetRecords(PERIOD_M15) current_price = records[-1].get("Close", 0) times = [record.get("Time", 0) for record in records] y = [record.get("High", 0) for record in records] diff --git "a/\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.js" "b/\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.js" new file mode 100644 index 00000000..31e63b58 --- /dev/null +++ "b/\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.js" @@ -0,0 +1,111 @@ +/* +策略出处: https://www.botvs.com/strategy/82929 +策略名称: 内外盘期货品种实时差价图 +策略作者: Zero +策略描述: + + + + +参数 默认值 描述 +-------- ------------- ------- +FSymbol NYMEX CL 1805 外盘品种 +LSymbol sc1809 内盘品种 +USDCNY 6.28 USDNCY +Interval 10 收集周期(秒) +*/ + +function main() { + LogReset(); + LogProfitReset(); + SetErrorFilter('初始化'); + var symbolA = ''; + var symbolB = ''; + var eLocal = null; + var eForeign = null; + _.each(exchanges, function(e) { + var isForeign = e.GetName() == "Futures_Esunny"; + var ct = isForeign ? FSymbol : LSymbol; + if (isForeign) { + eForeign = e; + } else { + eLocal = e; + } + Log(e.GetName(), "正在连接", (isForeign ? "外盘" : "内盘"), "交易服务器...."); + while (!e.IO("status")) Sleep(100); + Log("正在订阅品种", ct); + var symbol = _C(e.SetContractType, ct); + var volumeMultiple = isForeign ? symbol.ProductDot : symbol.VolumeMultiple; + var symbolName = isForeign ? (symbol.CommodityName + symbol.UpperNo) : symbol.InstrumentName; + Log("订阅成功", "每手乘数:", volumeMultiple, "商品名:", symbolName, symbol); + e.IO("mode", 0); + }); + if (eLocal == null || eForeign == null) { + throw "必须添加一个内盘期货跟一个外盘期货"; + } + var cfgA = { + title: { + text: LSymbol + ' & ' + FSymbol + ' 最新价', + }, + subtitle: { + text: '每' + Interval + '秒更新一次', + }, + xAxis: { + type: 'datetime' + }, + series: [{ + name: LSymbol, + data: [], + }, { + name: FSymbol, + data: [], + }] + } + var cfgB = { + title: { + text: '差价图' + }, + xAxis: { + type: 'datetime' + }, + series: [{ + name: LSymbol + ' - ' + FSymbol + ' 差价', + type: 'line', + data: [], + }] + } + + var cfgC = { + __isStock: false, + title: { + text: 'USDCNY yahoo 汇率' + }, + xAxis: { + type: 'datetime' + }, + series: [{ + name: 'USDCNY', + type: 'line', + data: [], + }] + }; + var chart = Chart([cfgA, cfgB, cfgC]); + chart.reset(); + while (true) { + if ($.IsTrading(LSymbol)) { + var tickerA = eLocal.GetTicker(); + var tickerB = eForeign.GetTicker(); + if (tickerA && tickerB) { + var ts = Unix() * 1000; + chart.add(0, [ts, _N(tickerA.Last, 2)]); + chart.add(1, [ts, _N(tickerB.Last * USDCNY, 2)]); + chart.add(2, [ts, _N(tickerA.Last - tickerB.Last * USDCNY, 2)]); + chart.add(3, [ts, USDCNY]); + } + } else { + LogStatus("不在交易时间内...."); + } + LogStatus(_D(), "Running..."); + Sleep(Interval * 1000); + } +} diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.js" "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.js" index 59655579..b12c9e77 100644 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.js" +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.js" @@ -10,57 +10,23 @@ 每一笔委托的数量为其单次委托平均值的90%~110%,委托价格为最新买1价*(1-委托深度),在上一笔委托全部成交后再进行新的一笔委托,在最新成交价格距离该笔委托超过委托深度*2时自动撤单并重新进行委托。在策略总成交量等于其总委托数量时停止委托。当市场的最新成交价格高于其最高买入价格时停止委托,在最新成交价格重新低于最高买入价后恢复委托。 -参数 默认值 描述 ------------- ----- ------------- -TotalBuyCNY 10000 购买总金额(元) -AvgBuyOnce 100 单次购买数量均值(元) -FloatPoint 10 单次均值浮动点数(百分比) -EntrustDepth 0.1 委托深度(百分比) -MaxBuyPrice 4000 最高买入价格(元) -Interval 1000 失败重试(毫秒) -LoopInterval true 价格轮询间隔(秒) +参数 默认值 描述 +------------ ------ ------------- +TotalBuyNet 10000 购买总金额(元) +AvgBuyOnce 100 单次购买数量均值(元) +FloatPoint 10 单次均值浮动点数(百分比) +EntrustDepth 0.1 委托深度(百分比) +MaxBuyPrice 20000 最高买入价格(元) +Interval 1000 失败重试(毫秒) +MinStock 0.0001 最小交易量 +LoopInterval true 价格轮询间隔(秒) */ -function adjustFloat(v, precision) { - if (typeof(precision) != 'number') { - precision = 4; - } - var s = v.toString().split("."); - if (s.length < 2 || s[1].length <= precision) { - return v; - } - var b = Math.pow(10, precision); - return Math.floor(parseFloat(v.toFixed(Math.min(20, precision+10)))*b)/b; -} - -function GetTicker() { - var ticker; - while (!(ticker = exchange.GetTicker())) { - Sleep(Interval); - } - return ticker; -} - -function GetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(Interval); - } - return account; -} - -function GetOrders() { - var orders = null; - while (!(orders = exchange.GetOrders())) { - Sleep(Interval); - } - return orders; -} function CancelPendingOrders() { while (true) { - var orders = GetOrders(); + var orders = _C(exchange.GetOrders); if (orders.length == 0) { return; } @@ -79,11 +45,11 @@ var InitAccount = null; function dispatch() { var account = null; - var ticker = GetTicker(); + var ticker = _C(exchange.GetTicker); // 在最新成交价格距离该笔委托超过委托深度*2时自动撤单并重新进行委托 if (LastBuyPrice > 0) { // 订单没有完成 - if (GetOrders().length > 0) { + if (_C(exchange.GetOrders).length > 0) { if (ticker.Last > LastBuyPrice && ((ticker.Last - LastBuyPrice) / LastBuyPrice) > (2*(EntrustDepth/100))) { Log('偏离过多, 最新成交价:', ticker.Last, '委托价', LastBuyPrice); CancelPendingOrders(); @@ -91,49 +57,51 @@ function dispatch() { return true; } } else { - account = GetAccount(); - Log("买单完成, 累计花费:", adjustFloat(InitAccount.Balance - account.Balance), "平均买入价:", adjustFloat((InitAccount.Balance - account.Balance) / (account.Stocks - InitAccount.Stocks))); + account = _C(exchange.GetAccount); + Log("买单完成, 累计花费:", _N(InitAccount.Balance - account.Balance), "平均买入价:", _N((InitAccount.Balance - account.Balance) / (account.Stocks - InitAccount.Stocks))); } LastBuyPrice = 0; } + // 委托价格为最新买1价*(1-委托深度) - var BuyPrice = adjustFloat(ticker.Buy * (1 - EntrustDepth/100)); + var BuyPrice = _N(ticker.Buy * (1 - EntrustDepth/100)); if (BuyPrice > MaxBuyPrice) { return true; } if (!account) { - account = GetAccount(); + account = _C(exchange.GetAccount); } - if ((InitAccount.Balance - account.Balance) >= TotalBuyCNY) { + if ((InitAccount.Balance - account.Balance) >= TotalBuyNet) { return false; } var RandomAvgBuyOnce = (AvgBuyOnce * ((100 - FloatPoint) / 100)) + (((FloatPoint * 2) / 100) * AvgBuyOnce * Math.random()); - var UsedMoney = Math.min(account.Balance, RandomAvgBuyOnce, TotalBuyCNY - (InitAccount.Balance - account.Balance)); + var UsedMoney = Math.min(account.Balance, RandomAvgBuyOnce, TotalBuyNet - (InitAccount.Balance - account.Balance)); - var BuyAmount = adjustFloat(UsedMoney / BuyPrice); - if (BuyAmount < exchange.GetMinStock()) { + var BuyAmount = _N(UsedMoney / BuyPrice); + if (BuyAmount < MinStock) { return false; } LastBuyPrice = BuyPrice; - exchange.Buy(BuyPrice, BuyAmount, '花费: ¥', adjustFloat(UsedMoney), '上次成交价', ticker.Last); + exchange.Buy(BuyPrice, BuyAmount, '花费: ¥', _N(UsedMoney), '上次成交价', ticker.Last); return true; } function main() { CancelPendingOrders(); - InitAccount = GetAccount(); + InitAccount = _C(exchange.GetAccount); Log(InitAccount); - if (InitAccount.Balance < TotalBuyCNY) { + if (InitAccount.Balance < TotalBuyNet) { throw "账户余额不足"; } LoopInterval = Math.max(LoopInterval, 1); while (dispatch()) { Sleep(LoopInterval * 1000); } - Log("委托全部完成", GetAccount()); + Log("委托全部完成", _C(exchange.GetAccount)); } + diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.js" "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.js" index a8ae27af..a16dc837 100644 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.js" +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.js" @@ -10,56 +10,23 @@ 每一笔委托的数量为其单次委托平均值的90%~110%,委托价格为最新卖1价*(1+委托深度),在上一笔委托全部成交后再进行新的一笔委托,在最新成交价格距离该笔委托超过委托深度*2时自动撤单并重新进行委托。在策略总成交量等于其总委托数量时停止委托。当市场的最新成交价格低于其最低卖出价格时停止委托,在最新成交价格重新高于最低卖出价后恢复委托。 -参数 默认值 描述 ---------------- ------ ------------- -TotalSellStocks 10 卖出总数量(币) -AvgSellOnce 0.3 单次卖出数量均值(币) -FloatPoint 10 单次均值浮动点数(百分比) -EntrustDepth 0.1 委托深度(百分比) -MinSellPrice 3800 最低卖出价格(元) -Interval 1000 失败重试(毫秒) -LoopInterval 300 价格轮询间隔(毫秒) +参数 默认值 描述 +--------------- --------- ------------- +TotalSellStocks 10 卖出总数量(币) +AvgSellOnce 0.3 单次卖出数量均值(币) +FloatPoint 10 单次均值浮动点数(百分比) +EntrustDepth 0.1 委托深度(百分比) +MinSellPrice 3800 最低卖出价格(元) +Interval 1000 失败重试(毫秒) +MinStock 0.0001 最小交易量 +LoopInterval 300 价格轮询间隔(毫秒) */ -function adjustFloat(v, precision) { - if (typeof(precision) != 'number') { - precision = 4; - } - var s = v.toString().split("."); - if (s.length < 2 || s[1].length <= precision) { - return v; - } - var b = Math.pow(10, precision); - return Math.floor(parseFloat(v.toFixed(Math.min(20, precision+10)))*b)/b; -} - -function GetTicker() { - var ticker; - while (!(ticker = exchange.GetTicker())) { - Sleep(Interval); - } - return ticker; -} -function GetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(Interval); - } - return account; -} - -function GetOrders() { - var orders = null; - while (!(orders = exchange.GetOrders())) { - Sleep(Interval); - } - return orders; -} function CancelPendingOrders() { while (true) { - var orders = GetOrders(); + var orders = _C(exchange.GetOrders); if (orders.length == 0) { return; } @@ -78,11 +45,11 @@ var InitAccount = null; function dispatch() { var account = null; - var ticker = GetTicker(); + var ticker = _C(exchange.GetTicker); // 在最新成交价格距离该笔委托超过委托深度*2时自动撤单并重新进行委托 if (LastSellPrice > 0) { // 订单没有完成 - if (GetOrders().length > 0) { + if (_C(exchange.GetOrders).length > 0) { if (ticker.Last < LastSellPrice && ((LastSellPrice - ticker.Last) / ticker.Last) > (2*(EntrustDepth/100))) { Log('偏离过多, 最新成交价:', ticker.Last, '委托价', LastSellPrice); CancelPendingOrders(); @@ -90,19 +57,19 @@ function dispatch() { return true; } } else { - account = GetAccount(); - Log("卖单完成, 累计卖出:", adjustFloat(InitAccount.Stocks - account.Stocks), "平均卖出价:", adjustFloat((account.Balance - InitAccount.Balance) / (InitAccount.Stocks - account.Stocks))); } + account = _C(exchange.GetAccount); + Log("卖单完成, 累计卖出:", _N(InitAccount.Stocks - account.Stocks), "平均卖出价:", _N((account.Balance - InitAccount.Balance) / (InitAccount.Stocks - account.Stocks))); } LastSellPrice = 0; } // 委托价格为最新卖1价*(1+委托深度) - var SellPrice = adjustFloat(ticker.Sell * (1 + EntrustDepth/100)); + var SellPrice = _N(ticker.Sell * (1 + EntrustDepth/100)); if (SellPrice < MinSellPrice) { return true; } if (!account) { - account = GetAccount(); + account = _C(exchange.GetAccount); } @@ -112,7 +79,7 @@ function dispatch() { var RandomAvgSellOnce = (AvgSellOnce * ((100 - FloatPoint) / 100)) + (((FloatPoint * 2) / 100) * AvgSellOnce * Math.random()); var SellAmount = Math.min(TotalSellStocks - (InitAccount.Stocks - account.Stocks), RandomAvgSellOnce); - if (SellAmount < exchange.GetMinStock()) { + if (SellAmount < MinStock) { return false; } LastSellPrice = SellPrice; @@ -122,7 +89,7 @@ function dispatch() { function main() { CancelPendingOrders(); - InitAccount = GetAccount(); + InitAccount = _C(exchange.GetAccount); Log(InitAccount); if (InitAccount.Stocks < TotalSellStocks) { throw "账户币数不足"; @@ -131,6 +98,7 @@ function main() { while (dispatch()) { Sleep(LoopInterval); } - Log("委托全部完成", GetAccount()); + Log("委托全部完成", _C(exchange.GetAccount)); } + diff --git "a/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.js" "b/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.js" index ee456cf1..d1df18d0 100644 --- "a/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.js" +++ "b/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.js" @@ -86,17 +86,17 @@ function onTick() { if (diff > threshold) { var amount = adjustFloat(diff / 2 / ticker.Buy); - if (amount < exchange.GetMinStock()) { + if (amount < 0.001) { return; } - exchange.Buy(ticker.Buy, amount); + exchange.Buy(ticker.Buy*1.1, amount); State = STATE_WAIT_BUY; } else if (diff <= -threshold) { var amount = adjustFloat(Math.abs(diff) / 2 / ticker.Sell); - if (amount < exchange.GetMinStock()) { + if (amount < 0.001) { return; } - exchange.Sell(ticker.Sell, amount); + exchange.Sell(ticker.Sell*0.9, amount); State = STATE_WAIT_SELL; } } diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" index 024658b6..fb8b0e19 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" @@ -72,7 +72,7 @@ SyncInterval 5 账户与持仓同步周期(秒) */ /*backtest -start: 2018-01-15 00:00:00 +start: 2018-01-15 09:00:00 end: 2018-01-30 00:00:00 period: 1d exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] @@ -522,7 +522,7 @@ $.IsTrading = function(symbol) { var nperiod = [ [ - ['AU', 'AG'], + ['AU', 'AG', 'sc'], [21, 0, 02, 30] ], [ @@ -538,7 +538,7 @@ $.IsTrading = function(symbol) { [21, 0, 23, 30] ], [ - ['SR', 'CF', 'RM', 'MA', 'TA', 'ZC', 'FG', 'IO'], + ['SR', 'CF', 'RM', 'MA', 'TA', 'ZC', 'FG', 'OI'], [21, 0, 23, 30] ], ]; @@ -743,13 +743,13 @@ $.NewTaskQueue = function(onTaskFinish) { task.e.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy"); amount = Math.min(amount, depth.Bids[0].Amount) orderId = task.e.Sell(_N(depth.Bids[0].Price - slidePrice, 2), amount, task.symbol, positions[i].Type == PD_LONG ? "平今" : "平昨", 'Bid', depth.Bids[0]); + remain -= amount; } else if (task.action == "closesell" && (positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD)) { task.e.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell"); amount = Math.min(amount, depth.Asks[0].Amount) orderId = task.e.Buy(_N(depth.Asks[0].Price + slidePrice, 2), amount, task.symbol, positions[i].Type == PD_SHORT ? "平今" : "平昨", 'Ask', depth.Asks[0]); + remain -= amount; } - // assume order is success insert - remain -= amount; } } else { if (task.action == "buy") { diff --git "a/\345\233\275\345\244\226\347\237\245\345\220\215\347\255\226\347\225\245 Dual Thrust.js" "b/\345\233\275\345\244\226\347\237\245\345\220\215\347\255\226\347\225\245 Dual Thrust.js" deleted file mode 100644 index b41d7749..00000000 --- "a/\345\233\275\345\244\226\347\237\245\345\220\215\347\255\226\347\225\245 Dual Thrust.js" +++ /dev/null @@ -1,178 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/153 -策略名称: 国外知名策略 Dual Thrust -策略作者: Zero -策略描述: - -国外知名策略 Dual Thrust, 这个策略横盘振荡时很受伤,有波动的时候,很给力。建议周期选择最少5分钟 -参考: -http://pan.baidu.com/share/link?shareid=51043384&uk=690262241 -http://bbs.tb18.net/thread-16325-1-1.html -http://www.doc88.com/p-0893982494346.html -http://www.legu8.com/?p=253 - - -参数 默认值 描述 --------------- ----- ---------- -NPeriod true 计算周期 -Ks 0.5 上轨系数 -Kx 0.5 下轨系数 -Lot true 手数 -SlidePrice 0.3 下单滑动价 -Interval 2000 出错重试间隔(毫秒) -UseMarketOrder false 使用市价单 -*/ - -function adjustFloat(v) { - return Math.floor(v*1000)/1000; -} - -function GetTicker() { - var ticker; - while (!(ticker = exchange.GetTicker())) { - Sleep(Interval); - } - return ticker; -} - -function GetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(Interval); - } - return account; -} - -function CancelPendingOrders() { - while (true) { - var orders = null; - while (!(orders = exchange.GetOrders())) { - Sleep(Interval); - } - - if (orders.length == 0) { - return; - } - - for (var j = 0; j < orders.length; j++) { - exchange.CancelOrder(orders[j].Id); - if (j < (orders.length-1)) { - Sleep(Interval); - } - } - } -} - -function Highest(records, attr, n) { - var v = 0; - for (var pos = records.length - n; pos < records.length; pos++) { - v = Math.max(v, records[pos][attr]); - } - return v; -} - -function Lowest(records, attr, n) { - var v = -1; - for (var pos = records.length - n; pos < records.length; pos++) { - if (v == -1) { - v = records[pos][attr]; - } else { - v = Math.min(v, records[pos][attr]); - } - } - return v; -} - -function updateProfit(accountInit, accountNow, ticker) { - var netNow = accountNow.Balance + accountNow.FrozenBalance + ((accountNow.Stocks + accountNow.FrozenStocks) * ticker.Buy); - var netInit = accountInit.Balance + accountInit.FrozenBalance + ((accountInit.Stocks + accountInit.FrozenStocks) * ticker.Buy); - LogProfit(adjustFloat(netNow - netInit)); -} - -var LastEpoch = 0; -var InitAccount = null; -var LastProfit = 0; - -function onTick() { - var records = exchange.GetRecords(); - if (!records || records.length <= NPeriod) { - return; - } - var Bar = records[records.length-1]; - - if (LastEpoch == Bar.Time) { - return; - } - - var Range = 0; - var HH = Highest(records, 'High', NPeriod); - var HC = Highest(records, 'Close', NPeriod); - var LL = Lowest(records, 'Low', NPeriod); - var LC = Lowest(records, 'Close', NPeriod); - - if ((HH - LC) >= (HC - LL)) { - Range = HH - LC; - } else { - Range = HC - LL; - } - - var BuyPosition = Bar.Open + (Ks * Range); - var SellPosition = Bar.Open - (Kx * Range); - - var shouldBuy = false; - var shouldSell = false; - - if (Bar.High >= BuyPosition) { - shouldBuy = true; - } - - if (Bar.Low <= SellPosition) { - shouldSell = true; - } - - if (!shouldBuy && !shouldSell) { - return; - } - - CancelPendingOrders(); - - var account = GetAccount(); - var ticker = GetTicker(); - - if (shouldSell) { - var maxSell = adjustFloat(account.Stocks - InitAccount.Stocks); - if (maxSell > exchange.GetMinStock()) { - var sellPrice = ticker.Sell - SlidePrice; - if (UseMarketOrder) { - sellPrice = ticker.Buy - SlidePrice; - } - exchange.Sell(sellPrice, maxSell); - } else { - // Nothing to sell - LastEpoch = Bar.Time; - updateProfit(InitAccount, account, ticker); - } - } else if (shouldBuy) { - var buyPrice = ticker.Buy + SlidePrice; - if (UseMarketOrder) { - buyPrice = ticker.Sell + SlidePrice; - } - var amount = adjustFloat(account.Balance / buyPrice); - if (amount > exchange.GetMinStock()) { - exchange.Buy(buyPrice, Math.min(amount, Lot)) - LastEpoch = Bar.Time; - } - } -} - -function main() { - InitAccount = GetAccount(); - Log(exchange.GetName(), exchange.GetCurrency(), InitAccount); - if (Lot < exchange.GetMinStock()) { - throw "手数小于最小交易值"; - } - while (true) { - onTick(); - Sleep(10000); - } -} diff --git "a/\345\235\207\347\272\277\344\271\260\345\215\226\347\255\226\347\225\245.js" "b/\345\235\207\347\272\277\344\271\260\345\215\226\347\255\226\347\225\245.js" deleted file mode 100644 index e94789c6..00000000 --- "a/\345\235\207\347\272\277\344\271\260\345\215\226\347\255\226\347\225\245.js" +++ /dev/null @@ -1,155 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/143 -策略名称: 均线买卖策略 -策略作者: Zero -策略描述: - -均线买卖策略, 当EMA快线上穿慢线的时候,做多,当EMA中线上穿快线或者达到的止盈/止损的时候,平仓。 - - -参数 默认值 描述 ----------- ------ -------- -EMA_Fast 7 EMA快线周期 -EMA_Mid 12 EMA中线周期 -EMA_Slow 30 EMA慢线周期 -StopProfit 0.2 止盈点 -StopLoss 0.3 止损点 -SlidePrice 0.3 下单滑动价(元) -Interval 2000 出错重试(毫秒) -*/ - - -function adjustFloat(v) { - return Math.floor(v*1000)/1000; -} - -function CancelPendingOrders() { - while (true) { - var orders = null; - while (!(orders = exchange.GetOrders())) { - Sleep(Interval); - } - - if (orders.length == 0) { - return; - } - - for (var j = 0; j < orders.length; j++) { - exchange.CancelOrder(orders[j].Id); - if (j < (orders.length-1)) { - Sleep(Interval); - } - } - } -} - -function GetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(Interval); - } - return account; -} - -function GetTicker() { - var ticker; - while (!(ticker = exchange.GetTicker())) { - Sleep(Interval); - } - return ticker; -} - -var STATE_WAIT_BUY = 0; -var STATE_WAIT_SELL = 1; -var STATE_BUY = 2; -var STATE_SELL = 3; -var STATE_WAIT_SELL_ALL = 4; - -var State = STATE_WAIT_BUY; -var lastRecord = null; -var InitAccount = null; -var LastBuyPrice = 0.0; -var LastHighPrice = 0.0; - -function onTick(exchange) { - var records = exchange.GetRecords(); - if (!records || records.length < (EMA_Slow + 3)) { - return; - } - var newLast = records[records.length-1]; - if ((!lastRecord) || (lastRecord.Time == newLast.Time && lastRecord.Close == newLast.Close)) { - lastRecord = newLast; - return; - } - lastRecord = newLast; - - - var ticker = GetTicker(); - - var emaFast = TA.EMA(records, EMA_Fast); - var emaSlow = TA.EMA(records, EMA_Slow); - var emaMid = TA.EMA(records, EMA_Mid); - - if (State == STATE_WAIT_BUY && - (emaFast[emaFast.length-1] >= emaSlow[emaSlow.length-1]) - && (emaFast[emaFast.length-2] < emaSlow[emaSlow.length-2]) - && (emaFast[emaFast.length-1] > emaMid[emaSlow.length-1])) { - State = STATE_BUY; - } else if (State == STATE_WAIT_SELL) { - var ratioStopLoss = Math.abs((LastHighPrice - ticker.Last) / LastHighPrice) * 100; - var ratioStopProfit = Math.abs((ticker.Last - LastBuyPrice) / LastBuyPrice) * 100; - - if (emaFast[emaFast.length-1] < emaMid[emaFast.length-1]) { - State = STATE_SELL; - Log("EMA 快线下穿中线", "Fast:", adjustFloat(emaFast[emaFast.length-1]), "Mid", adjustFloat(emaMid[emaFast.length-1])); - } else if (ticker.Last < LastHighPrice && ratioStopLoss >= StopLoss) { - State = STATE_SELL; - Log("开始止损, 当前下跌点数:", adjustFloat(ratioStopLoss), "当前价格", ticker.Last, "对比价格", adjustFloat(LastHighPrice)); - } else if (ticker.Last > LastBuyPrice && ratioStopProfit >= StopProfit) { - State = STATE_SELL; - Log("开始止赢, 当前上涨点数:", adjustFloat(ratioStopProfit), "当前价格", ticker.Last, "对比价格", adjustFloat(LastBuyPrice)); - } - LastHighPrice = Math.max(LastHighPrice, ticker.Last); - } - - if (State != STATE_BUY && State != STATE_SELL && State != STATE_WAIT_SELL_ALL) { - return; - } - - // Buy or Sell, Cancel pending orders first - CancelPendingOrders(); - - var account = GetAccount(); - - if (State == STATE_BUY) { - var price = ticker.Last + SlidePrice; - var amount = adjustFloat(account.Balance / price); - if (amount >= exchange.GetMinStock()) { - if (exchange.Buy(price, amount)) { - State = STATE_WAIT_SELL; - LastBuyPrice = LastHighPrice = price; - } - } - } else { - var sellAmount = account.Stocks - InitAccount.Stocks; - if (sellAmount > exchange.GetMinStock()) { - // STATE_WAIT_SELL or STATE_WAIT_SELL_ALL - State = STATE_WAIT_SELL_ALL; - exchange.Sell(ticker.Last - SlidePrice, sellAmount); - } else { - // No stocks, wait buy and log profit - LogProfit(account.Balance - InitAccount.Balance); - Log(account); - State = STATE_WAIT_BUY; - } - } -} - -function main() { - InitAccount = GetAccount(); - Log(exchange.GetName(), exchange.GetCurrency(), InitAccount); - while (true) { - onTick(exchange); - Sleep(10000); - } -} diff --git "a/\345\244\232\345\271\263\345\217\260\345\257\271\345\206\262\347\250\263\345\256\232\345\245\227\345\210\251 V2.1.js" "b/\345\244\232\345\271\263\345\217\260\345\257\271\345\206\262\347\250\263\345\256\232\345\245\227\345\210\251 V2.1.js" deleted file mode 100644 index 8c86b168..00000000 --- "a/\345\244\232\345\271\263\345\217\260\345\257\271\345\206\262\347\250\263\345\256\232\345\245\227\345\210\251 V2.1.js" +++ /dev/null @@ -1,305 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/57 -策略名称: 多平台对冲稳定套利 V2.1 -策略作者: Zero -策略描述: - -程序自动换算汇率,手续费,下单参考买一卖一的价,注意这个不是搬砖,是对冲! 不需要人工转钱或者币,一个存钱,一个存币,一个买,一个卖,高级对冲模式. -这种对冲模式不管币的价格是涨还是跌,只赚差价。 -建仓需要一个放钱,一个放币,比如BTC现在价格4000吧,一个交易所放2000元,一个放0.5个币就行了,或者都加倍 -MaxDiff指最低平台差价, SlidePrice指下单时的滑动价, 买单就加上这个价, 卖单就减去这个价, TickIntervalS 指检测周期 -跌停值指的时虚拟币跌到这个价格了就不操作,涨停值指虚拟币高于这个价格也不操作,防止平台恶意给机器人下套. -要求系统版本1.7以上 - - -参数 默认值 描述 --------------- ------- ---------- -Interval 500 出错重试间隔(毫秒) -TickInterval 300 检测频率(毫秒) -MaxDiff 3 最低差价(元) -SlidePrice 0.1 止损滑动价(元) -SlideRatio 2 对冲滑动价系数 -StopPriceL 1000 跌停值(元) -StopPriceH 9000 涨停值(元) -optFeeTimeout 30 手续费更新周期(分) -AmountOnce 0.2 单笔交易数量 -UseMarketOrder false 使用市价单止损 -StopWhenLoss false 亏损时停止 -MaxLoss 50 最大亏损限度(元) -SMSAPI http:// 短信通知接口 -*/ - -var initState; -var isBalance = true; -var feeCache = new Array(); -var feeTimeout = optFeeTimeout * 60000; -var lastProfit = 0; -var lastAvgPrice = 0; -var lastSpread = 0; -var lastOpAmount = 0; -function adjustFloat(v) { - return Math.floor(v*1000)/1000; -} - -function isPriceNormal(v) { - return (v >= StopPriceL) && (v <= StopPriceH); -} - -function stripTicker(t) { - return 'Buy: ' + adjustFloat(t.Buy) + ' Sell: ' + adjustFloat(t.Sell); -} - -function updateStatePrice(state) { - var now = (new Date()).getTime(); - for (var i = 0; i < state.details.length; i++) { - var ticker = null; - var key = state.details[i].exchange.GetName() + state.details[i].exchange.GetCurrency(); - var fee = null; - while (!(ticker = state.details[i].exchange.GetTicker())) { - Sleep(Interval); - } - - if (key in feeCache) { - var v = feeCache[key]; - if ((now - v.time) > feeTimeout) { - delete feeCache[key]; - } else { - fee = v.fee; - } - } - if (!fee) { - while (!(fee = state.details[i].exchange.GetFee())) { - Sleep(Interval); - } - feeCache[key] = {fee: fee, time: now}; - } - // Buy-=fee Sell+=fee - state.details[i].ticker = {Buy: ticker.Buy * (1-(fee.Sell/100)), Sell: ticker.Sell * (1+(fee.Buy/100))}; - state.details[i].realTicker = ticker; - state.details[i].fee = fee; - } -} - -function getProfit(stateInit, stateNow, coinPrice) { - var netNow = stateNow.allBalance + (stateNow.allStocks * coinPrice); - var netInit = stateInit.allBalance + (stateInit.allStocks * coinPrice); - return adjustFloat(netNow - netInit); -} - -function getExchangesState() { - var allStocks = 0; - var allBalance = 0; - var minStock = 0; - var details = []; - for (var i = 0; i < exchanges.length; i++) { - var account = null; - while (!(account = exchanges[i].GetAccount())) { - Sleep(Interval); - } - allStocks += account.Stocks + account.FrozenStocks; - allBalance += account.Balance + account.FrozenBalance; - minStock = Math.max(minStock, exchanges[i].GetMinStock()); - details.push({exchange: exchanges[i], account: account}); - } - return {allStocks: adjustFloat(allStocks), allBalance: adjustFloat(allBalance), minStock: minStock, details: details}; -} - -function cancelAllOrders() { - for (var i = 0; i < exchanges.length; i++) { - while (true) { - var orders = null; - while (!(orders = exchanges[i].GetOrders())) { - Sleep(Interval); - } - - if (orders.length == 0) { - break; - } - - for (var j = 0; j < orders.length; j++) { - exchanges[i].CancelOrder(orders[j].Id, orders[j]); - } - } - } -} - -function balanceAccounts() { - // already balance - if (isBalance) { - return; - } - - cancelAllOrders(); - - var state = getExchangesState(); - var diff = state.allStocks - initState.allStocks; - var adjustDiff = adjustFloat(Math.abs(diff)); - if (adjustDiff < state.minStock) { - isBalance = true; - } else { - Log('初始币总数量:', initState.allStocks, '现在币总数量: ', state.allStocks, '差额:', adjustDiff); - // other ways, diff is 0.012, bug A only has 0.006 B only has 0.006, all less then minstock - // we try to statistical orders count to recognition this situation - updateStatePrice(state); - var details = state.details; - var ordersCount = 0; - if (diff > 0) { - var attr = 'Sell'; - if (UseMarketOrder) { - attr = 'Buy'; - } - // Sell adjustDiff, sort by price high to low - details.sort(function(a, b) {return b.ticker[attr] - a.ticker[attr];}); - for (var i = 0; i < details.length && adjustDiff >= state.minStock; i++) { - if (isPriceNormal(details[i].ticker[attr]) && (details[i].account.Stocks >= state.minStock)) { - var orderAmount = adjustFloat(Math.min(AmountOnce, adjustDiff, details[i].account.Stocks)); - var orderPrice = details[i].realTicker[attr] - SlidePrice; - if ((orderPrice * orderAmount) < details[i].exchange.GetMinPrice()) { - continue; - } - ordersCount++; - if (details[i].exchange.Sell(orderPrice, orderAmount, stripTicker(details[i].ticker))) { - adjustDiff = adjustFloat(adjustDiff - orderAmount); - } - // only operate one platform - break; - } - } - } else { - var attr = 'Buy'; - if (UseMarketOrder) { - attr = 'Sell'; - } - // Buy adjustDiff, sort by sell-price low to high - details.sort(function(a, b) {return a.ticker[attr] - b.ticker[attr];}); - for (var i = 0; i < details.length && adjustDiff >= state.minStock; i++) { - if (isPriceNormal(details[i].ticker[attr])) { - var canRealBuy = adjustFloat(details[i].account.Balance / (details[i].ticker[attr] + SlidePrice)); - var needRealBuy = Math.min(AmountOnce, adjustDiff, canRealBuy); - var orderAmount = adjustFloat(needRealBuy * (1+(details[i].fee.Buy/100))); - var orderPrice = details[i].realTicker[attr] + SlidePrice; - if ((orderAmount < details[i].exchange.GetMinStock()) || - ((orderPrice * orderAmount) < details[i].exchange.GetMinPrice())) { - continue; - } - ordersCount++; - if (details[i].exchange.Buy(orderPrice, orderAmount, stripTicker(details[i].ticker))) { - adjustDiff = adjustFloat(adjustDiff - needRealBuy); - } - // only operate one platform - break; - } - } - } - isBalance = (ordersCount == 0); - } - - if (isBalance) { - var currentProfit = getProfit(initState, state, lastAvgPrice); - LogProfit(currentProfit, "Spread: ", adjustFloat((currentProfit - lastProfit) / lastOpAmount), "Balance: ", adjustFloat(state.allBalance), "Stocks: ", adjustFloat(state.allStocks)); - - if (StopWhenLoss && currentProfit < 0 && Math.abs(currentProfit) > MaxLoss) { - Log('交易亏损超过最大限度, 程序取消所有订单后退出.'); - cancelAllOrders(); - if (SMSAPI.length > 10 && SMSAPI.indexOf('http') == 0) { - HttpQuery(SMSAPI); - Log('已经短信通知'); - } - throw '已停止'; - } - lastProfit = currentProfit; - } -} - -function onTick() { - if (!isBalance) { - balanceAccounts(); - return; - } - - var state = getExchangesState(); - // We also need details of price - updateStatePrice(state); - - var details = state.details; - var maxPair = null; - var minPair = null; - for (var i = 0; i < details.length; i++) { - var sellOrderPrice = details[i].account.Stocks * (details[i].realTicker.Buy - SlidePrice); - if (((!maxPair) || (details[i].ticker.Buy > maxPair.ticker.Buy)) && (details[i].account.Stocks >= state.minStock) && - (sellOrderPrice > details[i].exchange.GetMinPrice())) { - details[i].canSell = details[i].account.Stocks; - maxPair = details[i]; - } - - var canBuy = adjustFloat(details[i].account.Balance / (details[i].realTicker.Sell + SlidePrice)); - var buyOrderPrice = canBuy * (details[i].realTicker.Sell + SlidePrice); - if (((!minPair) || (details[i].ticker.Sell < minPair.ticker.Sell)) && (canBuy >= state.minStock) && - (buyOrderPrice > details[i].exchange.GetMinPrice())) { - details[i].canBuy = canBuy; - // how much coins we real got with fee - details[i].realBuy = adjustFloat(details[i].account.Balance / (details[i].ticker.Sell + SlidePrice)); - minPair = details[i]; - } - } - - if ((!maxPair) || (!minPair) || ((maxPair.ticker.Buy - minPair.ticker.Sell) < MaxDiff) || - !isPriceNormal(maxPair.ticker.Buy) || !isPriceNormal(minPair.ticker.Sell)) { - return; - } - - // filter invalid price - if (minPair.realTicker.Sell <= minPair.realTicker.Buy || maxPair.realTicker.Sell <= maxPair.realTicker.Buy) { - return; - } - - // what a fuck... - if (maxPair.exchange.GetName() == minPair.exchange.GetName()) { - return; - } - - lastAvgPrice = adjustFloat((minPair.realTicker.Buy + maxPair.realTicker.Buy) / 2); - lastSpread = adjustFloat((maxPair.realTicker.Sell - minPair.realTicker.Buy) / 2); - - // compute amount - var amount = Math.min(AmountOnce, maxPair.canSell, minPair.realBuy); - lastOpAmount = amount; - var hedgePrice = adjustFloat((maxPair.realTicker.Buy - minPair.realTicker.Sell) / Math.max(SlideRatio, 2)) - if (minPair.exchange.Buy(minPair.realTicker.Sell + hedgePrice, amount * (1+(minPair.fee.Buy/100)), stripTicker(minPair.realTicker))) { - maxPair.exchange.Sell(maxPair.realTicker.Buy - hedgePrice, amount, stripTicker(maxPair.realTicker)); - } - - isBalance = false; -} - -function main() { - if (exchanges.length < 2) { - throw "交易所数量最少得两个才能完成对冲"; - } - - TickInterval = Math.max(TickInterval, 50); - Interval = Math.max(Interval, 50); - - cancelAllOrders(); - - initState = getExchangesState(); - if (initState.allStocks == 0) { - throw "所有交易所货币数量总和为空, 必须先在任一交易所建仓才可以完成对冲"; - } - if (initState.allBalance == 0) { - throw "所有交易所CNY数量总和为空, 无法继续对冲"; - } - - for (var i = 0; i < initState.details.length; i++) { - var e = initState.details[i]; - Log(e.exchange.GetName(), e.exchange.GetCurrency(), e.account); - } - - Log("ALL: Balance: ", initState.allBalance, "Stocks: ", initState.allStocks, "Ver:", Version()); - - - while (true) { - onTick(); - Sleep(parseInt(TickInterval)); - } -} diff --git "a/\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).js" "b/\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).js" index 10f92ea0..c5459b5c 100644 --- "a/\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).js" +++ "b/\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).js" @@ -14,23 +14,6 @@ SlidePrice 0.3 滑动值 KeepStock false 保留币数 */ - -function GetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(2000); - } - return account; -} - -function GetTicker() { - var ticker; - while (!(ticker = exchange.GetTicker())) { - Sleep(2000); - } - return ticker; -} - function cancelAllOrders() { var orders = null; while (!(orders = exchange.GetOrders())) { @@ -49,7 +32,7 @@ function cancelAllOrders() { function sellAll() { cancelAllOrders(); - var initAccount = GetAccount(); + var initAccount = _C(exchange.GetAccount); Log(exchange.GetName(), exchange.GetCurrency(), initAccount); if (initAccount.Stocks == 0) { Log("空仓"); @@ -57,12 +40,12 @@ function sellAll() { } var remaind = initAccount.Stocks - KeepStock; var account = initAccount; - while (remaind >= exchange.GetMinStock()) { - var ticker = GetTicker(); + while (remaind >= 0.001) { + var ticker = _C(exchange.GetTicker); exchange.Sell(ticker.Buy - SlidePrice, remaind); Sleep(RetryInterval * 1000); cancelAllOrders(); - account = GetAccount(); + account = _C(exchange.GetAccount); remaind = account.Stocks - KeepStock; } Log("平均卖出价", (account.Balance - initAccount.Balance) / (initAccount.Stocks - account.Stocks)); @@ -76,3 +59,4 @@ function main() { } } + diff --git "a/\345\245\227\345\210\251\350\275\257\344\273\266(\345\267\256\344\273\267\345\245\227\345\210\251).js" "b/\345\245\227\345\210\251\350\275\257\344\273\266(\345\267\256\344\273\267\345\245\227\345\210\251).js" deleted file mode 100644 index 781fdea4..00000000 --- "a/\345\245\227\345\210\251\350\275\257\344\273\266(\345\267\256\344\273\267\345\245\227\345\210\251).js" +++ /dev/null @@ -1,252 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/275 -策略名称: 套利软件(差价套利) -策略作者: Zero -策略描述: - -主交易所参考其它交易所价格, 判断当前价格的走向, 所以策略需要添加两个交易所 - - -参数 默认值 描述 -------------------- ----- ---------- -Interval 2000 出错重试间隔(毫秒) -SlidePrice 0.3 滑动价(元) -StopLoss 0.8 止损点 -StopProfitThreshold 0.9 止盈系数(0-1) -EnableGoingShort true 允许做空 -LoopInterval true 轮询间隔(秒) -PriceDiff 5 套利差价 -AmountOnce 0.2 单笔交易数量 -*/ - - -function adjustFloat(v) { - return Math.floor(v*1000)/1000; -} - -function GetOrders() { - var orders = null; - while (!(orders = exchange.GetOrders())) { - Sleep(Interval); - } - return orders; -} - -function CancelPendingOrders() { - while (true) { - var orders = GetOrders(); - if (orders.length == 0) { - return; - } - - for (var j = 0; j < orders.length; j++) { - exchange.CancelOrder(orders[j].Id, orders[j]); - if (j < (orders.length-1)) { - Sleep(Interval); - } - } - } -} - -function GetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(Interval); - } - return account; -} - -function GetTicker(e) { - if (typeof(e) == 'undefined') { - e = exchange; - } - var ticker; - while (!(ticker = e.GetTicker())) { - Sleep(Interval); - } - return ticker; -} - -function updateProft(accountInit, accountNow, ticker) { - var netNow = accountNow.Balance + accountNow.FrozenBalance + ((accountNow.Stocks + accountNow.FrozenStocks) * ticker.Buy); - var netInit = accountInit.Balance + accountInit.FrozenBalance + ((accountInit.Stocks + accountInit.FrozenStocks) * ticker.Buy); - LogProfit(netNow - netInit); -} - -var STATE_WAIT_IDLE = 0; -var STATE_WAIT_BUY = 1; -var STATE_WAIT_SELL = 2; -var STATE_BUY = 3; -var STATE_SELL = 4; - -var State = STATE_WAIT_IDLE; -var InitAccount = null; -var LastBuyPrice = 0; -var LastSellPrice = 0; -var LastHighPrice = 0; -var LastLowPrice = 0; -var LastRecord = null; -var Goingshort = false; - -function onTick(exchange) { - var oldState = State; - var ticker = GetTicker(); - - if (State == STATE_WAIT_IDLE) { - var tickerOther = GetTicker(exchanges[1]); - // 价格被低估 - if ((tickerOther.Buy - ticker.Sell) > PriceDiff) { - Goingshort = false; - State = STATE_BUY; - Log('开始做多, 价差:', adjustFloat(tickerOther.Buy - ticker.Sell)); - } else if ((ticker.Buy - tickerOther.Sell) > PriceDiff) { - Goingshort = true; - State = STATE_SELL; - Log('开始做空, 价差:', adjustFloat(ticker.Buy - tickerOther.Sell)); - } else { - return; - } - } - - // 重新设置这两个参数 - if (oldState == STATE_WAIT_IDLE && State != STATE_WAIT_IDLE) { - LastLowPrice = ticker.Last; - LastHighPrice = ticker.Last; - } - - // 做多 - if (!Goingshort) { - if (State == STATE_WAIT_SELL) { - var ratioStopLoss = Math.abs((LastHighPrice - ticker.Last) / LastHighPrice) * 100; - var ratioStopProfit = Math.abs((ticker.Last - LastBuyPrice) / LastBuyPrice) * 100; - var ratioMaxUp = Math.abs((LastHighPrice - LastBuyPrice) / LastBuyPrice) * 100; - if (ticker.Last < LastBuyPrice && ratioStopLoss >= StopLoss) { - State = STATE_SELL; - Log("开始止损, 当前下跌点数:", adjustFloat(ratioStopLoss), "当前价格", ticker.Last, "对比价格", adjustFloat(LastHighPrice)); - } else if (ticker.Last > LastBuyPrice && ticker.Last < LastHighPrice && ratioStopProfit <= (ratioMaxUp*StopProfitThreshold)) { - State = STATE_SELL; - Log("开始止赢, 当前上涨点数:", adjustFloat(ratioStopProfit), "当前价格", ticker.Last, "对比价格", adjustFloat(LastBuyPrice)); - } - LastHighPrice = Math.max(LastHighPrice, ticker.Last); - } - } else { - if (State == STATE_WAIT_BUY) { - var ratioStopLoss = Math.abs((ticker.Last - LastLowPrice) / LastLowPrice) * 100; - var ratioStopProfit = Math.abs((LastSellPrice - ticker.Last) / LastSellPrice) * 100; - var ratioMaxDown = Math.abs((LastSellPrice - LastLowPrice) / LastSellPrice) * 100; - if (ticker.Last > LastSellPrice && ratioStopLoss >= StopLoss) { - State = STATE_BUY; - Log("开始止损, 当前上涨点数:", adjustFloat(ratioStopLoss), "当前价格", ticker.Last, "对比价格", adjustFloat(LastSellPrice)); - } else if (ticker.Last < LastSellPrice && ticker.Last > LastLowPrice && ratioStopProfit <= (ratioMaxDown*StopProfitThreshold)) { - State = STATE_BUY; - Log("开始止盈, 当前下跌点数:", adjustFloat(ratioStopProfit), "当前价格", ticker.Last, "对比价格", adjustFloat(LastLowPrice)); - } - LastHighPrice = Math.max(LastHighPrice, ticker.Last); - LastLowPrice = Math.min(LastLowPrice, ticker.Last); - } - - } - - if (State != STATE_BUY && State != STATE_SELL) { - return; - } - var orders = GetOrders(); - if (orders.length > 0) { - if (((State == STATE_BUY) && (LastBuyPrice >= (ticker.Buy-SlidePrice))) || ((State == STATE_SELL) && (LastSellPrice <= (ticker.Sell-SlidePrice)))) { - return; - } - } - // Buy or Sell, Cancel pending orders first - CancelPendingOrders(); - // Wait Ticker Update - Sleep(3000); - var account = GetAccount(); - // Update Ticker - ticker = GetTicker(); - - // 做多 - if (!Goingshort) { - if (State == STATE_BUY) { - var tickerOther = GetTicker(exchanges[1]); - // 价差消失 - if ((tickerOther.Buy - ticker.Sell) < (PriceDiff/2)) { - Log('做多价差消失:', adjustFloat(tickerOther.Buy - ticker.Sell)); - if ((account.Stocks - InitAccount.Stocks) > exchange.GetMinStock()) { - State = STATE_WAIT_SELL; - } else { - State = STATE_WAIT_IDLE; - } - return; - } - var price = ticker.Buy + SlidePrice; - var amount = adjustFloat(Math.min(AmountOnce, account.Balance / price)); - if (amount >= exchange.GetMinStock()) { - if (exchange.Buy(price, amount)) { - LastBuyPrice = LastHighPrice = price; - } - } else { - State = STATE_WAIT_SELL; - } - } else { - var sellAmount = Math.min(AmountOnce, account.Stocks - InitAccount.Stocks); - if (sellAmount > exchange.GetMinStock()) { - exchange.Sell(ticker.Sell - SlidePrice, sellAmount); - LastSellPrice = price; - } else { - // No stocks, wait buy and log profit - updateProft(account, InitAccount, ticker); - State = STATE_WAIT_IDLE; - } - } - } else { - if (State == STATE_BUY) { - var price = ticker.Buy + SlidePrice; - var amount = adjustFloat(Math.min(AmountOnce, account.Balance / price, InitAccount.Stocks - account.Stocks)); - if (amount >= exchange.GetMinStock()) { - exchange.Buy(price, amount); - LastBuyPrice = price; - } else { - updateProft(account, InitAccount, ticker); - State = STATE_WAIT_IDLE; - } - } else { - var tickerOther = GetTicker(exchanges[1]); - // 价差消失 - if ((ticker.Buy - tickerOther.Sell) < (PriceDiff/2)) { - Log('做空价差消失:', adjustFloat(ticker.Buy - tickerOther.Sell)); - if ((InitAccount.Stocks - account.Stocks) > exchange.GetMinStock()) { - State = STATE_WAIT_BUY; - } else { - State = STATE_WAIT_IDLE; - } - return; - } - var price = ticker.Sell - SlidePrice; - var sellAmount = Math.min(AmountOnce, account.Stocks); - if (sellAmount > exchange.GetMinStock()) { - exchange.Sell(price, sellAmount, "做空"); - LastSellPrice = LastLowPrice = price; - } else { - // No stocks, wait buy and log profit - State = STATE_WAIT_BUY; - } - } - } -} - -function main() { - if (exchanges.length < 2) { - throw '最少提供一个参考平台'; - } - InitAccount = GetAccount(); - LoopInterval = Math.min(1, LoopInterval); - Log('交易平台:', exchange.GetName(), GetAccount()); - Log('参考平台:', exchanges[1].GetName()); - - EnableGoingShort = EnableGoingShort && (InitAccount.Stocks > exchange.GetMinStock()); - LoopInterval = Math.max(LoopInterval, 1); - while (true) { - onTick(exchange); - Sleep(LoopInterval*1000); - } -} diff --git "a/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210 (Copy).js" "b/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210 (Copy).js" new file mode 100644 index 00000000..69d77ff4 --- /dev/null +++ "b/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210 (Copy).js" @@ -0,0 +1,76 @@ +/* +策略出处: https://www.botvs.com/strategy/83805 +策略名称: 定投简单版 (Copy) +策略作者: thifeathe +策略描述: + + + + +参数 默认值 描述 +------------------ ----- ----- +singleInvestAmount 0.1 单次买入量 +*/ + +// botvs@620e5a1b33965b615ef40e1d29cd2c44 + +/*backtest + start: 2017-12-01 + end: 2018-01-01 + period: 60 + mode: 2 +*/ + +function dateFormat(date, format) { + var o = { + "M+": date.getMonth() + 1, //月份 + "d+": date.getDate(), //日 + "h+": date.getHours(), //小时 + "m+": date.getMinutes(), //分 + "s+": date.getSeconds(), //秒 + "q+": Math.floor((date.getMonth() + 3) / 3), //季度 + "S": date.getMilliseconds() //毫秒 + }; + if (/(y+)/.test(format)) { + format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length)); + } + + for (var k in o) { + if (new RegExp("(" + k + ")").test(format)) { + format = format.replace(RegExp.$1, (RegExp.$1.length == 1) ? + (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); + } + } + + return format; +} + + +function main() { + Log(exchange.GetAccount()); + + //最近一次投资的日期 + var lastInvestDate = ''; + + while (true) { + //每次轮询,间隔时间为60秒 + Sleep(60 * 1000); + + //如果当前日期和最近一次投资日期相同,说明当天已经投过了,跳过 + var date = dateFormat(new Date(), "yyyy-MM-dd"); + if (date == lastInvestDate) { + continue; + } + + lastInvestDate = date; + Log("日期: " + date); + + //获取当前深度 + var depth = exchange.GetDepth(); + + //以买1价挂一个买入单 + var buy1price = depth.Bids[0].Price; + exchange.Buy(buy1price, singleInvestAmount / buy1price); + } +} + diff --git "a/\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.js" "b/\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.js" index 26e84f05..f84f1738 100644 --- "a/\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.js" +++ "b/\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.js" @@ -29,21 +29,6 @@ var lastHighPrice = 0; var lastBuyPrice = 0; var initBalance = 0; -function GetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(2000); - } - return account; -} - -function GetTicker() { - var ticker; - while (!(ticker = exchange.GetTicker())) { - Sleep(2000); - } - return ticker; -} function cancelAllOrders() { var orders = null; @@ -61,13 +46,9 @@ function cancelAllOrders() { } } -function adjustFloat(v) { - return Math.floor(v*1000)/1000; -} - function MustBuy() { var buyAmount = 0; - var initAccount = GetAccount(); + var initAccount = _C(exchange.GetAccount); if (initBalance == 0) { initBalance = initAccount.Balance; if (initAccount.Balance < UsedFund) { @@ -82,22 +63,22 @@ function MustBuy() { var buyAmount = 0; while (spend < UsedFund) { - var ticker = GetTicker(); - var amount = adjustFloat((UsedFund - spend) / (ticker.Last + SlidePrice)); - if (amount < exchange.GetMinStock()) { + var ticker = _C(exchange.GetTicker); + var amount = _N((UsedFund - spend) / (ticker.Last + SlidePrice)); + if (amount < 0.001) { break; } exchange.Buy(ticker.Last + SlidePrice, amount); Sleep(RetryInterval * 1000); cancelAllOrders(); - var account = GetAccount(); + var account = _C(exchange.GetAccount); spend = initAccount.Balance - account.Balance; buyAmount = account.Stocks - initAccount.Stocks; } if (buyAmount > 0) { lastBuyPrice = lastHighPrice = (spend / buyAmount); - Log("平均买入价", adjustFloat(lastHighPrice)); + Log("平均买入价", _N(lastHighPrice)); } return buyAmount; @@ -105,13 +86,13 @@ function MustBuy() { function MustSell(sellAmount) { var remaind = sellAmount; - var initAccount = GetAccount(); - while (remaind >= exchange.GetMinStock()) { - var ticker = GetTicker(); + var initAccount = _C(exchange.GetAccount); + while (remaind >= 0.001) { + var ticker = _C(exchange.GetTicker); exchange.Sell(ticker.Last - SlidePrice, remaind); Sleep(RetryInterval * 1000); cancelAllOrders(); - var newAccount = GetAccount(); + var newAccount = _C(exchange.GetAccount); remaind -= (initAccount.Stocks - newAccount.Stocks); initAccount = newAccount; } @@ -137,7 +118,7 @@ function onTick() { } state = 0; } else if ((EnableStopProfit || EnableStopLoss) && lastBuyAmount > 0) { - var ticker = GetTicker(); + var ticker = _C(exchange.GetTicker); if (RefHigh) { lastHighPrice = Math.max(lastHighPrice, ticker.Last); } @@ -147,12 +128,12 @@ function onTick() { if (EnableStopLoss && ticker.Last < lastHighPrice && (ratioStopLoss >= (StopLoss/100))) { // Stop loss - Log("开始止损, 当前跌价点数:", adjustFloat(ratioStopLoss*100), "当前价格", ticker.Last, "对比价格", adjustFloat(lastHighPrice)); + Log("开始止损, 当前跌价点数:", _N(ratioStopLoss*100), "当前价格", ticker.Last, "对比价格", _N(lastHighPrice)); shouldSell = true; } else if (EnableStopProfit && ticker.Last > lastBuyPrice && (ratioStopProfit >= (StopProfit/100))) { // Stop loss - Log("开始止赢, 当前涨价点数:", adjustFloat(ratioStopProfit*100), "当前价格", ticker.Last, "对比价格", adjustFloat(lastBuyPrice)); + Log("开始止赢, 当前涨价点数:", _N(ratioStopProfit*100), "当前价格", ticker.Last, "对比价格", _N(lastBuyPrice)); shouldSell = true; } @@ -167,10 +148,11 @@ function main() { if (EnterHour == LeaveHour) { throw "进场时间跟离场时间不能相等!"; } - Log(GetAccount()); + Log(_C(exchange.GetAccount)); while(true) { onTick(); Sleep(60000); } } + diff --git "a/\345\271\263\345\217\260API\346\265\213\350\257\225.js" "b/\345\271\263\345\217\260API\346\265\213\350\257\225.js" deleted file mode 100644 index 44327b7e..00000000 --- "a/\345\271\263\345\217\260API\346\265\213\350\257\225.js" +++ /dev/null @@ -1,33 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/71 -策略名称: 平台API测试 -策略作者: Zero -策略描述: - -平台API测试, 可以添加多个平台,测试接口是否正常. - -*/ - -function main() { - Log("ALL Platform", exchanges.length); - for (var i = 0; i < exchanges.length; i++) { - var ex = exchanges[i]; - Log(ex.GetName(), ex.GetCurrency(), ex.GetFee()); - Log(ex.GetAccount()); - Log(ex.GetDepth()); - var depth = ex.GetDepth(); - if (depth) { - Log("Depth", depth.Asks.length); - } else { - Log("Depth NULL"); - } - Log('ticker', ex.GetTicker()); - Log(ex.CancelOrder(123)); - var orders = ex.GetOrders(); - if (orders) { - Log("orders", orders.length); - } else { - Log("orders NULL"); - } - } -} diff --git "a/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.js" "b/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.js" index 744f2fc9..58449c0d 100644 --- "a/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.js" +++ "b/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.js" @@ -7,30 +7,20 @@ 抢盘口做市策略, 最基础的做市策略,买一卖一抢单抢盘口, 赚买一卖一的差价. -参数 默认值 描述 ------------- ----- ---------- -Interval 2000 出错重试间隔(毫秒) -LoopInterval true 轮询间隔(秒) -SlidePrice 0.01 滑点 -MaxDiff 0.8 盘口最小差价 -Lot 0.2 手数 +参数 默认值 描述 +------------ ------ ---------- +Interval 2000 出错重试间隔(毫秒) +LoopInterval true 轮询间隔(秒) +SlidePrice 0.01 滑点 +MaxDiff 0.8 盘口最小差价 +Lot 0.2 手数 +MinStock 0.0001 最小交易量 */ -function adjustFloat(v) { - return Math.floor(v*1000)/1000; -} - -function GetOrders() { - var orders = null; - while (!(orders = exchange.GetOrders())) { - Sleep(Interval); - } - return orders; -} function CancelPendingOrders(orderType) { while (true) { - var orders = GetOrders(); + var orders = _C(exchange.GetOrders); var count = 0; if (typeof(orderType) != 'undefined') { for (var i = 0; i < orders.length; i++) { @@ -56,24 +46,6 @@ function CancelPendingOrders(orderType) { } } -function GetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(Interval); - } - return account; -} - -function GetTicker(e) { - if (typeof(e) == 'undefined') { - e = exchange; - } - var ticker; - while (!(ticker = e.GetTicker())) { - Sleep(Interval); - } - return ticker; -} function updateProfit(accountInit, accountNow, ticker) { var netNow = accountNow.Balance + accountNow.FrozenBalance + ((accountNow.Stocks + accountNow.FrozenStocks) * ticker.Buy); @@ -86,7 +58,7 @@ var LastBuyPrice = 0; var LastSellPrice = 0; function onTick() { - var ticker = GetTicker(); + var ticker = _C(exchange.GetTicker); var BuyPrice = ticker.Buy + SlidePrice; var SellPrice = ticker.Sell - SlidePrice; @@ -116,15 +88,15 @@ function onTick() { CancelPendingOrders(cancelType); } - var orders = GetOrders(); + var orders = _C(exchange.GetOrders); if (orders.length == 2) { return; } - var account = GetAccount(); - var amountBuy = Math.min(adjustFloat(account.Balance / BuyPrice), Lot); + var account = _C(exchange.GetAccount); + var amountBuy = _N(Math.min(account.Balance / BuyPrice, Lot)); var amountSell = Math.min(account.Stocks, Lot); - if (amountBuy >= exchange.GetMinStock()) { + if (amountBuy >= MinStock) { if (orders.length == 0 || orders[0].Type == ORDER_TYPE_SELL) { if (orders.length > 0) { updateProfit(InitAccount, account, ticker); @@ -133,7 +105,7 @@ function onTick() { LastBuyPrice = BuyPrice; } } - if (amountSell >= exchange.GetMinStock()) { + if (amountSell >= MinStock) { if (orders.length == 0 || orders[0].Type == ORDER_TYPE_BUY) { if (orders.length > 0) { updateProfit(InitAccount, account, ticker); @@ -149,14 +121,15 @@ function onexit() { } function main() { - InitAccount = GetAccount(); + InitAccount = _C(exchange.GetAccount); Log(InitAccount); SetErrorFilter("502:|503:|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|received|EOF"); exchange.SetRate(1); LoopInterval = Math.max(LoopInterval, 1); - Lot = Math.max(exchange.GetMinStock(), Lot); + Lot = Math.max(MinStock, Lot); while (true) { onTick(); Sleep(LoopInterval * 1000); } } + diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.cpp" similarity index 100% rename from "\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.js" rename to "\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.cpp" diff --git "a/\346\234\237\350\264\247\345\201\232\345\270\202\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245 \345\205\274\345\256\271OK-VC-796.js" "b/\346\234\237\350\264\247\345\201\232\345\270\202\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245 \345\205\274\345\256\271OK-VC-796.js" deleted file mode 100644 index 950677da..00000000 --- "a/\346\234\237\350\264\247\345\201\232\345\270\202\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245 \345\205\274\345\256\271OK-VC-796.js" +++ /dev/null @@ -1,434 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/1484 -策略名称: 期货做市高频交易策略 兼容OK-VC-796 -策略作者: Zero -策略描述: - -这个策略属于期货的做市策略 -会对盘口价格造成影响 -所以不适合大资金. -策略为研究市场行为而写, 实盘请用小资金测试. - - -参数 默认值 描述 --------------- ----- ----------------- -ContractType 0 合约类型: 周|月|季 -MLevel 0 杠杆大小: 5倍|10倍|20倍 -DepthBuy 5 买单深度 -DepthSell 5 卖单深度 -Interval 500 出错重试间隔(毫秒) -LoopInterval 2 轮询间隔(秒) -SlidePrice 0.01 滑点 -MinDiff 0.5 盘口最小差价 -KeepStocksRate true 保证金保留倍数 -Lot 80 开仓手数 -LotCover 200 平仓手数 -StopLoss 3 最大亏损波动(元) -StopProfit 0.5 目标利润点(元) -OpType 0 操作类型: 做多|做空|自动 -EMA_Fast 7 EMA快线周期 -EMA_Slow 12 EMA慢线周期 -EMAInterval 50 EMA检测间隔(秒) -WaitType 0 K线收集完成前: 做多|做空|等待 -DisableLog false 关闭订单跟踪 -*/ - -var DO_IDLE = 0; -var DO_LONG = 1; -var DO_SHORT = 2; - -var _MarginLevel = [5, 10, 20][MLevel]; -var _ContractType = ["week", "month", "quarter"][ContractType]; -var _CurrentDirection = [DO_LONG, DO_SHORT, DO_IDLE][OpType !=2 ? OpType : WaitType]; -var _isAuto = OpType == 2; -var _IsBitVC = false; -var _Is796 = false; -var _IsOKCoin = false; -var _MinAmount = 0; -var _Fee = 0.0003; - -function _N(v, precision) { - if (typeof(precision) != 'number') { - precision = _IsOKCoin ? 3 : 2; - } - var d = parseFloat(v.toFixed(Math.max(10, precision+5))); - s = d.toString().split("."); - if (s.length < 2 || s[1].length <= precision) { - return d; - } - - var b = Math.pow(10, precision); - return Math.floor(d*b)/b; -} - -function GetOrders() { - var orders = null; - while (!(orders = exchange.GetOrders())) { - Sleep(Interval); - } - return orders; -} - -function CancelPendingOrders(orderType) { - while (true) { - var orders = GetOrders(); - var count = 0; - if (typeof(orderType) != 'undefined') { - for (var i = 0; i < orders.length; i++) { - if (orders[i].Type == orderType) { - count++; - } - } - } else { - count = orders.length; - } - if (count == 0) { - return; - } - - for (var j = 0; j < orders.length; j++) { - if (typeof(orderType) == 'undefined' || (orderType == orders[j].Type)) { - exchange.CancelOrder(orders[j].Id, orders[j]); - if (j < (orders.length-1)) { - Sleep(Interval); - } - } - } - } -} - -function GetPosition(orderType) { - var positions; - while (!(positions = exchange.GetPosition())) { - Sleep(Interval); - } - for (var i = 0; i < positions.length; i++) { - if (positions[i].ContractType == _ContractType && positions[i].Type == orderType) { - return positions[i]; - } - } - return null; -} - -function GetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(Interval); - } - return account; -} - -function GetLimit() { - var ticker; - while (!(ticker = exchange.GetTicker())) { - Sleep(Interval); - } - if (IsVirtual()) { - return {high: ticker.Sell + 100, low: ticker.Buy - 100}; - } - var js = exchange.GetRawJSON(); - try { - var obj = JSON.parse(js); - return {high: parseFloat(obj.limit_highest_price), low: parseFloat(obj.limit_lowest_price)}; - } catch (e) { - Log(e); - } - return null; -} - -function GetDepth() { - var depth; - while (true) { - depth = exchange.GetDepth(); - if (depth && depth.Asks.length > 0 && depth.Bids.length > 0 && depth.Asks[0].Price > depth.Bids[0].Price) { - break; - } - Sleep(Interval); - } - return depth; -} - -var LastOpenPrice = 0; -var LastCoverPrice = 0; -var LastHoldPrice = 0; -var LastRecord = null; -var LastEMATime = 0; - -function GetDirection() { - if (OpType != 2) { - return _CurrentDirection; - } - var n = new Date().getTime(); - if ((n - LastEMATime) < (EMAInterval * 1000)) { - return _CurrentDirection; - } - LastEMATime = n; - - var records = exchange.GetRecords(); - if (!records || records.length < (EMA_Slow + 3)) { - return _CurrentDirection; - } - var newLast = records[records.length-1]; - if ((!LastRecord) || (LastRecord.Time == newLast.Time && LastRecord.Close == newLast.Close)) { - if (!LastRecord) { - LastRecord = newLast; - } - return _CurrentDirection; - } - LastRecord = newLast; - - var emaFast = TA.EMA(records, EMA_Fast); - var emaSlow = TA.EMA(records, EMA_Slow); - return emaFast[emaFast.length-1] >= emaSlow[emaSlow.length-1] ? DO_LONG : DO_SHORT; -} - -function GetPrice() { - var buyPrice = 0; - var buyAmount = 0; - var sellPrice = 0; - var sellAmount = 0; - var depth = GetDepth(); - for (var i = 0; i < depth.Asks.length; i++) { - sellAmount += depth.Asks[i].Amount; - if (sellAmount >= DepthSell) { - sellPrice = depth.Asks[i].Price; - break; - } - } - - for (var i = 0; i < depth.Bids.length; i++) { - buyAmount += depth.Bids[i].Amount; - if (buyAmount >= DepthBuy) { - buyPrice = depth.Bids[i].Price; - break; - } - } - - var diff = MinDiff - (sellPrice - buyPrice); - if (diff >= 0) { - buyPrice = buyPrice - (diff/2); - sellPrice = sellPrice + (diff/2); - } else { - buyPrice += SlidePrice; - sellPrice -= SlidePrice; - } - return {buy : buyPrice, sell: sellPrice}; -} - - -function updateProfit() { - var account = GetAccount(); - if (_IsBitVC) { - try { - var obj = JSON.parse(exchange.GetRawJSON()); - LogProfit(obj.dynamicRights, 'Stocks:', account.Stocks, 'FrozenStocks:', account.FrozenStocks); - } catch(e) { - Log(e); - } - } else { - LogProfit(account.Stocks + account.FrozenStocks); - } -} - -var _prePositions = 0; - -function onTick() { - var price = GetPrice(); - - if (_IsBitVC) { - var limit = GetLimit(); - if (limit) { - price.sell = Math.max(Math.min(price.sell, limit.high), limit.low); - price.buy = Math.min(Math.max(price.buy, limit.low), limit.high); - } - } - - var openFunc = _CurrentDirection == DO_LONG ? exchange.Buy : exchange.Sell; - var openDirection = _CurrentDirection == DO_LONG ? "buy" : "sell"; - var openTradeType = _CurrentDirection == DO_LONG ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; - - var coverFunc = _CurrentDirection == DO_LONG ? exchange.Sell : exchange.Buy; - var coverDirection = _CurrentDirection == DO_LONG ? "closebuy" : "closesell"; - var coverTradeType = _CurrentDirection == DO_LONG ? ORDER_TYPE_SELL : ORDER_TYPE_SELL; - - var openPrice = _N(_CurrentDirection == DO_LONG ? price.buy : price.sell); - var coverPrice = _N(_CurrentDirection == DO_LONG ? price.sell : price.buy); - - var op = 0; - var isFighting = false; - var marketCoverPrice = coverPrice; - - if (LastHoldPrice > 0 && LastCoverPrice > 0) { - if (_CurrentDirection == DO_LONG) { - isFighting = (LastHoldPrice - coverPrice) <= StopLoss; - if (isFighting) { - coverPrice = _N((LastHoldPrice * (1+_Fee)) + StopProfit); - } else { - isFighting = true; - } - } else { - isFighting = (coverPrice - LastHoldPrice) <= StopLoss; - if (isFighting) { - coverPrice = _N((LastHoldPrice * (1-_Fee)) - StopProfit); - } - } - } - - if (LastHoldPrice > 0) { - LogStatus(_CurrentDirection == DO_LONG ? "多仓" : "空仓", isFighting ? "僵持中.." : "止损中..", "持仓均价: ", _N(LastHoldPrice), "盘口平仓价:", marketCoverPrice, isFighting ? "#0000ff" : "#ff0000"); - } else { - LogStatus(_CurrentDirection == DO_LONG ? "做多" : "做空", "开仓价: ", openPrice, "平仓价:", marketCoverPrice, "抢盘中... #428bca"); - } - - if (openPrice != LastOpenPrice) { - op = 1; - } - - if (coverPrice != LastCoverPrice) { - op = op == 0 ? 2 : 3; - } - - if (op == 3) { - CancelPendingOrders(); - } else if (op != 0) { - CancelPendingOrders(op == 1 ? openTradeType : coverTradeType); - } else { - return; - } - - var position = 0; - - var hold = GetPosition(openTradeType); - if (hold) { - position = hold.Amount; - LastHoldPrice = hold.Price; - } else { - LastHoldPrice = 0; - } - - var coverAmount = _N(Math.min(position, _IsBitVC ? (LotCover * 100) : LotCover)); - if (!_Is796) { - coverAmount = parseInt(coverAmount); - } - if (_IsBitVC) { - coverAmount = parseInt(parseInt(coverAmount / 100) * 100); - } - if ((op == 2 || op == 3) && (coverAmount >= _MinAmount)) { - exchange.SetDirection(coverDirection); - if (coverFunc(coverPrice, coverAmount, "上次平仓价格", LastCoverPrice) > 0) { - LastCoverPrice = coverPrice; - } - } - - if (position == 0 && _prePositions != 0) { - updateProfit(); - _prePositions = 0; - } - - var d = GetDirection(); - if (_prePositions == 0) { - _prePositions = position; - } - - - if (_isAuto) { - if (d != _CurrentDirection) { - if (position == 0 && GetOrders().length == 0) { - Log(d == DO_LONG ? "开始做多" : "开始做空"); - _CurrentDirection = d; - } - return; - } - } - - var account = GetAccount(); - var canUsedStocks = account.Stocks; - if (KeepStocksRate > 0) { - canUsedStocks = _N(Math.max(account.Stocks - _N((position * (_IsOKCoin ? 10 : 1) / _MarginLevel / (_Is796 ? 1 : openPrice)) * KeepStocksRate), 0) / KeepStocksRate); - } - var openAmount = 0; - if (_IsBitVC) { - openAmount = parseInt(parseInt(Math.min(((canUsedStocks * _MarginLevel * (openPrice*0.9)) / 100), Lot)) * 100); - } else if (_IsOKCoin) { - openAmount = parseInt(Math.min(((canUsedStocks * _MarginLevel * (openPrice*0.9)) / 10), Lot)); - } else { - openAmount = _N(Math.min(canUsedStocks * _MarginLevel, Lot)); - } - if ((op == 1 || op == 3) && (openAmount >= _MinAmount)) { - exchange.SetDirection(openDirection); - if (openFunc(openPrice, openAmount, "上次建仓价格", LastOpenPrice) > 0) { - LastOpenPrice = openPrice; - } - } -} - -function onexit() { - CancelPendingOrders(); - Log("Exit"); -} - -function main() { - var eName = exchange.GetName(); - - if (eName.indexOf("Futures") == -1) { - throw "该策略为期货专用策略"; - } - if (_IsOKCoin && _MarginLevel == 5) { - throw "OKCoin期货只支持10倍或20倍杠杆"; - } - if (DisableLog) { - EnableLog(false); - } - - _IsBitVC = eName.indexOf("BitVC") != -1; - _Is796 = eName.indexOf("796") != -1; - _IsOKCoin = eName.indexOf("OKCoin") != -1; - - if (_IsBitVC) { - _MinAmount = 100; - } else if (_IsOKCoin) { - _MinAmount = 1; - } else { - _MinAmount = exchange.GetMinStock(); - } - - exchange.SetRate(1); - Log(exchange.GetName(), GetAccount()); - CancelPendingOrders(); - LoopInterval = Math.max(LoopInterval, 1); - EMAInterval = Math.max(EMAInterval, 1); - if (_IsBitVC || _IsOKCoin) { - Lot = parseInt(Math.max(1, Lot)); - LotCover = parseInt(Math.max(1, LotCover)); - if (Lot < 1 || LotCover < 1) { - throw "手数最少为1, BitVC一手相当于100元人民币, OKCoin相当于10美金."; - } - } - KeepStocksRate = parseInt(KeepStocksRate); - Log("预留", KeepStocksRate, "倍的保证金"); - - if (_IsOKCoin && ContractType == 0) { - _ContractType = "this_week"; - } - if (!_IsOKCoin && ContractType == 1) { - throw "只有OKCoin期货支持月全约"; - } - if (_Is796 && ContractType != 0) { - throw "796只支持周合约类型"; - } - exchange.SetContractType(_ContractType); - exchange.SetMarginLevel(_MarginLevel); - - if (OpType == 2) { - Log("开始收集K线信息, 请耐心等待."); - } - - while (true) { - if (_CurrentDirection == DO_IDLE) { - _CurrentDirection = GetDirection(); - } else { - onTick(); - } - Sleep(LoopInterval * 1000); - } -} diff --git "a/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.py" "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.py" new file mode 100644 index 00000000..cf92c660 --- /dev/null +++ "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.py" @@ -0,0 +1,73 @@ +''' +策略出处: https://www.botvs.com/strategy/84042 +策略名称: 测试多图表展示Python版 +策略作者: 小小梦 +策略描述: + + + +''' + +import random +import time +def main(): + cfgA = { + "title" : {"text" : "盘口图表"}, + "xAxis" : { + "type" : "datetime" + }, + "series" : [{ + "name" : "买一", + "data" : [], + },{ + "name" : "卖一", + "data" : [], + }] + } + + cfgB = { + "title" : {"text" : "差价图"}, + "xAxis" : { + "type" : "datetime" + }, + "series" : [{ + "name" : "差价", + "type" : "column", + "data" : [], + }] + } + + cfgC = { + "__isStock" : False, + "title" : { + "text" : "饼图" + }, + "series" : [{ + "type" : "pie", + "name" : "one", + "data" : [ + ["A", 25], + ["B", 25], + ["C", 25], + ["D", 25], + ] + }] + } + + chart = Chart([cfgA, cfgB, cfgC]) + chart.reset() + chart.add(3, { + "name" : "ZZ", + "y" : random.random() * 100 + }) + + + chart.update([cfgA, cfgB, cfgC]) + chart.add(0, [_N(time.time() * 1000, 0), 50]) + chart.add(1, [_N(time.time() * 1000, 0), 80]) + chart.add(2, [_N(time.time() * 1000, 0), 90]) + chart.add(3, { + "name" : "ZZ", + "y" : random.random() * 100 + }, -1) + diff --git "a/\347\273\237\350\256\241BitVC\345\212\250\346\200\201\346\235\203\347\233\212-OKCoin\345\267\262\347\273\217\345\256\236\347\216\260\347\233\210\344\272\217-796\350\264\246\346\210\267\344\275\231\351\242\235.js" "b/\347\273\237\350\256\241BitVC\345\212\250\346\200\201\346\235\203\347\233\212-OKCoin\345\267\262\347\273\217\345\256\236\347\216\260\347\233\210\344\272\217-796\350\264\246\346\210\267\344\275\231\351\242\235.js" deleted file mode 100644 index ef17b47c..00000000 --- "a/\347\273\237\350\256\241BitVC\345\212\250\346\200\201\346\235\203\347\233\212-OKCoin\345\267\262\347\273\217\345\256\236\347\216\260\347\233\210\344\272\217-796\350\264\246\346\210\267\344\275\231\351\242\235.js" +++ /dev/null @@ -1,59 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/1483 -策略名称: 统计BitVC动态权益-OKCoin已经实现盈亏-796账户余额 -策略作者: Zero -策略描述: - -利用2.67版本新增加的GetRawJSON函数, 可以返回最后一次REST API请求返回的原始信息, 来解析平台的扩展参数 - - -参数 默认值 描述 ----------- ----- ------- -LoopIntval 30 检测周期(秒) -*/ - -function main() { - var eName = exchange.GetName(); - var coin = exchange.GetCurrency().toLowerCase(); - var isBitVC = eName == "Futures_BitVC"; - var isOKCoin = eName == "Futures_OKCoin"; - var is796 = eName == "Futures_796"; - if (!isBitVC && !isOKCoin && !is796) { - throw "该策略为 BitVC/OKCoin/796 期货专用策略"; - } - if (parseFloat(Version()) < 2.67) { - throw "要求托管者2.67版本以上"; - } - - var lastVal = 0; - LoopIntval = Math.max(LoopIntval, 1); - Log(isBitVC ? "BitVC动态权益" : "OKCoin已实现盈亏", "将显示为收益曲线, 有变化后更新"); - while (true) { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(300); - } - // GetRawJSON返回GetAccount的原始信息 - var js = exchange.GetRawJSON(); - try { - var obj = JSON.parse(js); - var v = 0; - if (isBitVC) { - v = obj.dynamicRights; - } else if (isOKCoin) { - for (var i = 0; i < obj.info[coin].contracts.length; i++) { - v += obj.info[coin].contracts[i].profit; - } - } else if (is796) { - v = account.Stocks; - } - if (v != lastVal) { - lastVal = v; - LogProfit(lastVal, 'Stocks:', account.Stocks, 'FrozenStocks:', account.FrozenStocks); - } - } catch(e) { - Log(e); - } - Sleep(LoopIntval * 1000); - } -} diff --git "a/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" index 90d6e1e3..bc0e18c5 100644 --- "a/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" +++ "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" @@ -51,6 +51,8 @@ EnableDynamic false 开启动态挂单 DynamicMax 30 订单失效距离(元) ResetData true 启动时清空所有数据 Precision 5 价格小数位长度 +XPrecision 5 下单量小数位长度 +MinStock 0.001 最小交易量 按钮 默认值 描述 ---- ---------- ---------- @@ -255,7 +257,7 @@ function balanceAccount(orgAccount, initAccount) { var ok = true; while (true) { var diff = _N(nowAccount.Stocks - initAccount.Stocks); - if (Math.abs(diff) < exchange.GetMinStock()) { + if (Math.abs(diff) < MinStock) { break; } var depth = _C(exchange.GetDepth); @@ -278,7 +280,7 @@ function balanceAccount(orgAccount, initAccount) { } else { amount = Math.min(nowAccount.Balance / price, amount); } - if (amount < exchange.GetMinStock()) { + if (amount < MinStock) { Log("资金不足, 无法平衡到初始状态"); ok = false; break; @@ -457,7 +459,7 @@ function fishing(orgAccount, fishCount) { var money_diff = (nowAccount.Balance + nowAccount.FrozenBalance) - (InitAccount.Balance + InitAccount.FrozenBalance); var floatProfit = _N(money_diff + (amount_diff * ticker.Last)); var floatProfitAll = _N((nowAccount.Balance + nowAccount.FrozenBalance - orgAccount.Balance - orgAccount.FrozenBalance) + ((nowAccount.Stocks + nowAccount.FrozenStocks - orgAccount.Stocks - orgAccount.FrozenStocks) * ticker.Last)); - var isHold = Math.abs(amount_diff) >= exchange.GetMinStock(); + var isHold = Math.abs(amount_diff) >= MinStock; if (isHold) { setBusy(); } @@ -605,7 +607,7 @@ function main() { LogProfitReset(); LogReset(); } - exchange.SetMaxDigits(Precision) + exchange.SetPrecision(Precision, XPrecision) if (typeof(AmountType) === 'undefined') { AmountType = 0; } diff --git "a/\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.js" "b/\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.js" index 72d99013..9fc12462 100644 --- "a/\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.js" +++ "b/\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.js" @@ -20,14 +20,11 @@ StopProfitThreshold 0.9 止盈系数(0-1) EMA_Slow 30 EMA慢线周期 EMA_Fast 7 EMA快线周期 EnableGoingShort true 允许做空 +MinStock 0.001 最小交易量 LoopInterval 60 轮询间隔(秒) */ -function adjustFloat(v) { - return Math.floor(v*1000)/1000; -} - function CancelPendingOrders() { while (true) { var orders = null; @@ -48,22 +45,6 @@ function CancelPendingOrders() { } } -function GetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(Interval); - } - return account; -} - -function GetTicker() { - var ticker; - while (!(ticker = exchange.GetTicker())) { - Sleep(Interval); - } - return ticker; -} - var STATE_WAIT_IDLE = 0; var STATE_WAIT_BUY = 1; var STATE_WAIT_SELL = 2; @@ -108,7 +89,7 @@ function onTick(exchange) { } } - var ticker = GetTicker(); + var ticker = _C(exchange.GetTicker); // 重新设置这两个参数 if (oldState == STATE_WAIT_IDLE && State != STATE_WAIT_IDLE) { LastLowPrice = ticker.Last; @@ -132,10 +113,10 @@ function onTick(exchange) { var ratioMaxUp = Math.abs((LastHighPrice - LastBuyPrice) / LastBuyPrice) * 100; if (ticker.Last < LastBuyPrice && ratioStopLoss >= StopLoss) { State = STATE_SELL; - Log("开始止损, 当前下跌点数:", adjustFloat(ratioStopLoss), "当前价格", ticker.Last, "对比价格", adjustFloat(LastHighPrice)); + Log("开始止损, 当前下跌点数:", _N(ratioStopLoss), "当前价格", ticker.Last, "对比价格", _N(LastHighPrice)); } else if (ticker.Last > LastBuyPrice && ticker.Last < LastHighPrice && ratioStopProfit <= (ratioMaxUp*StopProfitThreshold)) { State = STATE_SELL; - Log("开始止赢, 当前上涨点数:", adjustFloat(ratioStopProfit), "当前价格", ticker.Last, "对比价格", adjustFloat(LastBuyPrice)); + Log("开始止赢, 当前上涨点数:", _N(ratioStopProfit), "当前价格", ticker.Last, "对比价格", _N(LastBuyPrice)); } LastHighPrice = Math.max(LastHighPrice, ticker.Last); } @@ -155,10 +136,10 @@ function onTick(exchange) { var ratioMaxDown = Math.abs((LastSellPrice - LastLowPrice) / LastSellPrice) * 100; if (ticker.Last > LastSellPrice && ratioStopLoss >= StopLoss) { State = STATE_BUY; - Log("开始止损, 当前上涨点数:", adjustFloat(ratioStopLoss), "当前价格", ticker.Last, "对比价格", adjustFloat(LastSellPrice)); + Log("开始止损, 当前上涨点数:", _N(ratioStopLoss), "当前价格", ticker.Last, "对比价格", _N(LastSellPrice)); } else if (ticker.Last < LastSellPrice && ticker.Last > LastLowPrice && ratioStopProfit <= (ratioMaxDown*StopProfitThreshold)) { State = STATE_BUY; - Log("开始止盈, 当前下跌点数:", adjustFloat(ratioStopProfit), "当前价格", ticker.Last, "对比价格", adjustFloat(LastLowPrice)); + Log("开始止盈, 当前下跌点数:", _N(ratioStopProfit), "当前价格", ticker.Last, "对比价格", _N(LastLowPrice)); } LastHighPrice = Math.max(LastHighPrice, ticker.Last); LastLowPrice = Math.min(LastLowPrice, ticker.Last); @@ -173,24 +154,26 @@ function onTick(exchange) { // Buy or Sell, Cancel pending orders first CancelPendingOrders(); - var account = GetAccount(); + var account = _C(exchange.GetAccount); // 做多 if (!Goingshort) { if (State == STATE_BUY) { - var price = ticker.Last + SlidePrice; - var amount = adjustFloat(account.Balance / price); - if (amount >= exchange.GetMinStock()) { + var price = ticker.Sell + SlidePrice; + var amount = _N(account.Balance*0.99 / price); + if (amount >= MinStock) { if (exchange.Buy(price, amount, "做多")) { LastBuyPrice = LastHighPrice = price; + } else { + Log("开多仓失败", price, amount, account); } } else { State = STATE_WAIT_SELL; } } else { var sellAmount = account.Stocks - InitAccount.Stocks; - if (sellAmount > exchange.GetMinStock()) { - exchange.Sell(ticker.Last - SlidePrice, sellAmount); + if (sellAmount > MinStock) { + exchange.Sell(ticker.Buy - SlidePrice, sellAmount); } else { // No stocks, wait buy and log profit LogProfit(account.Balance - InitAccount.Balance, account); @@ -199,18 +182,18 @@ function onTick(exchange) { } } else { if (State == STATE_BUY) { - var price = ticker.Last + SlidePrice; - var amount = Math.min(adjustFloat(account.Balance / price), InitAccount.Stocks - account.Stocks); - if (amount >= exchange.GetMinStock()) { + var price = ticker.Sell + SlidePrice; + var amount = Math.min(_N(account.Balance*0.99 / price), InitAccount.Stocks - account.Stocks); + if (amount >= MinStock) { exchange.Buy(price, amount); } else { LogProfit(account.Balance - InitAccount.Balance, account); State = STATE_WAIT_IDLE; } } else { - var price = ticker.Last - SlidePrice; + var price = ticker.Buy - SlidePrice; var sellAmount = account.Stocks; - if (sellAmount > exchange.GetMinStock()) { + if (sellAmount > MinStock) { exchange.Sell(ticker.Last - SlidePrice, sellAmount, "做空"); LastSellPrice = LastLowPrice = price; } else { @@ -222,12 +205,13 @@ function onTick(exchange) { } function main() { - InitAccount = GetAccount(); + InitAccount = _C(exchange.GetAccount); Log(exchange.GetName(), exchange.GetCurrency(), InitAccount); - EnableGoingShort = EnableGoingShort && (InitAccount.Stocks > exchange.GetMinStock()); + EnableGoingShort = EnableGoingShort && (InitAccount.Stocks > MinStock); LoopInterval = Math.max(LoopInterval, 1); while (true) { onTick(exchange); Sleep(LoopInterval*1000); } } + From 7cef1487124aad64726f088486744802afb7d3b4 Mon Sep 17 00:00:00 2001 From: Zero Date: Thu, 5 Jul 2018 10:03:51 +0800 Subject: [PATCH 05/19] update --- ...210\206\346\236\220 (Share 1513097042).js" | 2 +- ...250\241\345\236\213 (Share 1513096985).js" | 2 +- ...72\345\223\201\347\255\226\347\225\245.js" | 2 +- ...344\272\272 (Copy) (Share 1512130985).js" | 182 ---- ...77\346\234\272\345\231\250\344\272\272.js" | 10 +- ...40\345\200\215\347\256\227\346\263\225.js" | 2 +- ...60\346\211\213\345\205\245\351\227\250.js" | 2 +- ...55\344\277\241\351\200\232\347\237\245.js" | 2 +- ...00\345\215\225\346\265\213\350\257\225.js" | 2 +- ...5\351\227\250 \347\255\226\347\225\245.js" | 2 +- ...3\347\224\250\344\276\213\345\255\220.cpp" | 2 +- ...44\346\230\223\347\255\226\347\225\245.js" | 2 +- ...344\272\206SSL\351\252\214\350\257\201.py" | 328 +++++++ Convert_Record_Cycle.js | 2 +- Dual Thrust OKEX Feature.js | 239 ++++++ ...Thrust OKCoin \346\234\237\350\264\247.js" | 8 +- ...06\345\223\201\346\234\237\350\264\247.js" | 2 +- ...\347\240\264_\347\255\226\347\225\2451.py" | 200 ----- ...1\346\200\273\345\210\206\344\272\253).js" | 146 ++++ Hedge_BTC-ETH Demo.js | 2 +- Iceberg Buy Order.js | 101 +++ ...26\347\225\245\346\241\206\346\236\266.js" | 2 +- "JS\347\211\210\346\234\254Dual Thrust.js" | 2 +- ...6\347\225\245_\344\275\216\351\242\221.js" | 2 +- MA_20180107 (Copy).js | 79 -- ...13\345\212\277\344\272\244\346\230\223.js" | 2 +- Moving Average Strategy in 30 lines.js | 60 ++ ...32\346\212\225\347\255\226\347\225\245.js" | 2 +- ...30\345\270\246\346\255\242\346\215\237.js" | 2 +- ...13\345\212\277\347\255\226\347\225\245.py" | 2 +- "Python API \346\265\213\350\257\225.py" | 2 +- ...71\345\206\262\347\255\226\347\225\245.py" | 2 +- ...04\346\265\213\344\271\260\345\215\226.py" | 11 +- ...(\346\265\213\350\257\225\347\211\210).py" | 2 +- ...13\350\257\225\347\255\226\347\225\245.py" | 8 +- ...44\346\230\223\347\255\226\347\225\245.py" | 2 +- ...44\346\230\223\347\255\226\347\225\245.py" | 2 +- README.md | 326 +++---- ...07\347\272\277\347\255\226\347\225\245.js" | 128 +++ RSI_now_sb_ok.js | 2 +- Shannon's Demon (Copy).js | 52 -- Shannon's Demon.js | 2 +- ...222\214okcoin\344\270\200\350\207\264).js" | 2 +- TableTemplet.js | 2 +- ...01\351\207\221\344\272\244\346\230\223.js" | 2 +- ...60\345\205\245\346\214\201\346\234\211.js" | 2 +- ...26\347\237\277\346\274\224\347\244\272.js" | 46 + js R-Breaker.js | 2 +- ...46\346\210\267\345\205\254\345\274\200.js" | 2 +- ...17\344\272\244\346\230\223\351\207\217.js" | 520 +++++++++++ ...Thrust OKCoin \346\234\237\350\264\247.py" | 2 +- ...\272\223 (\345\205\274\345\256\2712-3).py" | 2 +- ...13\350\257\225\347\211\210\357\274\211.py" | 2 +- ...44\346\230\223\347\261\273\345\272\223.py" | 2 +- ...7\346\240\207\346\241\206\346\236\266).js" | 2 +- ...11\345\217\252\344\271\214\351\270\246.js" | 2 +- ...20\347\240\224\347\251\266\343\200\221.js" | 2 +- ...26\347\225\245\345\217\202\346\225\260.js" | 2 +- ...\265\213\350\257\225 websocket vs rest.js" | 2 +- ...00\347\233\256\345\235\207\350\241\241.js" | 2 +- ...60\261\346\230\257\345\271\262 (Copy).js" | 74 -- ...02\345\260\261\346\230\257\345\271\262.js" | 2 +- ...01\347\240\264\345\211\215\351\253\230.py" | 2 +- ...272\277 (0804\346\233\264\346\226\260).js" | 2 +- ...7\350\264\247\347\211\210) Rev. 161216.js" | 2 +- ...07\350\241\241\347\255\226\347\225\245.js" | 2 +- ...4GetMinStock()\345\207\275\346\225\260.js" | 2 +- "\344\273\267\345\200\2740.418.js" | 2 +- ...63\345\235\207\345\256\232\346\212\225.js" | 2 +- ...42\345\212\250\346\212\245\350\255\246.js" | 2 +- ...\273\267\347\233\221\346\216\247 (CTP).js" | 2 +- ...60\345\214\226\347\255\226\347\225\245.js" | 2 +- ...63\345\217\260\344\275\231\351\242\235.js" | 2 +- ...44\346\230\223\347\263\273\347\273\237.js" | 2 +- ...66\345\267\256\344\273\267\345\233\276.js" | 2 +- ...346\211\230 - \344\271\260\345\205\245.js" | 2 +- ...346\211\230 - \345\215\226\345\207\272.js" | 2 +- ...37\350\264\247\344\270\223\347\224\250.js" | 2 +- ...71\351\224\231\346\250\241\346\235\277.js" | 2 +- ...32\204\346\216\222\345\210\227 - btcdw.py" | 24 + ...07\350\241\241\347\255\226\347\225\245.js" | 2 +- ...5\245\227\347\256\227\346\263\225 V1.2.js" | 807 +++++++++--------- ...7\240\201\346\235\245\350\207\252zero).js" | 2 +- ...25\350\276\271\347\275\221\346\240\274.js" | 170 ++++ ...01\346\261\202\346\214\207\347\202\271.py" | 2 +- ...\254(two platforms hedging-JS) (Copy).js" | 2 +- ...\346\234\254(two platforms hedging-JS).js" | 2 +- ...00\346\234\211\350\256\242\345\215\225.js" | 2 +- ...50\347\216\207\347\273\237\350\256\241.js" | 2 +- ...10\347\272\246\350\277\207\346\273\244.js" | 2 +- ...7\345\215\225\345\212\237\350\203\275).js" | 2 +- ...44\346\230\223\347\261\273\345\272\223.js" | 2 +- ...46\347\273\206\344\277\241\346\201\257.js" | 2 +- ...06\345\217\262\346\237\245\350\257\242.js" | 2 +- ...37\345\215\225\347\263\273\347\273\237.js" | 138 +++ ...27\345\210\251\345\220\210\347\272\246.js" | 33 +- ...43\347\240\201\345\256\236\347\216\260.js" | 2 +- ...345\210\260\346\234\254\345\234\260CSV.py" | 2 +- ...17\350\241\250\346\240\274\357\274\211.js" | 346 -------- ...5\347\244\272\345\256\236\344\276\2131.js" | 2 +- ...45\270\201\347\255\226\347\225\245V0.2.py" | 2 +- ...77\347\224\250\350\214\203\344\276\213.js" | 28 - ...0 \350\241\214\346\220\236\345\256\232.js" | 2 +- ...\274\210python\347\211\210\357\274\211.py" | 2 +- ...44\346\230\223\347\255\226\347\225\245.js" | 73 ++ ...07\347\272\277\347\255\226\347\225\245.js" | 2 +- ...(\344\271\260\344\270\200\344\273\267).js" | 2 +- ...46\346\210\267\347\273\237\350\256\241.js" | 2 +- ...61\345\272\246\344\277\241\346\201\257.js" | 2 +- ...46\346\210\267\344\277\241\346\201\257.js" | 2 +- ...\217\212 Demo \347\250\213\345\272\217.js" | 2 +- ...56\200\345\215\225\347\211\210 (Copy).js" | 76 -- ...25\347\256\200\345\215\225\347\211\210.js" | 2 +- ...10\345\210\251\351\252\214\350\257\201.js" | 2 +- ...73\345\234\272\345\215\226\345\215\225.js" | 2 +- ...67\346\250\241\346\213\237\345\231\250.js" | 362 -------- ...46\345\217\267\347\273\237\350\256\241.js" | 2 +- ...56\344\273\267\347\233\221\346\216\247.js" | 2 +- ...11\345\261\261\345\257\250\345\270\201.js" | 55 ++ ...vs\345\256\236\347\216\260\347\211\210.py" | 2 +- ...346\240\207\347\233\221\346\216\2471.1.js" | 2 +- ...346\240\274\346\257\224\350\276\2031.0.js" | 2 +- ...255\226\347\225\245 (Share 1512580165).js" | 2 +- ...347\225\245 - \345\257\271\346\225\262.js" | 2 +- ...21\351\200\274\350\277\221\345\236\213.js" | 5 +- ...07\346\225\260\351\207\217\345\214\226.js" | 222 +++++ ...12\347\216\207\347\273\237\350\256\241.js" | 2 +- ...1OKCoin\346\234\237\350\264\247-BitVC).js" | 532 ------------ ...\214\201$.CTA\345\207\275\346\225\260).js" | 2 +- ...47\345\270\201\345\256\232\346\212\225.py" | 2 +- ...44\346\230\223\347\261\273\345\272\223.js" | 2 +- ...46\230\223\347\261\273\345\272\223c++.cpp" | 317 ------- ...60\345\215\225\345\215\226\345\215\225.js" | 2 +- ...77\347\224\250\344\276\213\345\255\220.js" | 2 +- ...\345\267\256\344\273\267(by JackConan).js" | 2 +- ...56\344\273\267\345\257\271\345\206\262.js" | 2 +- ...60\347\273\204\345\212\237\350\203\275.js" | 2 +- ...6\350\241\250\346\230\276\347\244\272).js" | 4 +- ...45\346\241\206\346\236\266\357\274\211.js" | 4 +- ...76\350\241\250\345\261\225\347\244\272.js" | 2 +- ...\261\225\347\244\272Python\347\211\210.py" | 2 +- ...73\347\272\277\347\261\273\345\272\223.js" | 2 +- ...14\347\232\204\345\217\230\345\214\226.js" | 2 +- ...07\347\253\240\347\255\226\347\225\245.js" | 2 +- ...45\345\217\243\346\265\213\350\257\225.js" | 2 +- ...32\347\237\245\347\261\273\345\272\223.js" | 2 +- "\347\240\264\345\206\260\350\200\205.js" | 9 +- ...34\346\224\266\345\211\262\346\234\272.js" | 2 +- ...50\346\255\242\346\215\237\347\211\210.js" | 2 +- ...7 \347\210\206\347\240\264\347\211\210.js" | 2 +- ...06\346\236\266\346\250\241\346\235\277.js" | 25 +- ...07\347\272\277\347\255\226\347\225\245.js" | 2 +- ...30\345\234\250\350\266\213\345\212\277.js" | 2 +- ...\345\267\256\344\273\267(by JackConan).js" | 2 +- ...6\240\274 (OK\346\234\237\350\264\247).js" | 476 +++++++++++ ...25\350\276\271\347\275\221\346\240\274.js" | 2 +- ...11\351\246\231\345\206\234\347\211\210.js" | 2 +- ...60\345\215\226\347\244\272\344\276\213.js" | 2 +- ...10\346\201\257\346\216\250\351\200\201.js" | 2 +- ...36\346\227\266\351\231\220\344\273\267.js" | 2 +- ...7\345\217\226\345\221\250K\347\272\277.js" | 2 +- ...on\347\211\210\346\234\254\357\274\211.py" | 2 +- ...15\345\270\201\347\273\237\350\256\241.js" | 2 +- ...24\346\211\230\344\271\260\345\205\245.js" | 21 +- ...24\346\211\230\345\215\226\345\207\272.js" | 5 +- ...345\212\250\346\203\205\345\206\2652.0.js" | 2 +- ...52\344\272\244\346\230\223\346\211\200.js" | 2 +- ...07\350\215\241\347\255\226\347\225\245.js" | 2 +- ...7K\347\272\277\345\221\250\346\234\237.js" | 2 +- ...7\221\346\233\264\346\226\26020180627).js" | 26 +- ...75\346\266\250\346\235\200\350\267\214.py" | 49 ++ ...46\345\217\221\344\273\267\346\240\274.js" | 2 +- ...57\345\276\210\346\234\211\346\225\210.js" | 2 +- ...14\346\200\247\345\210\206\346\236\220.js" | 78 ++ ...6\347\225\245\344\271\213 - Penny Jump.js" | 2 +- ...62\346\234\272\344\270\200\345\217\267.js" | 2 +- ...26\347\225\245\346\241\206\346\236\266.js" | 2 +- 177 files changed, 3648 insertions(+), 3023 deletions(-) delete mode 100644 "2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272 (Copy) (Share 1512130985).js" create mode 100644 "CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.py" create mode 100644 Dual Thrust OKEX Feature.js delete mode 100644 "Dual Thrust_\345\217\214\350\275\250\347\252\201\347\240\264_\347\255\226\347\225\2451.py" create mode 100644 "FCoin\344\272\244\346\230\223\346\211\213\347\273\255\350\264\271\347\273\237\350\256\241(\346\204\237\350\260\242\346\273\241\346\200\273\345\210\206\344\272\253).js" create mode 100644 Iceberg Buy Order.js delete mode 100644 MA_20180107 (Copy).js create mode 100644 Moving Average Strategy in 30 lines.js create mode 100644 "RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.js" delete mode 100644 Shannon's Demon (Copy).js create mode 100644 "fcoin\346\214\226\347\237\277\346\274\224\347\244\272.js" create mode 100644 "okex\345\270\201\345\270\201\346\234\200\345\260\217\344\272\244\346\230\223\351\207\217.js" delete mode 100644 "\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262 (Copy).js" create mode 100644 "\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.py" create mode 100644 "\345\215\225\350\276\271\347\275\221\346\240\274.js" create mode 100644 "\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.js" delete mode 100644 "\345\233\276\350\241\250\346\250\241\346\235\277\357\274\210\345\242\236\345\212\240\347\212\266\346\200\201\346\240\217\350\241\250\346\240\274\357\274\211.js" delete mode 100644 "\345\235\207\347\272\277MA\346\214\207\346\240\207\344\275\277\347\224\250\350\214\203\344\276\213.js" create mode 100644 "\345\237\272\344\272\216CCI\345\221\250\346\234\237\346\200\247\345\214\272\351\227\264\344\272\244\346\230\223\347\255\226\347\225\245.js" delete mode 100644 "\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210 (Copy).js" delete mode 100644 "\345\256\236\347\233\230\350\264\246\346\210\267\346\250\241\346\213\237\345\231\250.js" create mode 100644 "\345\270\201\345\256\211\345\207\272\345\224\256\346\211\200\346\234\211\345\261\261\345\257\250\345\270\201.js" create mode 100644 "\346\214\207\346\225\260\351\207\217\345\214\226.js" delete mode 100644 "\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC).js" delete mode 100644 "\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.cpp" create mode 100644 "\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).js" rename "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180118).js" => "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180627).js" (96%) create mode 100644 "\350\277\275\346\266\250\346\235\200\350\267\214.py" create mode 100644 "\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220.js" diff --git "a/02\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220 (Share 1513097042).js" "b/02\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220 (Share 1513097042).js" index 8d611b3b..8c705818 100644 --- "a/02\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220 (Share 1513097042).js" +++ "b/02\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220 (Share 1513097042).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/63223 +策略出处: https://www.fmz.com/strategy/63223 策略名称: 02顺大势逆小势策略之代码实现及可行性分析 (Share 1513097042) 策略作者: ellajella-0378 策略描述: diff --git "a/03\345\237\272\344\272\216\345\225\206\345\223\201\346\234\237\350\264\247\347\232\204\345\245\227\345\210\251\347\255\226\347\225\245\346\250\241\345\236\213 (Share 1513096985).js" "b/03\345\237\272\344\272\216\345\225\206\345\223\201\346\234\237\350\264\247\347\232\204\345\245\227\345\210\251\347\255\226\347\225\245\346\250\241\345\236\213 (Share 1513096985).js" index 870216fe..76e9bd23 100644 --- "a/03\345\237\272\344\272\216\345\225\206\345\223\201\346\234\237\350\264\247\347\232\204\345\245\227\345\210\251\347\255\226\347\225\245\346\250\241\345\236\213 (Share 1513096985).js" +++ "b/03\345\237\272\344\272\216\345\225\206\345\223\201\346\234\237\350\264\247\347\232\204\345\245\227\345\210\251\347\255\226\347\225\245\346\250\241\345\236\213 (Share 1513096985).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/63221 +策略出处: https://www.fmz.com/strategy/63221 策略名称: 03基于商品期货的套利策略模型 (Share 1513096985) 策略作者: ellajella-0378 策略描述: diff --git "a/10\350\241\214\344\272\272\345\223\201\347\255\226\347\225\245.js" "b/10\350\241\214\344\272\272\345\223\201\347\255\226\347\225\245.js" index 7874e6b2..112a2e70 100644 --- "a/10\350\241\214\344\272\272\345\223\201\347\255\226\347\225\245.js" +++ "b/10\350\241\214\344\272\272\345\223\201\347\255\226\347\225\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/14436 +策略出处: https://www.fmz.com/strategy/14436 策略名称: 10行人品策略 策略作者: 春哥 策略描述: diff --git "a/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272 (Copy) (Share 1512130985).js" "b/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272 (Copy) (Share 1512130985).js" deleted file mode 100644 index 67b11734..00000000 --- "a/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272 (Copy) (Share 1512130985).js" +++ /dev/null @@ -1,182 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/61398 -策略名称: 2014年的简易短线机器人 (Copy) (Share 1512130985) -策略作者: ellajella-0378 -策略描述: - -**策略的介绍** - -策略分享地址: -https://www.botvs.com/strategy/1088 -这个策略是我做虚拟货币以来的主要策略,后面经过不断完善和修改,复杂了很多,但主要思想并没有改变,分享的这个版本是无明显bug的 最初版本,最为简单清晰,没有仓位管理,每次交易都是满仓,没有卡死后重启等等,但也足够说明问题。 -策略从2014年8月运行,直到今年年初交易所收手续费。期间运行的还算很好,亏损的时间很少。资金从最初的200元跑到了80比特币。具体的过程可以看[小草的新浪博客](http://blog.sina.com.cn/u/2389357153)里[虚拟货币自动化交易之路](http://blog.sina.com.cn/s/blog_8e6ab2610102v6sq.html)系列文章。 - -**为什么分享这个策略** - -1.交易所收取手续费后,几乎杀死了所有的高频策略,我的也不例外。但策略改改也许还能用,大家可以研究一下。 -2.好久没有分享东西了,这篇文章早就想写了。 -3.和大家共同交流学习。 - -**策略的原理** - -这个策略原理极为简单,可以理解为准高频的做市策略,各位看了之后可能想打人,这都能赚钱,当时几乎谁都能写出来。我开始也没预料到它能这么有效,可见心中有想法要赶紧付出实践,说不一定有意外之喜。在比特币机器人初兴的2014年,写出赚钱的策略太容易了。 -和所有的高频策略一样,本策略也是基于orderbook,下图就是一个典型的比特币交易所的订单分布, - https://dn-filebox.qbox.me/0d8ec18c831404d3d1c19e17299c78017abcfd48.png -可以看到左侧是买单,显示了不同价格的挂单数量,右侧是卖单。可以想象如果一个人要买入比特币,如果不想挂单等待的话,只能选择吃单,如果他的单子比较多,会使得卖单挂单大量成交,对价格造成冲击,但是这种冲击一般不会一直持续,还有人想吃单卖出,价格在极短时间很可能还会恢复,反过来理解有人要卖币也类似。 -以图中的挂单为例,如果要直接买入5个币,那么价格会达到10377,在这时如果有人要直接卖出5个币,价格会达到10348,这个空间就是利润空间.策略会在稍低于10377的价格挂单,如10376.99,同时会以稍高于10348的价格买入,如10348.01,这是如果刚才的情况发生了,显然就会赚到其中的差价。虽然不会每次都如此完美,但在概率的作用下,赚钱的几率实际高得惊人。 -以现在策略的参数讲解一下具体操作,这个参数当然无法使用了,仅作一个说明。它会向上寻找累计卖挂单量为8个币的价格,这里是10377,那么此时的卖价就是这个价格减去0.01(减去多少可以是随机的),同理向下寻找累计买挂单为8个币,这里是10348,那么此时的卖价就是10348.01,此时买卖价的差价是10376.99-10348.01=28.98,大于策略预设的差价1.5,就以这两个价格挂单等待成交,如果价差小于1.5,也会找一个价格进行挂单,如盘口价格加减10,等待捡漏(更合适的应该是继续往下找跟多的深度)。 - -**进一步的说明** - -1. 没有钱或币了怎么办? -这种情况在我的钱较少是十分普遍,大多数时候只挂一边的单子,但不是大问题。其实可以加入币钱平衡的逻辑,但在平衡的过程难免产生损失,毕竟每一次的成交都是概率的垂青,我选择保持单边等待成交,当然这样也浪费了另一边的成交机会。 -2. 仓位是如何管理的? -刚开始都是满仓买入卖出,后来根据不同的参数分为不同的组,不会一次完全成交。 -3. 没有止损吗? -策略有完整的买卖挂单的逻辑,我认为不需要止损(可以讨论),还有就是概率的垂青,成交就是机会,止损可惜了。 -4. 如何调整为赚币的策略? -此时的参数是对称的,即向上8个币的累计卖单,向下8个币的累计买单,稍微不平衡一下,比如向上改为15个币的累计卖单,使得卖币机会更难得,有更大的几率会以更低的价格接回来,这样就会赚币,反过来就赚钱。实际上前期策略如此有效,币和钱都是增加的。 - -**代码讲解** - -完整的代码可以见我在www.botvs.com得策略分享,这里只讲解核心逻辑函数。在没有改动的情况下,在botvs自带的模拟盘竟然运转完全正常,这是一个3年多前的策略,平台还支持到现在,太让人感动了。 -首先是获取买卖价函数GetPrice(),需要获取订单深度信息,注意不同平台的订单深度信息长度不同,以及即使遍历了所有订单仍然没有所需要的量的情况(在后期许多0.01的网格挂单会导致这种情况),调用是GetPrice('Buy')就是获取买价。 -``` -function GetPrice(Type) { - //_C()是平台的容错函数 - var depth=_C(exchange.GetDepth); - var amountBids=0; - var amountAsks=0; - //计算买价,获取累计深度达到预设的价格 - if(Type=="Buy"){ - for(var i=0;i<20;i++){ - amountBids+=depth.Bids[i].Amount; - //参数floatamountbuy是预设的累计深度 - if (amountBids>floatamountbuy){ - //稍微加0.01,使得订单排在前面 - return depth.Bids[i].Price+0.01;} - } - } - //同理计算卖价 - if(Type=="Sell"){ - for(var j=0; j<20; j++){ - amountAsks+=depth.Asks[j].Amount; - if (amountAsks>floatamountsell){ - return depth.Asks[j].Price-0.01;} - } - } - //遍历了全部深度仍未满足需求,就返回一个价格,以免出现bug - return depth.Asks[0].Price -} -``` -每个循环的主函数onTick(),这里定的循环时间3.5s,每次循环都会把原来的单子撤销,重新挂单,越简单越不会遇到bug. -``` -function onTick() { - var buyPrice = GetPrice("Buy"); - var sellPrice= GetPrice("Sell"); - //diffprice是预设差价,买卖价差如果小于预设差价,就会挂一个相对更深的价格 - if ((sellPrice - buyPrice) <= diffprice){ - buyPrice-=10; - sellPrice+=10;} - //把原有的单子全部撤销,实际上经常出现新的价格和已挂单价格相同的情况,此时不需要撤销 - CancelPendingOrders() - //获取账户信息,确定目前账户存在多少钱和多少币 - var account=_C(exchange.GetAccount); - //可买的比特币量,_N()是平台的精度函数 - var amountBuy = _N((account.Balance / buyPrice-0.1),2); - //可卖的比特币量,注意到没有仓位的限制,有多少就买卖多少,因为我当时的钱很少 - var amountSell = _N((account.Stocks),2); - if (amountSell > 0.02) { - exchange.Sell(sellPrice,amountSell);} - if (amountBuy > 0.02) { - exchange.Buy(buyPrice, amountBuy);} - //休眠,进入下一轮循环 - Sleep(sleeptime); -} -``` - -**尾巴** - -整个程序也就40多行,看上去十分简单,但当时也花了我一个多星期,这还是在botvs平台上情况下。最大的优势还是起步早,在2014年,市场上以搬砖为主,网格和抢盘口的高频也不多,使得策略如鱼得水,后来竞争不可避免越来越激烈,我的钱也越来越多,面临的挑战很多,每隔一段时间都要进行较大的改动来应对,但总体还算顺利。在交易平台不收取手续费的情况下,是程序化交易的天堂,散户因为不收手续费跟倾向于操作,为高频和套利提供了空间,这一切也基本随着动辄0.1-0.2%的双向手续费终结了,不仅是自己被收费的问题,而是整个市场活跃度下降。 -但不需要高频的量化策略任然有很大的空间。 - - -参数 默认值 描述 ---------------- ------ ---- -sleeptime 3500 休眠时间 -floatamountbuy 8 买单深度 -floatamountsell 8 卖单高度 -diffprice 1.5 套利差价 -*/ - -/* -就是我刚开始编写机器人的源代码,几乎没有改动,参数也是原来的参数。这个版本的程序有许多 -需要改进的地方,但即使如此,它也当时表现除了惊人的盈利能力,在我本金不多时,不加杠杆平 -均每天盈利在5%左右。当然无论从哪一方面,它都不适应今天的市场。 -我同时也发了一篇文章在社区,大家可以看看。 -by 小草 -*/ - -//稍微改了一下,用了平台的容错函数_C(),和精度函数_N(). -//取消全部订单 -function CancelPendingOrders() { - var orders = _C(exchange.GetOrders); - for (var j = 0; j < orders.length; j++) { - exchange.CancelOrder(orders[j].Id, orders[j]);} -} - -//计算将要下单的价格 -function GetPrice(Type) { - var depth=_C(exchange.GetDepth); - var amountBids=0; - var amountAsks=0; - //计算买价,获取累计深度达到预设的价格 - if(Type=="Buy"){ - for(var i=0;i<20;i++){ - amountBids+=depth.Bids[i].Amount; - //floatamountbuy就是预设的累计买单深度 - if (amountBids>floatamountbuy){ - //稍微加0.01,使得订单排在前面 - return depth.Bids[i].Price+0.01;} - } - } - //同理计算卖价 - if(Type=="Sell"){ - for(var j=0; j<20; j++){ - amountAsks+=depth.Asks[j].Amount; - if (amountAsks>floatamountsell){ - return depth.Asks[j].Price-0.01;} - } - } - //遍历了全部深度仍未满足需求,就返回一个价格,以免出现bug - return depth.Asks[0].Price -} - -function onTick() { - var buyPrice = GetPrice("Buy"); - var sellPrice= GetPrice("Sell"); - //买卖价差如果小于预设值diffprice,就会挂一个相对更深的价格 - if ((sellPrice - buyPrice) <= diffprice){ - buyPrice-=10; - sellPrice+=10;} - //把原有的单子全部撤销,实际上经常出现新的价格和已挂单价格相同的情况,此时不需要撤销 - CancelPendingOrders() - //获取账户信息,确定目前账户存在多少钱和多少币 - var account=_C(exchange.GetAccount); - //可买的比特币量 - var amountBuy = _N((account.Balance / buyPrice-0.1),2); - //可卖的比特币量,注意到没有仓位的限制,有多少就买卖多少,因为我当时的钱很少 - var amountSell = _N((account.Stocks),2); - if (amountSell > 0.02) { - exchange.Sell(sellPrice,amountSell);} - if (amountBuy > 0.02) { - exchange.Buy(buyPrice, amountBuy);} - //休眠,进入下一轮循环 - Sleep(sleeptime); -} - -function main() { - while (true) { - onTick(); - } -} diff --git "a/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.js" "b/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.js" index 855f1add..3899b51a 100644 --- "a/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.js" +++ "b/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/1088 +策略出处: https://www.fmz.com/strategy/1088 策略名称: 2014年的简易短线机器人 策略作者: botvsing 策略描述: @@ -126,8 +126,7 @@ function CancelPendingOrders() { } //计算将要下单的价格 -function GetPrice(Type) { - var depth=_C(exchange.GetDepth); +function GetPrice(Type,depth) { var amountBids=0; var amountAsks=0; //计算买价,获取累计深度达到预设的价格 @@ -153,8 +152,9 @@ function GetPrice(Type) { } function onTick() { - var buyPrice = GetPrice("Buy"); - var sellPrice= GetPrice("Sell"); + var depth=_C(exchange.GetDepth); + var buyPrice = GetPrice("Buy",depth); + var sellPrice= GetPrice("Sell",depth); //买卖价差如果小于预设值diffprice,就会挂一个相对更深的价格 if ((sellPrice - buyPrice) <= diffprice){ buyPrice-=10; diff --git "a/796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.js" "b/796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.js" index 816beaed..3b87d901 100644 --- "a/796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.js" +++ "b/796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/3648 +策略出处: https://www.fmz.com/strategy/3648 策略名称: 796期货反手加倍算法 策略作者: Zero 策略描述: diff --git "a/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.js" "b/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.js" index cce14485..2f29c36a 100644 --- "a/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.js" +++ "b/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/4 +策略出处: https://www.fmz.com/strategy/4 策略名称: API 测试新手入门 策略作者: Zero 策略描述: diff --git "a/BTC-LTC \345\234\260\345\235\200\347\233\221\350\247\206, \347\237\255\344\277\241\351\200\232\347\237\245.js" "b/BTC-LTC \345\234\260\345\235\200\347\233\221\350\247\206, \347\237\255\344\277\241\351\200\232\347\237\245.js" index 24488cc9..2e7366a4 100644 --- "a/BTC-LTC \345\234\260\345\235\200\347\233\221\350\247\206, \347\237\255\344\277\241\351\200\232\347\237\245.js" +++ "b/BTC-LTC \345\234\260\345\235\200\347\233\221\350\247\206, \347\237\255\344\277\241\351\200\232\347\237\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/1295 +策略出处: https://www.fmz.com/strategy/1295 策略名称: BTC-LTC 地址监视, 短信通知 策略作者: Zero 策略描述: diff --git "a/BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.js" "b/BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.js" index 15412488..81d98300 100644 --- "a/BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.js" +++ "b/BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/40289 +策略出处: https://www.fmz.com/strategy/40289 策略名称: BitMEX 简单测试 策略作者: Tony123 策略描述: diff --git "a/BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.js" "b/BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.js" index 17c92497..2d989f74 100644 --- "a/BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.js" +++ "b/BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/59120 +策略出处: https://www.fmz.com/strategy/59120 策略名称: BotVS 商品期货 量化 测试入门 策略 策略作者: 小小梦 策略描述: diff --git "a/C++ API\350\260\203\347\224\250\344\276\213\345\255\220.cpp" "b/C++ API\350\260\203\347\224\250\344\276\213\345\255\220.cpp" index d6e4d235..1b742b1d 100644 --- "a/C++ API\350\260\203\347\224\250\344\276\213\345\255\220.cpp" +++ "b/C++ API\350\260\203\347\224\250\344\276\213\345\255\220.cpp" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/61533 +策略出处: https://www.fmz.com/strategy/61533 策略名称: C++ API调用例子 策略作者: Zero 策略描述: diff --git "a/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" "b/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" index 11d5c650..bc167d36 100644 --- "a/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" +++ "b/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/17289 +策略出处: https://www.fmz.com/strategy/17289 策略名称: CTP商品期货多品种海龟交易策略 策略作者: Zero 策略描述: diff --git "a/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.py" "b/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.py" new file mode 100644 index 00000000..bffeae2b --- /dev/null +++ "b/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.py" @@ -0,0 +1,328 @@ +''' +策略出处: https://www.fmz.com/strategy/101399 +策略名称: CoinPark交易所通用协议 6.27 16:00 更新 关闭了SSL验证 +策略作者: botvsing +策略描述: + +## CoinPark通用协议Python2版本 +用途:可以使BotVs支持coinpark.cc交易所 +不知道什么是通用协议?https://www.botvs.com/bbs-topic/1052 +可以把通用协议当成普通机器人,运行在BotVs模拟盘即可,不收取费用 +也可以把代码保存起来,在服务器上用python运行 +运行地址 + + http://127.0.0.1:6667 +也可以在运行时指定端口 + + python coinpark.py 8866 +在托管者所在服务器后台运行即可: + + nohup python coinpark.py & +交易所配置如下: +![iamge](https://dn-filebox.qbox.me/c1456599386e597f2966f67b49c7102bab857fef.png) +已经经过部分人的测试,欢迎反馈 +2018.6.26 18:46 更新,修改了Bug + +''' + +#!/usr/bin/env python +# -*- coding: utf-8 -*- +''' +CoinPark通用协议,使用Python2.7 +运行地址:http://127.0.0.1:6667,端口可指定 +由于账户没资产,未作详细测试,欢迎反馈Bug +QQ:1051804485 +反馈地址:https://www.botvs.com/bbs-topic/1963 +2018.6.26 15:57 更新,修改了Bug +可以把通用协议当成普通机器人,运行在BotVs模拟盘即可,不收取费用 +为了使用IO函数,需要重载exchange里的rpc方法,js的例子如下: +exchange.rpc = function(path, obj) { + return exchange.IO("api","POST", path, "obj="+escape(JSON.stringify(obj))); +} +function main() { + Log(exchange.rpc("/transfer", {cmd: "transfer/assets", body: {select:1}})); +} +''' +from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer +import json +import urllib +import urllib2 +import time +import hmac +import hashlib +import random +import ssl +ssl._create_default_https_context = ssl._create_unverified_context + +def httpGet(url): + headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'} + req = urllib2.Request(url,headers=headers) + response = urllib2.urlopen(req) + return json.loads(response.read()) + +def getsign(data,secret): + result = hmac.new(secret.encode("utf-8"), data.encode("utf-8"), hashlib.md5).hexdigest() + return result + +def httpPostWithSign(url, cmds, api_key, api_secret): + headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'} + s_cmds = json.dumps(cmds) + sign = getsign(s_cmds,api_secret) + req = urllib2.Request(url, urllib.urlencode({'cmds': s_cmds, 'apikey': api_key,'sign':sign}), headers=headers) + response = urllib2.urlopen(req) + return json.loads(response.read()) + +class MyExchange: + + market_url = "https://api.coinpark.cc/v1/mdata" + trade_url = "https://api.coinpark.cc/v1" + kline_period = {1:'1min', 3:'3min', 5:'5min', 15:'15min', 30:'30min',\ + 60:'1hour', 120:'2hour', 240:'4hour', 360:'6hour', \ + 60*12:'12hour', 60*24:'day', 60*24*7:'week'} + @staticmethod + def GetTicker(symbol): + url = MyExchange.market_url + "?cmd=ticker&pair=" + symbol + raw_data = httpGet(url) + if 'error' in raw_data.keys(): + return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)} + ret_data = {"data": {"time": raw_data['result']['timestamp'], "buy": raw_data['result']['buy'],\ + "sell": raw_data['result']['sell'], "last": raw_data['result']['last'],\ + "high": raw_data['result']['high'], "low": raw_data['result']['low'],\ + "vol": raw_data['result']['vol']}} + return ret_data + @staticmethod + def GetDepth(symbol): + url = MyExchange.market_url + "?cmd=depth&size=10&pair=" + symbol + raw_data = httpGet(url) + if 'error' in raw_data.keys(): + return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)} + ret_data = {"data" : {"time" : raw_data['result']['update_time'], "asks" : [], "bids" : []}} + for bid in raw_data['result']['bids']: + ret_data['data']['bids'].append([bid['price'],bid['volume']]) + for ask in raw_data['result']['asks']: + ret_data['data']['asks'].append([ask['price'],ask['volume']]) + return ret_data + @staticmethod + def GetRecords(symbol, period): + url = MyExchange.market_url + "?cmd=kline&size=200&period=%s&pair="%MyExchange.kline_period[period] + symbol + raw_data = httpGet(url) + if 'error' in raw_data.keys(): + return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)} + ret_data = {"data": []} + for kline in raw_data['result']: + ret_data['data'].append([kline['time'], kline['open'], kline['high'],\ + kline['low'], kline['close'], kline['vol']]) + return ret_data + @staticmethod + def GetTrades(symbol): + url = MyExchange.market_url + "?cmd=deals&size=50&pair=" + symbol + raw_data = httpGet(url) + if 'error' in raw_data.keys(): + return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)} + ret_data = {"data":[]} + for trade in raw_data["result"]: + ret_data["data"].append({"id":trade["id"], "time":trade["time"], \ + "price":trade["price"], "amount":trade["amount"],"type":"buy" if int(trade["side"])==1 else "sell"}) + return ret_data + @staticmethod + def GetAccount(api_key, api_secret): + url = MyExchange.trade_url + "/transfer" + cmds = [{"cmd": "transfer/assets", "body": {"select":1}}] + raw_data = httpPostWithSign(url, cmds, api_key, api_secret) + if 'error' in raw_data.keys(): + return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)} + ret_data = {"data": []} + if "assets_list" in raw_data["result"][0]["result"].keys(): + for asset in raw_data["result"][0]["result"]["assets_list"]: + ret_data["data"].append({"currency":asset["coin_symbol"], \ + "free":asset["balance"], "frozen":asset["freeze"]}) + ret_data["raw"] = raw_data["result"] + return ret_data + @staticmethod + def Trade(api_key, api_secret, pair, order_type, order_side, price, amount): + url = MyExchange.trade_url + "/orderpending" + cmds = [{ + 'cmd':"orderpending/trade", + 'index': random.randint(0,2000), + 'body':{ + 'pair':pair, + 'account_type':0, + 'order_type':order_type, + 'order_side':order_side, + 'price':price, + 'amount':amount, + } + }] + if order_type==1: + cmds['money'] = amount + raw_data = httpPostWithSign(url, cmds, api_key, api_secret) + if 'error' in raw_data.keys(): + return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)} + ret_data = {"data": {'id':raw_data['result'][0]['result']}} + return ret_data + @staticmethod + def CancelOrder(api_key, api_secret, orders_id): + url = MyExchange.trade_url + "/orderpending" + cmds = [{ + 'cmd':"orderpending/cancelTrade", + 'index': random.randint(0,2000), + 'body':{'orders_id':orders_id} + }] + raw_data = httpPostWithSign(url, cmds, api_key, api_secret) + if 'error' in raw_data.keys(): + return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)} + ret_data = {"data":True} + try: + result = raw_data['result'].encode('utf8') + except: + ret_data = {"data":False} + ret_data['raw'] = raw_data + return ret_data + @staticmethod + def GetOrder(api_key, api_secret, orders_id): + url = MyExchange.trade_url + "/orderpending" + cmds = [{ + 'cmd':"orderpending/order", + 'index': random.randint(0,2000), + 'body':{'id':orders_id} + }] + raw_data = httpPostWithSign(url, cmds, api_key, api_secret) + if 'error' in raw_data.keys(): + return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)} + status = 'open' + if not raw_data['result'][0]['result']: + return {"error":'Id not found'} + if int(raw_data['result'][0]['result']['status'])==3: + status = 'closed' + if int(raw_data['result'][0]['result']['status'])==5: + status = 'canceled' + ret_data = { + "data": { + "id": raw_data['result'][0]['result']['id'], + "amount": raw_data['result'][0]['result']['amount'], + "price": raw_data['result'][0]['result']['price'], + "status": status, + "deal_amount": raw_data['result'][0]['result']['deal_amount'], + "type": "buy" if raw_data['result'][0]['result']['order_side']==1 else "sell", + "avg_price": 0, + } + } + ret_data['raw'] = raw_data + return ret_data + @staticmethod + def GetOrders(api_key, api_secret, pair): + url = MyExchange.trade_url + "/orderpending" + cmds = [{ + 'cmd':"orderpending/orderPendingList", + 'body':{ + 'pair':pair, + 'page':1, + 'size':50 + } + }] + raw_data = httpPostWithSign(url, cmds, api_key, api_secret) + if 'error' in raw_data.keys(): + return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)} + ret_data = {"data":[]} + for order in raw_data["result"][0]["result"]["items"]: + status = 'open' + if int(order['status'])==3: + status = 'closed' + if int(order['status'])==5: + status = 'canceled' + ret_data["data"].append( + { + "id": order['id'], + "amount": order['amount'], + "price": order['price'], + "status": status, + "deal_amount": order['deal_amount'], + "type": "buy" if order['order_side']==1 else "sell", + } + ) + ret_data['raw'] = raw_data + return ret_data + @staticmethod + def IO(api_key, api_secret, path, params): + url = MyExchange.trade_url + path + cmds = [json.loads(str(urllib.unquote(params['obj'])))] + raw_data = httpPostWithSign(url, cmds, api_key, api_secret) + if 'error' in raw_data.keys(): + return {'error':json.dumps(raw_data['error'],encoding="utf8", ensure_ascii=False)} + return {"data":raw_data} + +class Server(BaseHTTPRequestHandler): + + def do_HEAD(self): + self.send_response(200) + self.send_header('Content-type', 'application/json') + self.end_headers() + + def do_POST(self): + + self.data_string = self.rfile.read(int(self.headers['Content-Length'])) + data =json.loads(self.data_string.replace("'", '"')) + sent_data = {} + if data['method'] == "ticker": + symbol = data['params']['symbol'].upper() + sent_data = MyExchange.GetTicker(symbol) + elif data['method'] == "depth": + symbol = data['params']['symbol'].upper() + sent_data = MyExchange.GetDepth(symbol) + elif data['method'] == "records": + symbol = data['params']['symbol'].upper() + period = data['params']['period'] + sent_data = MyExchange.GetRecords(symbol, int(period)) + elif data['method'] == "trades": + symbol = data['params']['symbol'].upper() + sent_data = MyExchange.GetTrades(symbol) + elif data['method'] == "accounts": + access_key = data["access_key"] + secret_key = data["secret_key"] + sent_data = MyExchange.GetAccount(access_key, secret_key) + elif data['method'] == "trade": + access_key = data["access_key"] + secret_key = data["secret_key"] + pair = data['params']['symbol'].upper() + order_side = 1 if data['params']['type'] == 'buy' else 2 + price = data['params']['price'] + order_type = 2 if price > 0 else 1 + amount = data['params']['amount'] + sent_data = MyExchange.Trade(access_key, secret_key, pair, order_type, order_side, price, amount) + elif data['method'] == "cancel": + access_key = data["access_key"] + secret_key = data["secret_key"] + orders_id = int(data['params']['id']) + sent_data = MyExchange.CancelOrder(access_key, secret_key, orders_id) + elif data['method'] == "order": + access_key = data["access_key"] + secret_key = data["secret_key"] + orders_id = int(data['params']['id']) + sent_data = MyExchange.GetOrder(access_key, secret_key, orders_id) + elif data['method'] == "orders": + access_key = data["access_key"] + secret_key = data["secret_key"] + pair = data['params']['symbol'].upper() + sent_data = MyExchange.GetOrders(access_key, secret_key, pair) + elif data['method'][:2] == "__": + access_key = data["access_key"] + secret_key = data["secret_key"] + path = data["method"].split('_')[-1] + params = data["params"] + sent_data = MyExchange.IO(access_key, secret_key, path, params) + + self.do_HEAD() + self.wfile.write(json.dumps(sent_data)) + +def run(server_class=HTTPServer, handler_class=Server, port=6667): + server_address = ('', port) + httpd = server_class(server_address, handler_class) + print 'Starting http server...' + httpd.serve_forever() + +if __name__ == "__main__": + from sys import argv + if len(argv) == 2: + run(port=int(argv[1])) + else: + run() diff --git a/Convert_Record_Cycle.js b/Convert_Record_Cycle.js index ba74a3e6..201c3e45 100644 --- a/Convert_Record_Cycle.js +++ b/Convert_Record_Cycle.js @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/37678 +策略出处: https://www.fmz.com/strategy/37678 策略名称: Convert_Record_Cycle 策略作者: jxc6698 策略描述: diff --git a/Dual Thrust OKEX Feature.js b/Dual Thrust OKEX Feature.js new file mode 100644 index 00000000..83574e98 --- /dev/null +++ b/Dual Thrust OKEX Feature.js @@ -0,0 +1,239 @@ +/* +策略出处: https://www.fmz.com/strategy/103247 +策略名称: Dual Thrust OKEX Feature +策略作者: botvsing +策略描述: + +Check the url below to learn abount Dual Thrust Strategy. + +https://www.quantconnect.com/tutorials/strategy-library/dual-thrust-trading-algorithm + + +参数 默认值 描述 +--------------- ----- ------------------------------------------ +ContractTypeIdx 0 Contract Name: this_week|next_week|quarter +MarginLevelIdx 0 Margin Level: 10|20 +NPeriod 4 Period included +Ks 0.5 Up-track ratio +Kx 0.5 Down-track ratio +AmountOP true Open positon amount +Interval 2000 retry interval +LoopInterval 3 loop time(second) +PeriodShow 500 total K-line number to show for chart +*/ + +var ChartCfg = { + __isStock: true, + title: { + text: 'Dual Thrust Up-Down Track' + }, + yAxis: { + plotLines: [{ + value: 0, + color: 'red', + width: 2, + label: { + text: 'Up Track', + align: 'center' + }, + }, { + value: 0, + color: 'green', + width: 2, + label: { + text: 'Down Track', + align: 'center' + }, + }] + }, + series: [{ + type: 'candlestick', + name: 'current cycle', + id: 'primary', + data: [] + }, { + type: 'flags', + onSeries: 'primary', + data: [], + }] +}; + +var STATE_IDLE = 0; +var STATE_LONG = 1; +var STATE_SHORT = 2; +var State = STATE_IDLE; + +var LastBarTime = 0; +var UpTrack = 0; +var BottomTrack = 0; +var chart = null; +var InitAccount = null; +var LastAccount = null; +var Counter = { + w: 0, + l: 0 +}; + +function _N(v) { + return Decimal(v).toSD(4, 1).toNumber(); +} + +function GetPosition(posType) { + var positions = exchange.GetPosition(); + for (var i = 0; i < positions.length; i++) { + if (positions[i].Type === posType) { + return [positions[i].Price, positions[i].Amount]; + } + } + return [0, 0]; +} + +function CancelPendingOrders() { + while (true) { + var orders = exchange.GetOrders(); + for (var i = 0; i < orders.length; i++) { + exchange.CancelOrder(orders[i].Id); + Sleep(Interval); + } + if (orders.length === 0) { + break; + } + } +} + +function Trade(currentState, nextState) { + var pfn = nextState === STATE_LONG ? exchange.Buy : exchange.Sell; + if (currentState !== STATE_IDLE) { + exchange.SetDirection(currentState === STATE_LONG ? "closebuy" : "closesell"); + while (true) { + var amount = GetPosition(currentState === STATE_LONG ? PD_LONG : PD_SHORT)[1]; + if (amount === 0) { + break; + } + // pfn(amount); + pfn(nextState === STATE_LONG ? _C(exchange.GetTicker).Sell * 1.001 : _C(exchange.GetTicker).Buy * 0.999, amount); + Sleep(Interval); + CancelPendingOrders(); + } + var account = exchange.GetAccount(); + + if (account.Stocks > LastAccount.Stocks) { + Counter.w++; + } else { + Counter.l++; + } + + LogProfit(_N(account.Stocks - InitAccount.Stocks), "Profit rate:", _N((account.Stocks - InitAccount.Stocks) * 100 / InitAccount.Stocks) + '%'); + LastAccount = account; + } + exchange.SetDirection(nextState === STATE_LONG ? "buy" : "sell"); + while (true) { + var pos = GetPosition(nextState === STATE_LONG ? PD_LONG : PD_SHORT); + if (pos[1] >= AmountOP) { + Log("Average Price", pos[0], "amount:", pos[1]); + break; + } + // pfn(AmountOP-pos[1]); + pfn(nextState === STATE_LONG ? _C(exchange.GetTicker).Sell * 1.001 : _C(exchange.GetTicker).Buy * 0.999, AmountOP-pos[1]); + Sleep(Interval); + CancelPendingOrders(); + } +} + +function onTick(exchange) { + var records = exchange.GetRecords(); + if (!records || records.length <= NPeriod) { + return; + } + var Bar = records[records.length - 1]; + if (LastBarTime !== Bar.Time) { + var HH = TA.Highest(records, NPeriod, 'High'); + var HC = TA.Highest(records, NPeriod, 'Close'); + var LL = TA.Lowest(records, NPeriod, 'Low'); + var LC = TA.Lowest(records, NPeriod, 'Close'); + + var Range = Math.max(HH - LC, HC - LL); + + UpTrack = _N(Bar.Open + (Ks * Range)); + DownTrack = _N(Bar.Open - (Kx * Range)); + if (LastBarTime > 0) { + var PreBar = records[records.length - 2]; + chart.add(0, [PreBar.Time, PreBar.Open, PreBar.High, PreBar.Low, PreBar.Close], -1); + } else { + for (var i = Math.min(records.length, NPeriod * 3); i > 1; i--) { + var b = records[records.length - i]; + chart.add(0, [b.Time, b.Open, b.High, b.Low, b.Close]); + } + } + chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close]); + ChartCfg.yAxis.plotLines[0].value = UpTrack; + ChartCfg.yAxis.plotLines[1].value = DownTrack; + ChartCfg.subtitle = { + text: 'Up Track: ' + UpTrack + ' Down Track: ' + DownTrack + }; + chart.update(ChartCfg); + chart.reset(PeriodShow); + + LastBarTime = Bar.Time; + } else { + chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close], -1); + } + + LogStatus("Price:", Bar.Close, "Up:", UpTrack, "Down:", DownTrack, "Wins: ", Counter.w, "Losses:", Counter.l, "Date:", new Date()); + var msg; + if (State === STATE_IDLE || State === STATE_SHORT) { + if (Bar.Close >= UpTrack) { + msg = 'Long Price: ' + Bar.Close + ' Up Track:' + UpTrack; + Log(msg); + Trade(State, STATE_LONG); + State = STATE_LONG; + chart.add(1, {x:Bar.Time, color: 'red', shape: 'flag', title: 'Long', text: msg}); + } + } + + if (State === STATE_IDLE || State === STATE_LONG) { + if (Bar.Close <= DownTrack) { + msg = 'Short Price: ' + Bar.Close + ' Down Track:' + DownTrack; + Log(msg); + Trade(State, STATE_SHORT); + chart.add(1, {x:Bar.Time, color: 'green', shape: 'circlepin', title: 'Short', text: msg}); + State = STATE_SHORT; + } + } +} + +function onexit() { + var pos = exchange.GetPosition(); + if (pos.length > 0) { + Log("Warning, has positions when exiting", pos); + } +} + +function main() { + if (exchange.GetName() !== 'Futures_OKCoin') { + throw "Only support OKEX features"; + } + exchange.SetRate(1); + exchange.SetContractType(["this_week", "next_week", "quarter"][ContractTypeIdx]); + exchange.SetMarginLevel([10, 20][MarginLevelIdx]); + + if (exchange.GetPosition().length > 0) { + throw "Can't have Positions when start.";} + + CancelPendingOrders(); + + InitAccount = LastAccount = exchange.GetAccount(); + LoopInterval = Math.min(1, LoopInterval); + Log('Exchange Name:', exchange.GetName(), InitAccount); + LogStatus("Ready..."); + + LogProfitReset(); + chart = Chart(ChartCfg); + chart.reset(); + + LoopInterval = Math.max(LoopInterval, 1); + while (true) { + onTick(exchange); + Sleep(LoopInterval * 1000); + } +} diff --git "a/Dual Thrust OKCoin \346\234\237\350\264\247.js" "b/Dual Thrust OKCoin \346\234\237\350\264\247.js" index f3cad5a6..630f932c 100644 --- "a/Dual Thrust OKCoin \346\234\237\350\264\247.js" +++ "b/Dual Thrust OKCoin \346\234\237\350\264\247.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/12101 +策略出处: https://www.fmz.com/strategy/12101 策略名称: Dual Thrust OKCoin 期货 策略作者: Zero 策略描述: @@ -120,7 +120,8 @@ function Trade(currentState, nextState) { if (amount === 0) { break; } - pfn(amount); + // pfn(amount); + pfn(nextState === STATE_LONG ? _C(exchange.GetTicker).Sell * 1.001 : _C(exchange.GetTicker).Buy * 0.999, amount); Sleep(Interval); CancelPendingOrders(); }; @@ -142,7 +143,8 @@ function Trade(currentState, nextState) { Log("持仓均价", pos[0], "数量:", pos[1]); break; } - pfn(AmountOP-pos[1]); + // pfn(AmountOP-pos[1]); + pfn(nextState === STATE_LONG ? _C(exchange.GetTicker).Sell * 1.001 : _C(exchange.GetTicker).Buy * 0.999, AmountOP-pos[1]); Sleep(Interval); CancelPendingOrders(); } diff --git "a/Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.js" "b/Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.js" index 44ade495..4601ce97 100644 --- "a/Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.js" +++ "b/Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/13011 +策略出处: https://www.fmz.com/strategy/13011 策略名称: Dual Thrust 商品期货 策略作者: Zero 策略描述: diff --git "a/Dual Thrust_\345\217\214\350\275\250\347\252\201\347\240\264_\347\255\226\347\225\2451.py" "b/Dual Thrust_\345\217\214\350\275\250\347\252\201\347\240\264_\347\255\226\347\225\2451.py" deleted file mode 100644 index ab594437..00000000 --- "a/Dual Thrust_\345\217\214\350\275\250\347\252\201\347\240\264_\347\255\226\347\225\2451.py" +++ /dev/null @@ -1,200 +0,0 @@ -''' -策略出处: https://www.botvs.com/strategy/22983 -策略名称: Dual Thrust_双轨突破_策略1 -策略作者: 太极 -策略描述: - -策略越简单越好 - -''' - -#!/usr/local/bin/python -#-*- coding: UTF-8 -*- -Enter_cycle=5 #周期数据 - -Open_price=0 #开盘价平均价 -High_price=0 #最高价平均价 -Low_price=0 #最低价平均价 -Close_price=0 #收盘价平均价 - -N1Open_price=0 #开盘价 -N1High_price=0 #最高价 -N1Low_price=0 #最低价 -N1Close_price=0 #收盘价 - -# import time -# import datetime -# def out_time(x_time): #获取当前时间 前10分钟时间戳 -# #d0=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time())) -# d1=datetime.datetime.now() -# #d1=time.mktime(time.strptime(d0,'%Y-%m-%d %H:%M:%S')) #转换成时间戳 -# d3 = str(d1 - datetime.timedelta(minutes =x_time)) #days日 hours时 minutes分 seconds秒 -# d4=d3[:len(d3)-7] #清除垃圾数据 -# return time.mktime(time.strptime(d4,'%Y-%m-%d %H:%M:%S')) - -def Volume_averages(Ticker_listxxx,x): #均价 - try: - Volume=0 - if len(Ticker_listxxx)int(timeB2): #收盘时间大于我们设定的时间及为 真 - # Log(colour.Time) - # #收集最高价 收盘 数据 - # High_list.append(colour.High) #最高价平均价 - # Low_list.append(colour.Low) #最低价平均价 - - #采集数据 N个周期 - for i in range(len(ticker)-cycle, len(ticker)): - colour=ticker[i] - # timeA1=str(int(colour.Time)) - # timeA2=timeA1[:len(timeA1)-3] #收盘时间 - # Log(colour) - # Log(timeA2,"xxx",len(ticker),"rrrr",i) - Open_list.append(colour.Open) #开盘价 - High_list.append(colour.High) #最高价 - Low_list.append(colour.Low) #最低价 - Close_list.append(colour.Close) #最低价 - - #上一个周期 最高价 最低价 - for i in range(len(ticker)-1, len(ticker)): - colour=ticker[i] - N1Open_price=colour.Open #开盘价 - N1High_price=colour.High #最高价 - N1Low_price=colour.Low #最低价 - N1Close_price=colour.Close #最低价 - - #计算平均价 - if (len(High_list)>=cycle)and(len(Low_list)>=cycle)and(len(Open_list)>=cycle)and(len(Close_list)>=cycle): - Open_Close=_N(Volume_averages(Open_list,cycle),2) #开盘价平均价 - High_Close=_N(Volume_averages(High_list,cycle),2) #最高价平均价 - Low_Close=_N(Volume_averages(Low_list,cycle),2) #最低价平均价 - Close_Close=_N(Volume_averages(Close_list,cycle),2) #收盘价平均价 - Open_price=Open_Close #开盘价平均价 - High_price=High_Close #最高价平均价 - Low_price=Low_Close #最低价平均价 - Close_price=Close_Close #收盘价平均价 - else: - Open_price=0 #开盘价平均价 - High_price=0 #最高价平均价 - Low_price=0 #最低价平均价 - Close_price=0 #收盘价平均价 - -############################################################### -lose_win={"lose":0,"win":0} #输:lose赢:win - -def print_logxx(): - global lose_win - #lose_win={"lose":35,"win":90} #输:lose赢:win - Log("赢:%s 输:%s"%(str(lose_win["win"]),str(lose_win["lose"]))) - # if (float(lose_win["win"])>0 and float(lose_win["lose"])>0): - # SL="%.2f%%"%((float(lose_win["win"]-lose_win["lose"])/float(lose_win["win"]))*100) - # Log("赢:%s 输:%s=胜:%s"%(str(lose_win["win"]),str(lose_win["lose"]),str(SL))) -############################################################### - -#low_minuN_Close= 0.1 #浮动开仓点 -#high_minuN_Close= 0.3 #浮动平仓点 -#lose_win={"lose":0,"win":0} #输:lose赢:win -def main(): - #global low_minuN_Close,high_minuN_Close - global lose_win - global Open_price,High_price,Low_price,Close_price,N1High_price,N1Low_price,N1Open_price,N1Close_price - #LogProfitReset()# 清空所有收益日志, 可以带一个数字参数, 指定保留的条数 - #LogReset()# 清空所有日志, 可以带一个数字参数, 指定保留的条数 - state = 3 #开仓状态 - open_price=0 #开仓价格 - gains=0 #盈利 - while True: - Record_Open_Close(Enter_cycle) #获取 开盘价 收盘价 平均价 - tickerx = _C(exchange.GetTicker).Last#Ticker 市场行情 最后成交价 - - # Log('高价-收盘价:',High_price-Close_price) - # Log('收盘价-最低价:',Close_price-Low_price) - # Log('最高价,开盘价:',High_price,Open_price) - # Log('收盘价,最低价:',Close_price,Low_price) - # Log('最高价,最低价:',N1High_price,N1Low_price) - if High_price-Close_price>=Close_price-Low_price: #比较值计算2个值的浮动区间 - floating_price=(High_price-Close_price) - else: - floating_price=(Close_price-Low_price) - #不知道如何获取当前开盘价采用上个周期收盘价最为开盘价 - x_high=N1Open_price+(0.5*floating_price) #上轨 - x_low=N1Open_price-(0.5*floating_price) #下轨 - #Log('上轨%s=下轨%s=价格差%s=当前价格%s'%(str(x_high),str(x_low),str(x_high-x_low),str(tickerx))) - - #if (float(tickerx)>=float(x_low-low_minuN_Close) and float(tickerx)<=float(x_low+low_minuN_Close)): #判断行情是否在指定区间内则开仓 - #判断当前行情是否在上轨和下轨中 - #突破上轨则开仓 - #突破下轨则平仓 - if (float(tickerx)<=float(x_high+5) and float(tickerx)>=float(x_low-5)): #判断当前行情是否在上轨和下轨中 - if (state == 3): #空闲状态 - if float(tickerx)>=float(x_high): #突破上轨则开仓 - Log('开仓 上轨%s=下轨%s=价格差%s=当前价格%s'%(str(x_high),str(x_low),str(x_high-x_low),str(tickerx))) - state = 0 #开仓 - if (state == 1): #开仓状态 - if float(tickerx)<=float(x_low): #突破下轨则平仓 - state = 2 #平仓 - - # if float(tickerx)<=float(x_low): #大于等于下轨 则开仓 - # if (state == 3): #空闲状态 - # state = 0 #开仓 - # Log('开仓 上轨%s=下轨%s=价格差%s=当前价格%s'%(str(x_high),str(x_low),str(x_high-x_low),str(tickerx))) - - if (state == 0): #开仓 - if ext.Buy(0.5): - #开仓成功 - open_price = tickerx - state = 1 - - if (state == 2): #平仓 - #if (float(tickerx)>=float(x_high-high_minuN_Close) and float(tickerx)<=float(x_high+high_minuN_Close)): #判断行情是否在指定区间内则平仓 - #if float(tickerx)>=float(x_high): #大于等于上轨道 则平仓 - if ext.Sell(0.5): - #平仓成功 - xx=tickerx-open_price #本次交易 - gains=gains+xx - Log("本次盈利:%s--当前共盈利:%s"%(str(tickerx-open_price),str(gains))) - if float(tickerx-open_price)>=0: - lose_win["win"]=lose_win["win"]+1 #赢:win"胜" - else: - lose_win["lose"]=lose_win["lose"]+1#输:lose"负" - print_logxx() #信息输出 - state = 3 - open_price=0 #开仓价格 - - Sleep(1* 1000) - - - - - - - - - diff --git "a/FCoin\344\272\244\346\230\223\346\211\213\347\273\255\350\264\271\347\273\237\350\256\241(\346\204\237\350\260\242\346\273\241\346\200\273\345\210\206\344\272\253).js" "b/FCoin\344\272\244\346\230\223\346\211\213\347\273\255\350\264\271\347\273\237\350\256\241(\346\204\237\350\260\242\346\273\241\346\200\273\345\210\206\344\272\253).js" new file mode 100644 index 00000000..37956533 --- /dev/null +++ "b/FCoin\344\272\244\346\230\223\346\211\213\347\273\255\350\264\271\347\273\237\350\256\241(\346\204\237\350\260\242\346\273\241\346\200\273\345\210\206\344\272\253).js" @@ -0,0 +1,146 @@ +/* +策略出处: https://www.fmz.com/strategy/98405 +策略名称: FCoin交易手续费统计(感谢满总分享) +策略作者: 每日一嫩模 +策略描述: + + + +*/ + +//2018-6-13 22:19 +var Trades = []; +var fees = {"usdt": 0, "btc": 0, "eth": 0, "etc": 0, "ft": 0}; +var num = 0; +var table = { + type: "table", + title: "标题", + cols: ["ts", "时间", "买卖", "委托数", "委托价", "成交额", "成交数", "成交均价", "手续费", "来源", "状态", "交易对", "委托类型", "手续费币"], + rows: [] +}; +var FC_pairs = FC_pairs(); + +function main() { + + /* + symbol 交易对 + states 订单状态 + + submitted 已提交 + partial_filled 部分成交 + partial_canceled 部分成交已撤销 + filled 完全成交 + canceled 已撤销 + pending_cancel 撤销已提交 + + before 查询某个页码之前的订单 + after 查询某个页码之后的订单 + limit 每页的订单数量,默认为 20 条 + + */ + + var Pairs = Object.keys(FC_pairs);//["btcusdt","ltcusdt","ethusdt","ftusdt","ftbtc","etcusdt","bchusdt"]; + var States = ["partial_canceled", "filled", "partial_filled"]; + + var after = new Date().setHours(0, 0, 0, 0); + var end = after + 24 * 3600 * 1000; + + var ts0 = new Date().getTime(); + Pairs.forEach(function (Symbol) { + var ts = after; + + States.forEach(function (State) { + while (true) { + Sleep(1000); +//Log(56,new Date().getTime()-ts0); + ts0 = new Date().getTime(); + var ordersHistory = FC_ordersHistory(Symbol, State, "after", ts); + calcFees(ordersHistory, end); + if (ordersHistory.length < 100) { + break; + } + ts = ordersHistory[0].created_at + 1; + } + }); + + }); + + Log(fees, after, new Date(after));//new Date().format("M-d h:m:s") + + table.title = JSON.stringify(fees); + table.rows = Trades; + // LogStatus("`" + JSON.stringify([table]) + "`" + "\n"); +} + +function calcFees(ordersHistory, end) { + ordersHistory.forEach(function (v) { + if (v.created_at < end) { + var quote = FC_pairs[v.symbol][v.side === "buy" ? 0 : 1]; + if (!fees.hasOwnProperty(quote)) { + fees[quote] = 0; + } + fees[quote] += Number(v.fill_fees); + Trades.push(FC_ordersformat(v).concat([quote])); + } + }); +} + +function FC_pairs() { + var info; + var sleep = 1000; + try { + info = exchange.IO("api", "GET", "/v2/public/symbols");// + } catch (e) { + Log("FC_pairs()出错重试"); + Sleep(sleep); + sleep += sleep; + FC_pairs(); + } + + if (info.hasOwnProperty("status") && info.status === 429) { + Log("429错误"); + Sleep(10000); + FC_pairs(); + } else { + info = info.data; + } + var ret = {}; + info.forEach(function (v) { + if (!ret.hasOwnProperty(v)) { + ret[v.name] = {}; + } + ret[v.name] = [v.base_currency, v.quote_currency]; + }); + + return ret; +} + +function FC_ordersHistory(symbol, states, after_before, ts) { + Log(ts, new Date(ts)); + var args = "symbol=" + symbol + "&limit=100&states=" + states + "&" + after_before + "=" + ts; + var info; + var sleep = 3000; + try { + info = exchange.IO("api", "GET", "/v2/orders", args); + Log(args); + Log(info.data.length); + } catch (e) { + Log("FC_ordersHistory 出错重试"); + Sleep(sleep); + sleep += sleep; + return FC_ordersHistory(symbol, states, after_before, ts); + } + + if (info.hasOwnProperty("status") && info.status === 429) { + Log("429错误"); + Sleep(10000); + return FC_ordersHistory(symbol, states, after_before, ts); + } + return info.data; +} + +function FC_ordersformat(v) { + var ret = [v.created_at, new Date(v.created_at), v.side, Number(v.amount), Number(v.price), Number(v.executed_value), Number(v.filled_amount), _N(Number(v.executed_value) / Number(v.filled_amount), 8), Number(v.fill_fees), v.source, v.state, v.symbol, v.type]; + return ret; +} + diff --git a/Hedge_BTC-ETH Demo.js b/Hedge_BTC-ETH Demo.js index 27223506..8ab6eaf5 100644 --- a/Hedge_BTC-ETH Demo.js +++ b/Hedge_BTC-ETH Demo.js @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/48536 +策略出处: https://www.fmz.com/strategy/48536 策略名称: Hedge_BTC-ETH Demo 策略作者: 小小梦 策略描述: diff --git a/Iceberg Buy Order.js b/Iceberg Buy Order.js new file mode 100644 index 00000000..79e81d09 --- /dev/null +++ b/Iceberg Buy Order.js @@ -0,0 +1,101 @@ +/* +策略出处: https://www.fmz.com/strategy/103319 +策略名称: Iceberg Buy Order +策略作者: botvsing +策略描述: + +冰山委托指的是投资者在进行大额交易时,为避免对市场造成过大冲击,将大单委托自动拆为多笔委托,根据当前的最新买一/卖一价格和客户设定的价格策略自动进行小单委托,在上一笔委托被全部成交或最新价格明显偏离当前委托价时,自动重新进行委托。 +例子: +如果单次均值浮动点数设置为10那么: +每一笔委托的数量为其单次委托平均值的90%~110%,委托价格为最新买1价*(1-委托深度),在上一笔委托全部成交后再进行新的一笔委托,在最新成交价格距离该笔委托超过委托深度*2时自动撤单并重新进行委托。在策略总成交量等于其总委托数量时停止委托。当市场的最新成交价格高于其最高买入价格时停止委托,在最新成交价格重新低于最高买入价后恢复委托。 + + +参数 默认值 描述 +------------ ------ ----------------------- +TotalBuyNet 10000 total buy value +AvgBuyOnce 100 avg buy value +FloatPoint 10 avg price float percent +EntrustDepth 0.1 buy depth percent +MaxBuyPrice 20000 Highest price to buy +Interval 1000 retry time(ms) +MinStock 0.0001 Min Stock +LoopInterval true loop time(second) +*/ + +function CancelPendingOrders() { + while (true) { + var orders = _C(exchange.GetOrders); + if (orders.length == 0) { + return; + } + + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id); + if (j < (orders.length-1)) { + Sleep(Interval); + } + } + } +} + +var LastBuyPrice = 0; +var InitAccount = null; + +function dispatch() { + var account = null; + var ticker = _C(exchange.GetTicker); + if (LastBuyPrice > 0) { + if (_C(exchange.GetOrders).length > 0) { + if (ticker.Last > LastBuyPrice && ((ticker.Last - LastBuyPrice) / LastBuyPrice) > (2*(EntrustDepth/100))) { + Log('deviate to much, newest last price:', ticker.Last, 'order buy price', LastBuyPrice); + CancelPendingOrders(); + } else { + return true; + } + } else { + account = _C(exchange.GetAccount); + Log("order finised, total cost:", _N(InitAccount.Balance - account.Balance), "avg buy price:", _N((InitAccount.Balance - account.Balance) / (account.Stocks - InitAccount.Stocks))); + } + LastBuyPrice = 0; + } + + var BuyPrice = _N(ticker.Buy * (1 - EntrustDepth/100),PricePerision); + if (BuyPrice > MaxBuyPrice) { + return true; + } + + if (!account) { + account = _C(exchange.GetAccount); + } + + + if ((InitAccount.Balance - account.Balance) >= TotalBuyNet) { + return false; + } + + var RandomAvgBuyOnce = (AvgBuyOnce * ((100 - FloatPoint) / 100)) + (((FloatPoint * 2) / 100) * AvgBuyOnce * Math.random()); + var UsedMoney = Math.min(account.Balance, RandomAvgBuyOnce, TotalBuyNet - (InitAccount.Balance - account.Balance)); + + var BuyAmount = _N(UsedMoney / BuyPrice, 3); + if (BuyAmount < MinStock) { + return false; + } + LastBuyPrice = BuyPrice; + exchange.Buy(BuyPrice, BuyAmount, 'Cost: ', _N(UsedMoney), 'last price', ticker.Last); + return true; +} + +function main() { + CancelPendingOrders(); + InitAccount = _C(exchange.GetAccount); + Log(InitAccount); + if (InitAccount.Balance < TotalBuyNet) { + throw "balance not enough"; + } + LoopInterval = Math.max(LoopInterval, 1); + while (dispatch()) { + Sleep(LoopInterval * 1000); + } + Log("All Done", _C(exchange.GetAccount)); +} + diff --git "a/JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.js" "b/JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.js" index 3008d078..2be4ba5c 100644 --- "a/JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.js" +++ "b/JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/44593 +策略出处: https://www.fmz.com/strategy/44593 策略名称: JS版 商品期货 精简多品种 MACD 趋势策略框架 策略作者: 小小梦 策略描述: diff --git "a/JS\347\211\210\346\234\254Dual Thrust.js" "b/JS\347\211\210\346\234\254Dual Thrust.js" index ab544eb2..42369197 100644 --- "a/JS\347\211\210\346\234\254Dual Thrust.js" +++ "b/JS\347\211\210\346\234\254Dual Thrust.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/36100 +策略出处: https://www.fmz.com/strategy/36100 策略名称: JS版本Dual Thrust 策略作者: BotVs@太极 策略描述: diff --git "a/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.js" "b/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.js" index cb73e681..3e68a35f 100644 --- "a/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.js" +++ "b/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/42283 +策略出处: https://www.fmz.com/strategy/42283 策略名称: KingKeltner趋势策略_低频 策略作者: ipqhjjybj 策略描述: diff --git a/MA_20180107 (Copy).js b/MA_20180107 (Copy).js deleted file mode 100644 index fe2a5336..00000000 --- a/MA_20180107 (Copy).js +++ /dev/null @@ -1,79 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/69033 -策略名称: MA_20180107 (Copy) -策略作者: ellajella-0378 -策略描述: - - - - -参数 默认值 描述 ------------- ----- ------------ -long_period 156 long_period -short_period 35 short_period -*/ - -/*backtest -start: 2018-01-01 00:00:00 -end: 2018-01-07 22:00:00 -period: 15m -exchanges: [{"eid":"Bitfinex","currency":"LTC","balance":100000,"stocks":0}] -*/ - -function refresh_data() { - ticker = exchange.GetTicker(); - coin_price = ticker.Last - account = exchange.GetAccount(); - balance = account.Balance - frozen_balance = account.FrozenBalance - stocks = account.Stocks - frozen_stocks = account.FrozenStocks - total_asset = balance + frozen_balance + (stocks + frozen_stocks) * coin_price -} - - -function main() { - refresh_data() - var init_total_asset = total_asset - var Profit = null - Log("账户信息,Total_asset:", total_asset); - - while (true) { - refresh_data() - ticker = exchange.GetTicker(); - coin_price = ticker.Last - var buy_amount = account.Balance / coin_price - var sell_amount = account.Stocks - - var records = exchange.GetRecords(PERIOD_M15); //可以填入不同k线周期,比如PERIOD_M1,PERIOD_M30,PERIOD_H1...... - var ma_short = TA.MA(records, short_period); - ma_short = ma_short[ma_short.length - 1] - var ma_long = TA.MA(records, long_period); - ma_long = ma_long[ma_long.length - 1] - - var condition = ma_short - ma_long - - if (condition > 0 & buy_amount > 0.001) { - Log('buy,coin_price=', coin_price, 'buy_amount=', buy_amount) - var id_buy = exchange.Buy(coin_price, buy_amount); - Log("id:", id_buy); - refresh_data() - Log("账户信息,Total_asset:", total_asset); - Profit = total_asset - init_total_asset - LogProfit(Profit) - } else if (condition <= 0 & sell_amount > 0.001) { - Log('sell,coin_price=', coin_price, 'sell_amount=', sell_amount) - var id_sell = exchange.Sell(coin_price, sell_amount); - Log("id:", id_sell); - refresh_data() - Log("账户信息,Total_asset:", total_asset); - Profit = total_asset - init_total_asset - LogProfit(Profit) - } - Sleep(1000 * 60) - } - refresh_data() - Profit = total_asset - init_total_asset - LogProfit(Profit) - Log("账户信息,Total_asset:", total_asset); -} diff --git "a/Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.js" "b/Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.js" index 496af319..763b50e9 100644 --- "a/Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.js" +++ "b/Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/42451 +策略出处: https://www.fmz.com/strategy/42451 策略名称: Ma单均线趋势交易 策略作者: ipqhjjybj 策略描述: diff --git a/Moving Average Strategy in 30 lines.js b/Moving Average Strategy in 30 lines.js new file mode 100644 index 00000000..f3c95821 --- /dev/null +++ b/Moving Average Strategy in 30 lines.js @@ -0,0 +1,60 @@ +/* +策略出处: https://www.fmz.com/strategy/103070 +策略名称: Moving Average Strategy in 30 lines +策略作者: botvsing +策略描述: + +"Talk is cheap. Show me the code" + +Just for learning, Be carefully when using in real market. + +Only run on digital currency exchanges. + +Note: this strategy included template. (function with $.) + +Beginers can start with this strategy, learn how to code, know the difference between backtesting and real market. + +https://dn-filebox.qbox.me/fb4d0c7d773ca83e9d0230927705d419dc0bbeaa.png + + +参数 默认值 描述 +----------- ----- --------------------- +Slippage 0.1 Slippage +FastPeriod 5 fast line periods +SlowPeriod 15 slow line periods +EnterPeriod 2 observe periods +Interval 120 Interval time(second) +*/ + +function main() { + var initAccount = _C(exchange.GetAccount); + var ticker = exchange.GetTicker(); + var InitValue = (initAccount.Stocks + initAccount.FrozenStocks)*ticker.Last + initAccount.Balance + initAccount.FrozenBalance; + while (true) { + var records = _C(exchange.GetRecords); + ticker =_C(exchange.GetTicker); + var FastRecords = TA.MA(records,FastPeriod); + var SlowRecords = TA.MA(records,SlowPeriod); + var NowAccount = _C(exchange.GetAccount); + var n = _Cross(FastRecords, SlowRecords); + if (n >= EnterPeriod && NowAccount.Balance > 0) { + var Price = _N(ticker.Sell+Slippage, 2); + var Amount = _N(0.99*NowAccount.Balance/Price, 3); + if(Amount>0.1){ + var id = exchange.Buy(Price, Amount); + if(exchange.GetOrders(id).Status == ORDER_STATE_PENDING){exchange.CancelOrder(id);} + LogProfit((NowAccount.Stocks + NowAccount.FrozenStocks)*ticker.Last + NowAccount.Balance + NowAccount.FrozenBalance - InitValue); + } + } + if(n <= -EnterPeriod && NowAccount.Stocks > 0) { + var Price = _N(ticker.Buy-Slippage, 2); + var Amount = _N(NowAccount.Stocks, 3); + if(Amount>0.1){ + var id = exchange.Sell(Price, Amount); + if(exchange.GetOrders(id).Status == ORDER_STATE_PENDING){exchange.CancelOrder(id);} + LogProfit((NowAccount.Stocks + NowAccount.FrozenStocks)*ticker.Last + NowAccount.Balance + NowAccount.FrozenBalance - InitValue); + } + } + Sleep(Interval*1000); + } +} diff --git "a/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.js" "b/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.js" index 13675538..f44452e4 100644 --- "a/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.js" +++ "b/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/8602 +策略出处: https://www.fmz.com/strategy/8602 策略名称: My-1-价值平均定投策略 策略作者: Lizza 策略描述: diff --git "a/OKCoin\346\234\237\350\264\247\346\235\241\344\273\266\350\247\246\345\217\221\345\247\224\346\211\230\345\270\246\346\255\242\346\215\237.js" "b/OKCoin\346\234\237\350\264\247\346\235\241\344\273\266\350\247\246\345\217\221\345\247\224\346\211\230\345\270\246\346\255\242\346\215\237.js" index 7530849c..0b0cc32c 100644 --- "a/OKCoin\346\234\237\350\264\247\346\235\241\344\273\266\350\247\246\345\217\221\345\247\224\346\211\230\345\270\246\346\255\242\346\215\237.js" +++ "b/OKCoin\346\234\237\350\264\247\346\235\241\344\273\266\350\247\246\345\217\221\345\247\224\346\211\230\345\270\246\346\255\242\346\215\237.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/2169 +策略出处: https://www.fmz.com/strategy/2169 策略名称: OKCoin期货条件触发委托带止损 策略作者: Zero 策略描述: diff --git "a/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" "b/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" index c992c87a..d8c34876 100644 --- "a/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" +++ "b/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/43965 +策略出处: https://www.fmz.com/strategy/43965 策略名称: Python 精简多品种 MACD 趋势策略 策略作者: Zero 策略描述: diff --git "a/Python API \346\265\213\350\257\225.py" "b/Python API \346\265\213\350\257\225.py" index 41bf4ec6..b181a122 100644 --- "a/Python API \346\265\213\350\257\225.py" +++ "b/Python API \346\265\213\350\257\225.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/21365 +策略出处: https://www.fmz.com/strategy/21365 策略名称: Python API 测试 策略作者: Zero 策略描述: diff --git "a/Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.py" "b/Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.py" index cb71621c..56f4cdc0 100644 --- "a/Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.py" +++ "b/Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/21023 +策略出处: https://www.fmz.com/strategy/21023 策略名称: Python 双平台对冲策略 策略作者: Zero 策略描述: diff --git "a/Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.py" "b/Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.py" index f620771e..0623dff2 100644 --- "a/Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.py" +++ "b/Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/21370 +策略出处: https://www.fmz.com/strategy/21370 策略名称: Python 机器学习之 SVM 预测买卖 策略作者: Zero 策略描述: @@ -71,21 +71,20 @@ def main(): n += 1 clf = svm.LinearSVC() clf.fit(inputs_X, output_Y) - predict = clf.predict(np.array([bar.Open, bar.Close]).reshape((1, -1))) + predict = clf.predict(np.array([bar.Open, bar.Close]).reshape((1, -1)))[0] pTime = bar.Time - Log("预测当前Bar结束:", bar.Time, ['涨', '跌', '横'][predict]) if marketPosition == 0: if predict == 0: - exchange.Buy(initAccount.Balance/2) + exchange.Buy(-1, initAccount.Balance/2) marketPosition = 1 elif predict == 1: - exchange.Sell(initAccount.Stocks/2) + exchange.Sell(-1, initAccount.Stocks/2) marketPosition = -1 else: nowAccount = exchange.GetAccount() if marketPosition > 0 and predict != 0: - exchange.Sell(nowAccount.Stocks - initAccount.Stocks) + exchange.Sell(-1, nowAccount.Stocks - initAccount.Stocks) nowAccount = exchange.GetAccount() marketPosition = 0 elif marketPosition < 0 and predict != 1: diff --git "a/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" "b/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" index a20dfe72..1c8a9507 100644 --- "a/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" +++ "b/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/46031 +策略出处: https://www.fmz.com/strategy/46031 策略名称: Python版 TableTemplet (测试版) 策略作者: 小小梦 策略描述: diff --git "a/Python\347\256\200\345\215\225\346\265\213\350\257\225\347\255\226\347\225\245.py" "b/Python\347\256\200\345\215\225\346\265\213\350\257\225\347\255\226\347\225\245.py" index a753e668..b263687f 100644 --- "a/Python\347\256\200\345\215\225\346\265\213\350\257\225\347\255\226\347\225\245.py" +++ "b/Python\347\256\200\345\215\225\346\265\213\350\257\225\347\255\226\347\225\245.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/20761 +策略出处: https://www.fmz.com/strategy/20761 策略名称: Python简单测试策略 策略作者: Zero 策略描述: @@ -44,14 +44,12 @@ def main(): Log(str(talib.EMA(r.Close, 10))) for e in exchanges: - Log(e.GetName(), e.GetRate(), e.GetCurrency(), e.GetFee()) + Log(e.GetName(), e.GetRate(), e.GetCurrency()) Log(e.GetAccount()) Log(_C(e.GetOrders)) Log(e.GetOrder(10)) Log(e.CancelOrder(10000)) - Log(e.IO("api", "userinfo")) - Log(e.IO("api", "order_info", "symbol=btc_usd&order_id=3")) - + Log(e.GetUSDCNY()) #Log(e.GetPosition()) #Log(e.SetContractType("next_week")) diff --git "a/R-Breaker \344\272\244\346\230\223\347\255\226\347\225\245.py" "b/R-Breaker \344\272\244\346\230\223\347\255\226\347\225\245.py" index dda386f3..b6619dbc 100644 --- "a/R-Breaker \344\272\244\346\230\223\347\255\226\347\225\245.py" +++ "b/R-Breaker \344\272\244\346\230\223\347\255\226\347\225\245.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/23531 +策略出处: https://www.fmz.com/strategy/23531 策略名称: R-Breaker 交易策略 策略作者: 太极 策略描述: diff --git "a/R-Breaker11 \344\272\244\346\230\223\347\255\226\347\225\245.py" "b/R-Breaker11 \344\272\244\346\230\223\347\255\226\347\225\245.py" index 3761a467..9cca28bc 100644 --- "a/R-Breaker11 \344\272\244\346\230\223\347\255\226\347\225\245.py" +++ "b/R-Breaker11 \344\272\244\346\230\223\347\255\226\347\225\245.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/23874 +策略出处: https://www.fmz.com/strategy/23874 策略名称: R-Breaker11 交易策略 策略作者: 太极 策略描述: diff --git a/README.md b/README.md index ee2a169c..5b7b51d8 100644 --- a/README.md +++ b/README.md @@ -4,163 +4,169 @@ > 开源策略列表 - - [python版CTP商品期货交易类库(支持2/3 测试版)](https://www.botvs.com/strategy/24288) - - [商品期货交易类库](https://www.botvs.com/strategy/12961) - - [网格变形策略之单边网格](https://www.botvs.com/strategy/629) - - [talib简单应用之查找三只乌鸦](https://www.botvs.com/strategy/62163) - - [内外盘期货品种实时差价图](https://www.botvs.com/strategy/82929) - - [测试多图表展示Python版](https://www.botvs.com/strategy/84042) - - [定投简单版 (Copy)](https://www.botvs.com/strategy/83805) - - [okex-BTC合约账户公开](https://www.botvs.com/strategy/83189) - - [抢盘口做市策略 - 对敲](https://www.botvs.com/strategy/304) - - [冰山委托 - 卖出](https://www.botvs.com/strategy/241) - - [冰山委托 - 买入](https://www.botvs.com/strategy/236) - - [趋势跟踪震荡策略](https://www.botvs.com/strategy/179) - - [多平台强制滑动平仓(买一价)](https://www.botvs.com/strategy/99) - - [定点进场下单定点离场卖单](https://www.botvs.com/strategy/64) - - [【001】单平台均衡策略 【研究】](https://www.botvs.com/strategy/82325) - - [CTP商品期货多品种海龟交易策略](https://www.botvs.com/strategy/17289) - - [python版 Dual Thrust OKCoin 期货](https://www.botvs.com/strategy/21856) - - [五线向上&&突破前高](https://www.botvs.com/strategy/76827) - - [单平台均衡策略](https://www.botvs.com/strategy/345) - - [数字货币现货交易类库](https://www.botvs.com/strategy/10989) - - [数字货币交易类库 (期货支持OKCoin期货/BitVC, 支持$.CTA函数)](https://www.botvs.com/strategy/57267) - - [C++ API调用例子](https://www.botvs.com/strategy/61533) - - [定期定额投资BTC盈利验证](https://www.botvs.com/strategy/65030) - - [双平台对冲js版本(two platforms hedging-JS)](https://www.botvs.com/strategy/57556) - - [转换任意K线周期管理模板(最近更新20180118)](https://www.botvs.com/strategy/41163) - - [代替废弃的GetMinStock()函数](https://www.botvs.com/strategy/69436) - - [Shannon's Demon (Copy)](https://www.botvs.com/strategy/69034) - - [MA_20180107 (Copy)](https://www.botvs.com/strategy/69033) - - [Python版 TableTemplet (测试版)](https://www.botvs.com/strategy/46031) - - [网格(波段)香农版](https://www.botvs.com/strategy/67495) - - [价值平均定投](https://www.botvs.com/strategy/67128) - - [定投简单版](https://www.botvs.com/strategy/67098) - - [策略框架模板](https://www.botvs.com/strategy/30861) - - [不要怂就是干 (Copy)](https://www.botvs.com/strategy/65114) - - [Shannon's Demon](https://www.botvs.com/strategy/64455) - - [画线类库](https://www.botvs.com/strategy/27293) - - [回测保存K线到本地CSV](https://www.botvs.com/strategy/61867) - - [02顺大势逆小势策略之代码实现及可行性分析 (Share 1513097042)](https://www.botvs.com/strategy/63223) - - [03基于商品期货的套利策略模型 (Share 1513096985)](https://www.botvs.com/strategy/63221) - - [数字货币现货交易类库c++](https://www.botvs.com/strategy/62140) - - [幽灵交易者策略 (Share 1512580165)](https://www.botvs.com/strategy/62303) - - [bitfinex保证金交易](https://www.botvs.com/strategy/57333) - - [双平台对冲js版本(two platforms hedging-JS) (Copy)](https://www.botvs.com/strategy/61405) - - [2014年的简易短线机器人 (Copy) (Share 1512130985)](https://www.botvs.com/strategy/61398) - - [2014年的简易短线机器人](https://www.botvs.com/strategy/1088) - - [简单多品种商品期货均线策略](https://www.botvs.com/strategy/57029) - - [测试 默认 参数组功能](https://www.botvs.com/strategy/40155) - - [全球10大交易系统之 Aberration 多品种商品期货交易系统](https://www.botvs.com/strategy/25943) - - [Dual Thrust 商品期货](https://www.botvs.com/strategy/13011) - - [python版 画线类库 (兼容2/3)](https://www.botvs.com/strategy/39066) - - [BotVS 商品期货 量化 测试入门 策略](https://www.botvs.com/strategy/59120) - - [如何找出一定Bar数量的 K线前期高点、低点 及 Demo 程序](https://www.botvs.com/strategy/58179) - - [python版现货数字货币交易类库](https://www.botvs.com/strategy/21104) - - [数字货币交易类库 (期货支持OKCoin期货/BitVC)](https://www.botvs.com/strategy/30199) - - [一目均衡](https://www.botvs.com/strategy/55839) - - [StochRSI(和okcoin一致)](https://www.botvs.com/strategy/56119) - - [使用 BotVS 构建一个机械化策略](https://www.botvs.com/strategy/40357) - - [差价监控](https://www.botvs.com/strategy/1340) - - [布林均线突破_vnpy_botvs实现版](https://www.botvs.com/strategy/52801) - - [数字货币定投](https://www.botvs.com/strategy/54256) - - [双平台对冲 练习用 求交流求指点](https://www.botvs.com/strategy/53512) - - [仓位均衡策略](https://www.botvs.com/strategy/54182) - - [Hedge_BTC/ETH Demo](https://www.botvs.com/strategy/48536) - - [多均线策略](https://www.botvs.com/strategy/47144) - - [均线MA指标使用范例](https://www.botvs.com/strategy/46484) - - [Python 精简多品种 MACD 趋势策略](https://www.botvs.com/strategy/43965) - - [JS版 商品期货 精简多品种 MACD 趋势策略框架](https://www.botvs.com/strategy/44593) - - [TableTemplet](https://www.botvs.com/strategy/44319) - - [Ma单均线趋势交易](https://www.botvs.com/strategy/42451) - - [KingKeltner趋势策略_低频](https://www.botvs.com/strategy/42283) - - [buy-hold 买入持有](https://www.botvs.com/strategy/41786) - - [知乎专栏 实例文章策略](https://www.botvs.com/strategy/40266) - - [BitMEX 简单测试](https://www.botvs.com/strategy/40289) - - [商品期货查看账户详细信息](https://www.botvs.com/strategy/37793) - - [股票证券查询买卖示例](https://www.botvs.com/strategy/5541) - - [测试多图表展示](https://www.botvs.com/strategy/38203) - - [商品期货结算单平仓盈亏历史查询](https://www.botvs.com/strategy/38083) - - [Convert_Record_Cycle](https://www.botvs.com/strategy/37678) - - [转换任意K线周期](https://www.botvs.com/strategy/35986) - - [测试-CTP商品期货连接状态 (图表显示)](https://www.botvs.com/strategy/22838) - - [API 测试新手入门](https://www.botvs.com/strategy/4) - - [实盘账户模拟器](https://www.botvs.com/strategy/35977) - - [js R-Breaker](https://www.botvs.com/strategy/36195) - - [JS版本Dual Thrust](https://www.botvs.com/strategy/36100) - - [图表界面信息展示实例1](https://www.botvs.com/strategy/36026) - - [移植 OKCoin 韭菜收割机](https://www.botvs.com/strategy/34388) - - [R-Breaker11 交易策略](https://www.botvs.com/strategy/23874) - - [比特币现货阶梯差价对冲](https://www.botvs.com/strategy/30573) - - [范例-定时测试微信消息推送](https://www.botvs.com/strategy/15098) - - [测试-布林带策略(基于策略框架)](https://www.botvs.com/strategy/28128) - - [商品期货跨期对冲 - 单品种套利合约](https://www.botvs.com/strategy/27122) - - [Python API 测试](https://www.botvs.com/strategy/21365) - - [从第三方获取K线 (商品期货版) Rev. 161216](https://www.botvs.com/strategy/15498) - - [均线策略 30 行搞定](https://www.botvs.com/strategy/12348) - - [商品期货跨期对冲 - 百行代码实现](https://www.botvs.com/strategy/23896) - - [短信通知类库](https://www.botvs.com/strategy/26921) - - [获取和讯期货数据(Python版本)](https://www.botvs.com/strategy/26017) - - [高频收割机一号](https://www.botvs.com/strategy/6237) - - [R-Breaker 交易策略](https://www.botvs.com/strategy/23531) - - [(13)策略框架](https://www.botvs.com/strategy/20663) - - [Dual Thrust_双轨突破_策略1](https://www.botvs.com/strategy/22983) - - [Python 机器学习之 SVM 预测买卖](https://www.botvs.com/strategy/21370) - - [均线策略(python版)](https://www.botvs.com/strategy/21157) - - [Python 双平台对冲策略](https://www.botvs.com/strategy/21023) - - [各大平台API可用率统计](https://www.botvs.com/strategy/4404) - - [均线-趋势_数字货币策略V0.2](https://www.botvs.com/strategy/21369) - - [Python简单测试策略](https://www.botvs.com/strategy/20761) - - [图表模板(增加状态栏表格)](https://www.botvs.com/strategy/20967) - - [高频交易策略之 - Penny Jump](https://www.botvs.com/strategy/358) - - [stochRSI策略 (指标框架)](https://www.botvs.com/strategy/20383) - - [获取周K线](https://www.botvs.com/strategy/20226) - - [对冲2.7收益率统计系统 支持多组账号统计](https://www.botvs.com/strategy/18678) - - [收益率统计](https://www.botvs.com/strategy/19329) - - [从第三方网站获取K线 (0804更新)](https://www.botvs.com/strategy/12977) - - [不要怂就是干](https://www.botvs.com/strategy/18943) - - [入门模板之各个平台余额](https://www.botvs.com/strategy/48) - - [商品期货主力合约过滤](https://www.botvs.com/strategy/9837) - - [商品期货交易类库(增加下限价单功能)](https://www.botvs.com/strategy/14198) - - [获取OK期货实时限价](https://www.botvs.com/strategy/17028) - - [定期定额投资BTC盈利验证](https://www.botvs.com/strategy/16845) - - [My-1-价值平均定投策略](https://www.botvs.com/strategy/8602) - - [记录净资产变动情况2.0](https://www.botvs.com/strategy/8916) - - [非常简单的策略,但是很有效](https://www.botvs.com/strategy/15085) - - [单独计算收益(代码来自zero)](https://www.botvs.com/strategy/1084) - - [10行人品策略](https://www.botvs.com/strategy/14436) - - [平台价格指标监控1.1](https://www.botvs.com/strategy/12442) - - [窜天猴 - 移动止损版](https://www.botvs.com/strategy/13594) - - [窜天猴 多空较量 爆破版](https://www.botvs.com/strategy/13597) - - [破冰者](https://www.botvs.com/strategy/9929) - - [函数自动容错模板](https://www.botvs.com/strategy/11609) - - [Dual Thrust OKCoin 期货](https://www.botvs.com/strategy/12101) - - [RSI_now_sb_ok](https://www.botvs.com/strategy/11604) - - [模板库使用例子](https://www.botvs.com/strategy/10991) - - [价值0.418](https://www.botvs.com/strategy/10744) - - [传统期货差价监控 (CTP)](https://www.botvs.com/strategy/5379) - - [融资融币统计](https://www.botvs.com/strategy/8954) - - [【Demo】如何利用“策略交互“动态调整策略参数](https://www.botvs.com/strategy/8379) - - [【Demo】速度测试 websocket vs rest](https://www.botvs.com/strategy/7547) - - [平台价格比较1.0](https://www.botvs.com/strategy/8266) - - [多平台账户统计](https://www.botvs.com/strategy/7827) - - [计划委托买入](https://www.botvs.com/strategy/638) - - [计划委托卖出](https://www.botvs.com/strategy/747) - - [阶梯下单 - 可设置触发价格](https://www.botvs.com/strategy/639) - - [单点狙击高频加仓自动反手解套算法 V1.2](https://www.botvs.com/strategy/2406) - - [796期货反手加倍算法](https://www.botvs.com/strategy/3648) - - [冰山委托 - 支持价格触发 BitVC期货专用](https://www.botvs.com/strategy/951) - - [多线程获取多个交易的深度信息](https://www.botvs.com/strategy/3651) - - [账户余额变动邮箱提醒, 支持添加多个交易所](https://www.botvs.com/strategy/2006) - - [多线程获取多个交易的账户信息](https://www.botvs.com/strategy/3297) - - [OKCoin期货条件触发委托带止损](https://www.botvs.com/strategy/2169) - - [监视并显示多个平台的全部资产总和的变化](https://www.botvs.com/strategy/443) - - [BTC/LTC 地址监视, 短信通知](https://www.botvs.com/strategy/1295) - - [统计K线回测是否存在趋势](https://www.botvs.com/strategy/1125) - - [价格波动报警](https://www.botvs.com/strategy/885) - - [取消所有订单](https://www.botvs.com/strategy/280) - - [新手入门之 - 下买单卖单](https://www.botvs.com/strategy/796) - - [短信通知接口测试](https://www.botvs.com/strategy/653) - - [抢盘口做市策略 - 高频逼近型](https://www.botvs.com/strategy/348) - - [每1分钟统计各个平台间的差价(by JackConan)](https://www.botvs.com/strategy/98) - - [统计各个平台间的最大差价(by JackConan)](https://www.botvs.com/strategy/86) + - [Iceberg Buy Order](https://www.fmz.com/strategy/103319) + - [Dual Thrust OKEX Feature](https://www.fmz.com/strategy/103247) + - [Moving Average Strategy in 30 lines](https://www.fmz.com/strategy/103070) + - [商品期货跟单系统](https://www.fmz.com/strategy/79351) + - [CoinPark交易所通用协议 6.27 16:00 更新 关闭了SSL验证](https://www.fmz.com/strategy/101399) + - [转换任意K线周期管理模板(最近更新20180627)](https://www.fmz.com/strategy/41163) + - [商品期货跨期对冲 - 单品种套利合约](https://www.fmz.com/strategy/27122) + - [2014年的简易短线机器人](https://www.fmz.com/strategy/1088) + - [FCoin交易手续费统计(感谢满总分享)](https://www.fmz.com/strategy/98405) + - [fcoin挖矿演示](https://www.fmz.com/strategy/97791) + - [币安出售所有山寨币](https://www.fmz.com/strategy/97629) + - [RSI 双均线策略](https://www.fmz.com/strategy/46605) + - [追涨杀跌](https://www.fmz.com/strategy/96634) + - [Python 机器学习之 SVM 预测买卖](https://www.fmz.com/strategy/21370) + - [Python简单测试策略](https://www.fmz.com/strategy/20761) + - [破冰者](https://www.fmz.com/strategy/9929) + - [Dual Thrust OKCoin 期货](https://www.fmz.com/strategy/12101) + - [计划委托买入](https://www.fmz.com/strategy/638) + - [计划委托卖出](https://www.fmz.com/strategy/747) + - [单点狙击高频加仓自动反手解套算法 V1.2](https://www.fmz.com/strategy/2406) + - [抢盘口做市策略 - 高频逼近型](https://www.fmz.com/strategy/348) + - [网格变形策略之单边网格 (OK期货)](https://www.fmz.com/strategy/8474) + - [测试-CTP商品期货连接状态 (图表显示)](https://www.fmz.com/strategy/22838) + - [测试-布林带策略(基于策略框架)](https://www.fmz.com/strategy/28128) + - [策略框架模板](https://www.fmz.com/strategy/30861) + - [python版CTP商品期货交易类库(支持2/3 测试版)](https://www.fmz.com/strategy/24288) + - [指数量化](https://www.fmz.com/strategy/91704) + - [顺大势逆小势策略之代码实现及可行性分析](https://www.fmz.com/strategy/59356) + - [判断MA线的排列 - btcdw](https://www.fmz.com/strategy/89969) + - [单边网格](https://www.fmz.com/strategy/88472) + - [okex币币最小交易量](https://www.fmz.com/strategy/88754) + - [基于CCI周期性区间交易策略](https://www.fmz.com/strategy/60287) + - [商品期货交易类库](https://www.fmz.com/strategy/12961) + - [网格变形策略之单边网格](https://www.fmz.com/strategy/629) + - [talib简单应用之查找三只乌鸦](https://www.fmz.com/strategy/62163) + - [内外盘期货品种实时差价图](https://www.fmz.com/strategy/82929) + - [测试多图表展示Python版](https://www.fmz.com/strategy/84042) + - [okex-BTC合约账户公开](https://www.fmz.com/strategy/83189) + - [抢盘口做市策略 - 对敲](https://www.fmz.com/strategy/304) + - [冰山委托 - 卖出](https://www.fmz.com/strategy/241) + - [冰山委托 - 买入](https://www.fmz.com/strategy/236) + - [趋势跟踪震荡策略](https://www.fmz.com/strategy/179) + - [多平台强制滑动平仓(买一价)](https://www.fmz.com/strategy/99) + - [定点进场下单定点离场卖单](https://www.fmz.com/strategy/64) + - [【001】单平台均衡策略 【研究】](https://www.fmz.com/strategy/82325) + - [CTP商品期货多品种海龟交易策略](https://www.fmz.com/strategy/17289) + - [python版 Dual Thrust OKCoin 期货](https://www.fmz.com/strategy/21856) + - [五线向上&&突破前高](https://www.fmz.com/strategy/76827) + - [单平台均衡策略](https://www.fmz.com/strategy/345) + - [数字货币现货交易类库](https://www.fmz.com/strategy/10989) + - [数字货币交易类库 (期货支持OKCoin期货/BitVC, 支持$.CTA函数)](https://www.fmz.com/strategy/57267) + - [C++ API调用例子](https://www.fmz.com/strategy/61533) + - [定期定额投资BTC盈利验证](https://www.fmz.com/strategy/65030) + - [双平台对冲js版本(two platforms hedging-JS)](https://www.fmz.com/strategy/57556) + - [代替废弃的GetMinStock()函数](https://www.fmz.com/strategy/69436) + - [Python版 TableTemplet (测试版)](https://www.fmz.com/strategy/46031) + - [网格(波段)香农版](https://www.fmz.com/strategy/67495) + - [价值平均定投](https://www.fmz.com/strategy/67128) + - [定投简单版](https://www.fmz.com/strategy/67098) + - [Shannon's Demon](https://www.fmz.com/strategy/64455) + - [画线类库](https://www.fmz.com/strategy/27293) + - [回测保存K线到本地CSV](https://www.fmz.com/strategy/61867) + - [02顺大势逆小势策略之代码实现及可行性分析 (Share 1513097042)](https://www.fmz.com/strategy/63223) + - [03基于商品期货的套利策略模型 (Share 1513096985)](https://www.fmz.com/strategy/63221) + - [幽灵交易者策略 (Share 1512580165)](https://www.fmz.com/strategy/62303) + - [bitfinex保证金交易](https://www.fmz.com/strategy/57333) + - [双平台对冲js版本(two platforms hedging-JS) (Copy)](https://www.fmz.com/strategy/61405) + - [简单多品种商品期货均线策略](https://www.fmz.com/strategy/57029) + - [测试 默认 参数组功能](https://www.fmz.com/strategy/40155) + - [全球10大交易系统之 Aberration 多品种商品期货交易系统](https://www.fmz.com/strategy/25943) + - [Dual Thrust 商品期货](https://www.fmz.com/strategy/13011) + - [python版 画线类库 (兼容2/3)](https://www.fmz.com/strategy/39066) + - [BotVS 商品期货 量化 测试入门 策略](https://www.fmz.com/strategy/59120) + - [如何找出一定Bar数量的 K线前期高点、低点 及 Demo 程序](https://www.fmz.com/strategy/58179) + - [python版现货数字货币交易类库](https://www.fmz.com/strategy/21104) + - [一目均衡](https://www.fmz.com/strategy/55839) + - [StochRSI(和okcoin一致)](https://www.fmz.com/strategy/56119) + - [使用 BotVS 构建一个机械化策略](https://www.fmz.com/strategy/40357) + - [差价监控](https://www.fmz.com/strategy/1340) + - [布林均线突破_vnpy_botvs实现版](https://www.fmz.com/strategy/52801) + - [数字货币定投](https://www.fmz.com/strategy/54256) + - [双平台对冲 练习用 求交流求指点](https://www.fmz.com/strategy/53512) + - [仓位均衡策略](https://www.fmz.com/strategy/54182) + - [Hedge_BTC/ETH Demo](https://www.fmz.com/strategy/48536) + - [多均线策略](https://www.fmz.com/strategy/47144) + - [Python 精简多品种 MACD 趋势策略](https://www.fmz.com/strategy/43965) + - [JS版 商品期货 精简多品种 MACD 趋势策略框架](https://www.fmz.com/strategy/44593) + - [TableTemplet](https://www.fmz.com/strategy/44319) + - [Ma单均线趋势交易](https://www.fmz.com/strategy/42451) + - [KingKeltner趋势策略_低频](https://www.fmz.com/strategy/42283) + - [buy-hold 买入持有](https://www.fmz.com/strategy/41786) + - [知乎专栏 实例文章策略](https://www.fmz.com/strategy/40266) + - [BitMEX 简单测试](https://www.fmz.com/strategy/40289) + - [商品期货查看账户详细信息](https://www.fmz.com/strategy/37793) + - [股票证券查询买卖示例](https://www.fmz.com/strategy/5541) + - [测试多图表展示](https://www.fmz.com/strategy/38203) + - [商品期货结算单平仓盈亏历史查询](https://www.fmz.com/strategy/38083) + - [Convert_Record_Cycle](https://www.fmz.com/strategy/37678) + - [转换任意K线周期](https://www.fmz.com/strategy/35986) + - [API 测试新手入门](https://www.fmz.com/strategy/4) + - [js R-Breaker](https://www.fmz.com/strategy/36195) + - [JS版本Dual Thrust](https://www.fmz.com/strategy/36100) + - [图表界面信息展示实例1](https://www.fmz.com/strategy/36026) + - [移植 OKCoin 韭菜收割机](https://www.fmz.com/strategy/34388) + - [R-Breaker11 交易策略](https://www.fmz.com/strategy/23874) + - [比特币现货阶梯差价对冲](https://www.fmz.com/strategy/30573) + - [范例-定时测试微信消息推送](https://www.fmz.com/strategy/15098) + - [Python API 测试](https://www.fmz.com/strategy/21365) + - [从第三方获取K线 (商品期货版) Rev. 161216](https://www.fmz.com/strategy/15498) + - [均线策略 30 行搞定](https://www.fmz.com/strategy/12348) + - [商品期货跨期对冲 - 百行代码实现](https://www.fmz.com/strategy/23896) + - [短信通知类库](https://www.fmz.com/strategy/26921) + - [获取和讯期货数据(Python版本)](https://www.fmz.com/strategy/26017) + - [高频收割机一号](https://www.fmz.com/strategy/6237) + - [R-Breaker 交易策略](https://www.fmz.com/strategy/23531) + - [(13)策略框架](https://www.fmz.com/strategy/20663) + - [均线策略(python版)](https://www.fmz.com/strategy/21157) + - [Python 双平台对冲策略](https://www.fmz.com/strategy/21023) + - [各大平台API可用率统计](https://www.fmz.com/strategy/4404) + - [均线-趋势_数字货币策略V0.2](https://www.fmz.com/strategy/21369) + - [高频交易策略之 - Penny Jump](https://www.fmz.com/strategy/358) + - [stochRSI策略 (指标框架)](https://www.fmz.com/strategy/20383) + - [获取周K线](https://www.fmz.com/strategy/20226) + - [对冲2.7收益率统计系统 支持多组账号统计](https://www.fmz.com/strategy/18678) + - [收益率统计](https://www.fmz.com/strategy/19329) + - [从第三方网站获取K线 (0804更新)](https://www.fmz.com/strategy/12977) + - [不要怂就是干](https://www.fmz.com/strategy/18943) + - [入门模板之各个平台余额](https://www.fmz.com/strategy/48) + - [商品期货主力合约过滤](https://www.fmz.com/strategy/9837) + - [商品期货交易类库(增加下限价单功能)](https://www.fmz.com/strategy/14198) + - [获取OK期货实时限价](https://www.fmz.com/strategy/17028) + - [定期定额投资BTC盈利验证](https://www.fmz.com/strategy/16845) + - [My-1-价值平均定投策略](https://www.fmz.com/strategy/8602) + - [记录净资产变动情况2.0](https://www.fmz.com/strategy/8916) + - [非常简单的策略,但是很有效](https://www.fmz.com/strategy/15085) + - [单独计算收益(代码来自zero)](https://www.fmz.com/strategy/1084) + - [10行人品策略](https://www.fmz.com/strategy/14436) + - [平台价格指标监控1.1](https://www.fmz.com/strategy/12442) + - [窜天猴 - 移动止损版](https://www.fmz.com/strategy/13594) + - [窜天猴 多空较量 爆破版](https://www.fmz.com/strategy/13597) + - [函数自动容错模板](https://www.fmz.com/strategy/11609) + - [RSI_now_sb_ok](https://www.fmz.com/strategy/11604) + - [模板库使用例子](https://www.fmz.com/strategy/10991) + - [价值0.418](https://www.fmz.com/strategy/10744) + - [传统期货差价监控 (CTP)](https://www.fmz.com/strategy/5379) + - [融资融币统计](https://www.fmz.com/strategy/8954) + - [【Demo】如何利用“策略交互“动态调整策略参数](https://www.fmz.com/strategy/8379) + - [【Demo】速度测试 websocket vs rest](https://www.fmz.com/strategy/7547) + - [平台价格比较1.0](https://www.fmz.com/strategy/8266) + - [多平台账户统计](https://www.fmz.com/strategy/7827) + - [阶梯下单 - 可设置触发价格](https://www.fmz.com/strategy/639) + - [796期货反手加倍算法](https://www.fmz.com/strategy/3648) + - [冰山委托 - 支持价格触发 BitVC期货专用](https://www.fmz.com/strategy/951) + - [多线程获取多个交易的深度信息](https://www.fmz.com/strategy/3651) + - [账户余额变动邮箱提醒, 支持添加多个交易所](https://www.fmz.com/strategy/2006) + - [多线程获取多个交易的账户信息](https://www.fmz.com/strategy/3297) + - [OKCoin期货条件触发委托带止损](https://www.fmz.com/strategy/2169) + - [监视并显示多个平台的全部资产总和的变化](https://www.fmz.com/strategy/443) + - [BTC/LTC 地址监视, 短信通知](https://www.fmz.com/strategy/1295) + - [统计K线回测是否存在趋势](https://www.fmz.com/strategy/1125) + - [价格波动报警](https://www.fmz.com/strategy/885) + - [取消所有订单](https://www.fmz.com/strategy/280) + - [新手入门之 - 下买单卖单](https://www.fmz.com/strategy/796) + - [短信通知接口测试](https://www.fmz.com/strategy/653) + - [每1分钟统计各个平台间的差价(by JackConan)](https://www.fmz.com/strategy/98) + - [统计各个平台间的最大差价(by JackConan)](https://www.fmz.com/strategy/86) diff --git "a/RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.js" "b/RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.js" new file mode 100644 index 00000000..d4504219 --- /dev/null +++ "b/RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.js" @@ -0,0 +1,128 @@ +/* +策略出处: https://www.fmz.com/strategy/46605 +策略名称: RSI 双均线策略 +策略作者: yilidalei +策略描述: + + + + +参数 默认值 描述 +-------------- ----- ----- +RSI_Period 14 RSI周期 +MA_fast_Period 10 快线周期 +MA_slow_Period 24 慢线周期 +SuperSellValue 20 超卖阈值 +SuperBuyValue 80 超买阈值 + +按钮 默认值 描述 +---- ---------- ----- +btn1 __button__ test +btn2 __button__ test2 +*/ + +// 以下是测试代码 +/*- 状态 在使用 模板时需要在 主策略内声明 +var TASK_IDLE = 0; +var TASK_OPEN_LONG = 1; +var TASK_OPEN_SHORT = 2; +var TASK_ADD = 3; +var TASK_ST = 4; +var TASK_COVER = 5; +*/ + +// 临时参数 +/* +var RSI_Period = 14; +var MA_fast_Period = 10; +var MA_slow_Period = 200; +var SuperSellValue = 20; +var SuperBuyValue = 80; +*/ + +// 全局变量 +var currency0 = exchanges[0].GetCurrency(); +var ChartObj = null; +var TASK_IDLE = 0; +var TASK_OPEN_LONG = 1; +var TASK_OPEN_SHORT = 2; +var TASK_ADD = 3; +var TASK_ST = 4; +var TASK_COVER = 5; + +function onTick1() { + // 获取K线数据 + var nowTime = new Date().getTime(); + var records = _C(exchanges[0].GetRecords); + if(records.length < Math.abs(RSI_Period, MA_slow_Period, MA_fast_Period)){ + return $.TaskCmd(TASK_IDLE); + } + + var rsi = TA.RSI(records, RSI_Period); + var ma_fast = TA.MA(records, MA_fast_Period); + var ma_slow = TA.MA(records, MA_slow_Period); + + // $.AddData = function(index, dataKey, dataValue) + + // 画图表 + $.PlotRecords(records, currency0); + $.PlotLine('ma_fast' + MA_fast_Period, ma_fast[ma_fast.length - 1], records[records.length - 1].Time); + $.PlotLine('ma_slow' + MA_slow_Period, ma_slow[ma_slow.length - 1], records[records.length - 1].Time); + $.PlotLine('rsi' + RSI_Period, rsi[rsi.length - 1], records[records.length - 1].Time); + + if (rsi[rsi.length - 2] > SuperBuyValue) { + // 标记 + $.PlotFlag(nowTime, 'C', 'CL', 'circlepin', 'blue'); + return $.TaskCmd(TASK_COVER); + }else if(rsi[rsi.length - 2] < SuperSellValue && records[records.length - 1].Close > ma_slow[ma_slow.length - 1] && records[records.length - 1].Close < ma_fast[ma_fast.length - 1]){ + // 标记 + $.PlotFlag(nowTime, 'L', 'L', 'flag', 'red'); + return $.TaskCmd(TASK_OPEN_LONG, 0.5); + } + + return $.TaskCmd(TASK_IDLE); +} + +function main() { + LogReset(1); + ChartObj = Chart(null); + ChartObj.reset(); + ChartObj = $.GetCfg(); + // 处理 指标轴------------------------ + ChartObj.yAxis = [{ + title: {text: 'K线'},//标题 + style: {color: '#4572A7'},//样式 + opposite: false //生成右边Y轴 + }, + { + title:{text: "指标轴"}, + opposite: true, //生成右边Y轴 ceshi + } + ]; + // 初始化指标线 + var records = null; + while(!records || records.length < 30){ + records = _C(exchange.GetRecords); + LogStatus("records.length:", records.length); + Sleep(1000); + } + + $.PlotRecords(records, currency0); + $.PlotLine('ma_fast' + MA_fast_Period, 0, records[records.length - 1].Time); + $.PlotLine('ma_slow' + MA_slow_Period, 0, records[records.length - 1].Time); + var chart = $.PlotLine('rsi' + RSI_Period, 0, records[records.length - 1].Time); + // $.PlotFlag(new Date().getTime(), '开始', 'begin', 'circlepin', 'green'); + // $.PlotFlag(new Date().getTime(), 'CoverLong', 'CL', 'circlepin', 'blue'); + // $.PlotFlag(new Date().getTime(), 'Long', 'L', 'flag', 'red'); + // 修改指标线 坐标轴Y轴 + for(var key in ChartObj.series){ + if(ChartObj.series[key].name == 'rsi' + RSI_Period){ + ChartObj.series[key].yAxis = 1; + } + } + chart.update(ChartObj); + chart.reset(); + + $.Relation_Exchange_onTick(exchanges[0], onTick1); + $.Trend(); // 不用传参数。 +} diff --git a/RSI_now_sb_ok.js b/RSI_now_sb_ok.js index 941714d4..f9ee3422 100644 --- a/RSI_now_sb_ok.js +++ b/RSI_now_sb_ok.js @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/11604 +策略出处: https://www.fmz.com/strategy/11604 策略名称: RSI_now_sb_ok 策略作者: tfboys 策略描述: diff --git a/Shannon's Demon (Copy).js b/Shannon's Demon (Copy).js deleted file mode 100644 index 64235d4a..00000000 --- a/Shannon's Demon (Copy).js +++ /dev/null @@ -1,52 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/69034 -策略名称: Shannon's Demon (Copy) -策略作者: ellajella-0378 -策略描述: - - - - -参数 默认值 描述 ------ ----- -------- -DELAY 30 平衡间隔 -DS 1.04 Sell -DB 1.08 Buy -RSIB 80 RSI Buy -RSIS 20 RSI Sell -*/ - -function onTick(){ - var Account = exchange.GetAccount(); - var Depth = exchange.GetDepth(); - var Buy = Depth.Asks[1].Price; - var Sell = Depth.Bids[1].Price; - var StockValue = Account.Stocks * Buy; - var TotalValue = Account.Balance + StockValue; - var Half = TotalValue / 2; - var Records = exchange.GetRecords(PERIOD_M1); - var RSI = TA.RSI(Records, 14); - //Log("StockValue:", StockValue ," TotalValue:", TotalValue); - var LastRSI = RSI[RSI.length -1]; - //Log(LastRSI); - if (StockValue / Half > DS && LastRSI > RSIS) { - Log("StockValue:", StockValue ," TotalValue:", TotalValue); - Log("StockValue Too High. Re Balancing..."); - var ToBeSold = (Account.Stocks * Buy - Account.Balance) / 2 / Buy; - Log(exchange.Sell(Buy,ToBeSold)); - Sleep(DELAY*1000*5); - } - if (Half / StockValue > DB && LastRSI < RSIB) { - Log("StockValue:", StockValue ," TotalValue:", TotalValue); - Log("StockValue Too Low. Re Balancing..."); - var ToBeBought = (Account.Balance - Account.Stocks * Buy) / 2 / Sell; - Log(exchange.Buy(Sell,ToBeBought)); - Sleep(DELAY*1000*5); - } -} -function main(){ - while(true){ - onTick(); - Sleep(DELAY*1000); - } -} diff --git a/Shannon's Demon.js b/Shannon's Demon.js index 9ea6a5d3..9df8f45c 100644 --- a/Shannon's Demon.js +++ b/Shannon's Demon.js @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/64455 +策略出处: https://www.fmz.com/strategy/64455 策略名称: Shannon's Demon 策略作者: FawkesPan 策略描述: diff --git "a/StochRSI(\345\222\214okcoin\344\270\200\350\207\264).js" "b/StochRSI(\345\222\214okcoin\344\270\200\350\207\264).js" index ded2075d..d023525d 100644 --- "a/StochRSI(\345\222\214okcoin\344\270\200\350\207\264).js" +++ "b/StochRSI(\345\222\214okcoin\344\270\200\350\207\264).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/56119 +策略出处: https://www.fmz.com/strategy/56119 策略名称: StochRSI(和okcoin一致) 策略作者: fangj 策略描述: diff --git a/TableTemplet.js b/TableTemplet.js index 053336ee..314f337f 100644 --- a/TableTemplet.js +++ b/TableTemplet.js @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/44319 +策略出处: https://www.fmz.com/strategy/44319 策略名称: TableTemplet 策略作者: 职业养鸡户 策略描述: diff --git "a/bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.js" "b/bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.js" index cfb8619d..e269b29d 100644 --- "a/bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.js" +++ "b/bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/57333 +策略出处: https://www.fmz.com/strategy/57333 策略名称: bitfinex保证金交易 策略作者: 7meter 策略描述: diff --git "a/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.js" "b/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.js" index 72bab060..fd296608 100644 --- "a/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.js" +++ "b/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/41786 +策略出处: https://www.fmz.com/strategy/41786 策略名称: buy-hold 买入持有 策略作者: ipqhjjybj 策略描述: diff --git "a/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.js" "b/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.js" new file mode 100644 index 00000000..145a4369 --- /dev/null +++ "b/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.js" @@ -0,0 +1,46 @@ +/* +策略出处: https://www.fmz.com/strategy/97791 +策略名称: fcoin挖矿演示 +策略作者: 爆仓小王子 +策略描述: + +看到官方api群里开源的python版本,虽然很简单了,但是还有很多人架不起来环境 +出问题的原因也有很多种,不太适合新手 +本着开源共享的精神,我也开源一份,请大家斧正 + + +参数 默认值 描述 +------ ----- ------- +Amount 10 下单量 +Wait true 等待间隔(秒) +*/ + +function DealOrder(orderType, sellPrice) { + var ticker = _C(exchange.GetTicker); + var action = orderType == ORDER_TYPE_BUY ? 'Buy' : 'Sell'; + _C(exchange[action], (orderType == ORDER_TYPE_SELL ? sellPrice : ticker.Last), Amount); + var recentPrice = ticker.Last; + while (true) { + Sleep(Wait*1000); + var orders = _C(exchange.GetOrders); + if (orders == 0) { + break; + } + ticker = _C(exchange.GetTicker); + _.each(orders, function(o) { + if (o.DealAmount == 0 && ((o.Type == ORDER_TYPE_SELL && ticker.Last >= sellPrice && ticker.Last != recentPrice) || (ticker.Last != recentPrice && o.Type == ORDER_TYPE_BUY))) { + exchange.CancelOrder(o.Id); + recentPrice = ticker.Last + _C(exchange[action], ticker.Last, Amount); + } + }); + } + return recentPrice; +} +function main() { + while (true) { + DealOrder(ORDER_TYPE_SELL, DealOrder(ORDER_TYPE_BUY)); + Sleep(1000); + } +} + diff --git a/js R-Breaker.js b/js R-Breaker.js index 1982285e..f21396d1 100644 --- a/js R-Breaker.js +++ b/js R-Breaker.js @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/36195 +策略出处: https://www.fmz.com/strategy/36195 策略名称: js R-Breaker 策略作者: 太极 策略描述: diff --git "a/okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.js" "b/okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.js" index 60c4135f..26c97e85 100644 --- "a/okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.js" +++ "b/okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/83189 +策略出处: https://www.fmz.com/strategy/83189 策略名称: okex-BTC合约账户公开 策略作者: leviyuan 策略描述: diff --git "a/okex\345\270\201\345\270\201\346\234\200\345\260\217\344\272\244\346\230\223\351\207\217.js" "b/okex\345\270\201\345\270\201\346\234\200\345\260\217\344\272\244\346\230\223\351\207\217.js" new file mode 100644 index 00000000..867b5707 --- /dev/null +++ "b/okex\345\270\201\345\270\201\346\234\200\345\260\217\344\272\244\346\230\223\351\207\217.js" @@ -0,0 +1,520 @@ +/* +策略出处: https://www.fmz.com/strategy/88754 +策略名称: okex币币最小交易量 +策略作者: leviyuan +策略描述: + + + +*/ + +// 数据来源 https://github.com/okcoin-okex/API-docs-OKEx.com/blob/master/%E5%B8%81%E5%B8%81%E6%9C%80%E5%B0%8F%E4%BA%A4%E6%98%93%E9%87%8F(min_trade_size%20for%20spot).mda_btc +// 更新时间 2018-4-25 13:37 +function main() { + Log(exchange.GetCurrency(), $.GetMinTradeSize(0)) +} + +var min_trade_size = {} + +min_trade_size.bch_btc = 0.001 +min_trade_size.ltc_btc = 0.001 +min_trade_size.eth_btc = 0.001 +min_trade_size.etc_btc = 0.01 +min_trade_size.eth_usdt = 0.001 +min_trade_size.btc_usdt = 0.001 +min_trade_size.bt2_btc = 0.01 +min_trade_size.etc_eth = 0.01 +min_trade_size.btg_btc = 0.01 +min_trade_size.ltc_usdt = 0.001 +min_trade_size.etc_usdt = 0.01 +min_trade_size.bch_usdt = 0.001 +min_trade_size.qtum_btc = 0.01 +min_trade_size.qtum_usdt = 0.01 +min_trade_size.qtum_eth = 0.01 +min_trade_size.neo_btc = 0.01 +min_trade_size.gas_btc = 0.01 +min_trade_size.hsr_btc = 0.1 +min_trade_size.neo_eth = 0.01 +min_trade_size.gas_eth = 0.01 +min_trade_size.hsr_eth = 0.1 +min_trade_size.neo_usdt = 0.01 +min_trade_size.gas_usdt = 0.01 +min_trade_size.hsr_usdt = 0.1 +min_trade_size.dash_btc = 0.001 +min_trade_size.xrp_btc = 1 +min_trade_size.zec_btc = 0.001 +min_trade_size.dash_eth = 0.001 +min_trade_size.xrp_eth = 1 +min_trade_size.zec_eth = 0.001 +min_trade_size.dash_usdt = 0.001 +min_trade_size.xrp_usdt = 1 +min_trade_size.zec_usdt = 0.001 +min_trade_size.iota_btc = 1 +min_trade_size.xuc_btc = 0.1 +min_trade_size.iota_eth = 1 +min_trade_size.xuc_eth = 0.1 +min_trade_size.iota_usdt = 1 +min_trade_size.xuc_usdt = 0.1 +min_trade_size.eos_btc = 0.1 +min_trade_size.omg_btc = 0.1 +min_trade_size.eos_eth = 0.1 +min_trade_size.omg_eth = 0.1 +min_trade_size.eos_usdt = 0.1 +min_trade_size.omg_usdt = 0.1 +min_trade_size.act_btc = 1 +min_trade_size.btm_btc = 1 +min_trade_size.act_eth = 1 +min_trade_size.btm_eth = 1 +min_trade_size.act_usdt = 1 +min_trade_size.btm_usdt = 1 +min_trade_size.bcd_btc = 0.1 +min_trade_size.bcd_usdt = 0.1 +min_trade_size.storj_btc = 1 +min_trade_size.snt_btc = 10 +min_trade_size.storj_eth = 1 +min_trade_size.snt_eth = 10 +min_trade_size.storj_usdt = 1 +min_trade_size.snt_usdt = 10 +min_trade_size.pay_btc = 1 +min_trade_size.dgd_btc = 0.001 +min_trade_size.gnt_btc = 1 +min_trade_size.pay_eth = 1 +min_trade_size.dgd_eth = 0.001 +min_trade_size.gnt_eth = 1 +min_trade_size.pay_usdt = 1 +min_trade_size.dgd_usdt = 0.001 +min_trade_size.gnt_usdt = 1 +min_trade_size.lrc_btc = 1 +min_trade_size.nuls_btc = 0.1 +min_trade_size.mco_btc = 0.1 +min_trade_size.lrc_eth = 1 +min_trade_size.nuls_eth = 0.1 +min_trade_size.mco_eth = 0.1 +min_trade_size.lrc_usdt = 1 +min_trade_size.nuls_usdt = 0.1 +min_trade_size.mco_usdt = 0.1 +min_trade_size.btg_usdt = 0.01 +min_trade_size.cmt_btc = 10 +min_trade_size.itc_btc = 1 +min_trade_size.cmt_eth = 10 +min_trade_size.itc_eth = 1 +min_trade_size.cmt_usdt = 10 +min_trade_size.itc_usdt = 1 +min_trade_size.sbtc_btc = 0.1 +min_trade_size.pra_btc = 1 +min_trade_size.san_btc = 1 +min_trade_size.edo_btc = 0.1 +min_trade_size.avt_btc = 1 +min_trade_size.pra_eth = 1 +min_trade_size.san_eth = 1 +min_trade_size.edo_eth = 0.1 +min_trade_size.avt_eth = 1 +min_trade_size.pra_usdt = 1 +min_trade_size.san_usdt = 1 +min_trade_size.edo_usdt = 1 +min_trade_size.avt_usdt = 1 +min_trade_size.ltc_bch = 0.001 +min_trade_size.ltc_eth = 0.001 +min_trade_size.etc_bch = 0.01 +min_trade_size.btg_bch = 0.01 +min_trade_size.avt_bch = 1 +min_trade_size.act_bch = 1 +min_trade_size.cmt_bch = 10 +min_trade_size.dgd_bch = 0.001 +min_trade_size.dash_bch = 0.001 +min_trade_size.eos_bch = 0.1 +min_trade_size.edo_bch = 0.1 +min_trade_size.ctr_btc = 1 +min_trade_size.link_btc = 1 +min_trade_size.salt_btc = 0.1 +min_trade_size['1st_btc'] = 1 +min_trade_size.wtc_btc = 0.1 +min_trade_size.sngls_btc = 10 +min_trade_size.snm_btc = 10 +min_trade_size.zrx_btc = 1 +min_trade_size.bnt_btc = 0.1 +min_trade_size.cvc_btc = 1 +min_trade_size.ctr_eth = 1 +min_trade_size.link_eth = 1 +min_trade_size.salt_eth = 0.1 +min_trade_size['1st_eth'] = 1 +min_trade_size.wtc_eth = 0.1 +min_trade_size.sngls_eth = 10 +min_trade_size.snm_eth = 10 +min_trade_size.zrx_eth = 1 +min_trade_size.bnt_eth = 0.1 +min_trade_size.cvc_eth = 1 +min_trade_size.ctr_usdt = 1 +min_trade_size.link_usdt = 1 +min_trade_size.salt_usdt = 0.1 +min_trade_size['1st_usdt'] = 1 +min_trade_size.wtc_usdt = 0.1 +min_trade_size.sngls_usdt = 10 +min_trade_size.snm_usdt = 10 +min_trade_size.zrx_usdt = 1 +min_trade_size.bnt_usdt = 0.1 +min_trade_size.cvc_usdt = 1 +min_trade_size.bcd_bch = 0.1 +min_trade_size.sbtc_bch = 0.1 +min_trade_size.bcx_btc = 10 +min_trade_size.bcx_bch = 10 +min_trade_size.mana_btc = 10 +min_trade_size.rcn_btc = 10 +min_trade_size.mana_eth = 10 +min_trade_size.mana_usdt = 10 +min_trade_size.vee_btc = 10 +min_trade_size.vee_eth = 10 +min_trade_size.vee_usdt = 10 +min_trade_size.tnb_btc = 10 +min_trade_size.tnb_eth = 10 +min_trade_size.tnb_usdt = 10 +min_trade_size.amm_btc = 1 +min_trade_size.amm_eth = 1 +min_trade_size.amm_usdt = 1 +min_trade_size.knc_btc = 1 +min_trade_size.knc_eth = 1 +min_trade_size.knc_usdt = 1 +min_trade_size.dat_eth = 10 +min_trade_size.dat_btc = 10 +min_trade_size.dat_usdt = 10 +min_trade_size.gnx_btc = 1 +min_trade_size.gnx_eth = 1 +min_trade_size.gnx_usdt = 1 +min_trade_size.icx_btc = 0.1 +min_trade_size.icx_eth = 0.1 +min_trade_size.icx_usdt = 0.1 +min_trade_size.ark_btc = 0.1 +min_trade_size.ark_eth = 0.1 +min_trade_size.ark_usdt = 0.1 +min_trade_size.yoyo_btc = 10 +min_trade_size.yoyo_eth = 10 +min_trade_size.yoyo_usdt = 10 +min_trade_size.qvt_btc = 1 +min_trade_size.qvt_eth = 1 +min_trade_size.qvt_usdt = 1 +min_trade_size.elf_eth = 1 +min_trade_size.elf_btc = 1 +min_trade_size.elf_usdt = 1 +min_trade_size.ast_btc = 1 +min_trade_size.ast_eth = 1 +min_trade_size.ast_usdt = 1 +min_trade_size.sub_btc = 1 +min_trade_size.sub_eth = 1 +min_trade_size.sub_usdt = 1 +min_trade_size.dnt_btc = 10 +min_trade_size.dnt_eth = 10 +min_trade_size.dnt_usdt = 10 +min_trade_size.fun_btc = 10 +min_trade_size.fun_eth = 10 +min_trade_size.fun_usdt = 10 +min_trade_size.ace_btc = 10 +min_trade_size.ace_eth = 10 +min_trade_size.ace_usdt = 10 +min_trade_size.trx_btc = 10 +min_trade_size.trx_eth = 10 +min_trade_size.trx_usdt = 10 +min_trade_size.evx_btc = 1 +min_trade_size.evx_eth = 0.1 +min_trade_size.evx_usdt = 1 +min_trade_size.mda_btc = 1 +min_trade_size.mda_eth = 1 +min_trade_size.mda_usdt = 1 +min_trade_size.mth_btc = 10 +min_trade_size.mth_eth = 10 +min_trade_size.mth_usdt = 10 +min_trade_size.mtl_btc = 0.1 +min_trade_size.mtl_eth = 0.1 +min_trade_size.mtl_usdt = 0.1 +min_trade_size.xem_btc = 1 +min_trade_size.xem_eth = 1 +min_trade_size.xem_usdt = 1 +min_trade_size.icn_btc = 1 +min_trade_size.icn_eth = 1 +min_trade_size.icn_usdt = 1 +min_trade_size.eng_btc = 0.1 +min_trade_size.req_btc = 1 +min_trade_size.oax_btc = 1 +min_trade_size.dgb_btc = 10 +min_trade_size.ppt_btc = 0.01 +min_trade_size.dgb_eth = 10 +min_trade_size.dgb_usdt = 10 +min_trade_size.ppt_eth = 0.01 +min_trade_size.ppt_usdt = 0.01 +min_trade_size.oax_eth = 1 +min_trade_size.oax_usdt = 1 +min_trade_size.req_eth = 1 +min_trade_size.req_usdt = 1 +min_trade_size.eng_eth = 0.1 +min_trade_size.eng_usdt = 0.1 +min_trade_size.rcn_eth = 10 +min_trade_size.rcn_usdt = 10 +min_trade_size.swftc_btc = 10 +min_trade_size.swftc_eth = 10 +min_trade_size.swftc_usdt = 10 +min_trade_size.rdn_btc = 0.1 +min_trade_size.rdn_eth = 0.1 +min_trade_size.rdn_usdt = 0.1 +min_trade_size.xmr_btc = 0.001 +min_trade_size.xmr_eth = 0.001 +min_trade_size.xmr_usdt = 0.001 +min_trade_size.xlm_btc = 1 +min_trade_size.xlm_eth = 1 +min_trade_size.xlm_usdt = 1 +min_trade_size.kcash_btc = 10 +min_trade_size.kcash_eth = 10 +min_trade_size.kcash_usdt = 10 +min_trade_size.mdt_btc = 10 +min_trade_size.mdt_eth = 10 +min_trade_size.mdt_usdt = 10 +min_trade_size.nas_btc = 0.1 +min_trade_size.nas_eth = 0.1 +min_trade_size.nas_usdt = 0.1 +min_trade_size.rnt_btc = 10 +min_trade_size.rnt_eth = 10 +min_trade_size.rnt_usdt = 10 +min_trade_size.wrc_btc = 10 +min_trade_size.wrc_eth = 10 +min_trade_size.wrc_usdt = 10 +min_trade_size.ukg_btc = 1 +min_trade_size.ukg_eth = 1 +min_trade_size.ukg_usdt = 1 +min_trade_size.ugc_btc = 10 +min_trade_size.ugc_eth = 10 +min_trade_size.ugc_usdt = 10 +min_trade_size.dpy_btc = 1 +min_trade_size.dpy_eth = 1 +min_trade_size.dpy_usdt = 1 +min_trade_size.read_btc = 10 +min_trade_size.read_eth = 10 +min_trade_size.read_usdt = 10 +min_trade_size.ssc_btc = 10 +min_trade_size.ssc_eth = 10 +min_trade_size.ssc_usdt = 10 +min_trade_size.aac_btc = 10 +min_trade_size.smt_btc = 10 +min_trade_size.fair_btc = 10 +min_trade_size.aac_eth = 10 +min_trade_size.smt_eth = 10 +min_trade_size.aac_usdt = 10 +min_trade_size.smt_usdt = 10 +min_trade_size.fair_eth = 10 +min_trade_size.fair_usdt = 10 +min_trade_size.ubtc_btc = 0.1 +min_trade_size.ubtc_eth = 0.1 +min_trade_size.ubtc_usdt = 0.1 +min_trade_size.cag_btc = 1 +min_trade_size.cag_eth = 1 +min_trade_size.cag_usdt = 1 +min_trade_size.dna_btc = 1 +min_trade_size.lend_btc = 10 +min_trade_size.lend_eth = 10 +min_trade_size.dna_eth = 1 +min_trade_size.lend_usdt = 10 +min_trade_size.dna_usdt = 1 +min_trade_size.rct_btc = 10 +min_trade_size.rct_eth = 10 +min_trade_size.rct_usdt = 10 +min_trade_size.bch_eth = 0.001 +min_trade_size.show_btc = 10 +min_trade_size.show_eth = 10 +min_trade_size.show_usdt = 10 +min_trade_size.vib_btc = 1 +min_trade_size.vib_eth = 1 +min_trade_size.vib_usdt = 1 +min_trade_size.mot_btc = 1 +min_trade_size.mot_eth = 1 +min_trade_size.mot_usdt = 1 +min_trade_size.utk_btc = 10 +min_trade_size.utk_eth = 10 +min_trade_size.utk_usdt = 1 +min_trade_size.mag_btc = 10 +min_trade_size.mag_eth = 10 +min_trade_size.mag_usdt = 10 +min_trade_size.topc_btc = 10 +min_trade_size.topc_eth = 10 +min_trade_size.brd_btc = 1 +min_trade_size.topc_usdt = 10 +min_trade_size.qun_btc = 10 +min_trade_size.brd_eth = 1 +min_trade_size.qun_eth = 10 +min_trade_size.qun_usdt = 10 +min_trade_size.brd_usdt = 1 +min_trade_size.viu_btc = 10 +min_trade_size.viu_eth = 10 +min_trade_size.ost_btc = 1 +min_trade_size.viu_usdt = 10 +min_trade_size.ost_eth = 1 +min_trade_size.ost_usdt = 1 +min_trade_size.aidoc_btc = 10 +min_trade_size.aidoc_eth = 10 +min_trade_size.aidoc_usdt = 10 +min_trade_size.int_btc = 10 +min_trade_size.la_btc = 1 +min_trade_size.la_eth = 1 +min_trade_size.la_usdt = 1 +min_trade_size.int_eth = 10 +min_trade_size.int_usdt = 10 +min_trade_size.ipc_btc = 1 +min_trade_size.ipc_eth = 1 +min_trade_size.ipc_usdt = 1 +min_trade_size.ngc_btc = 1 +min_trade_size.ngc_eth = 1 +min_trade_size.ngc_usdt = 1 +min_trade_size.tio_btc = 1 +min_trade_size.tio_eth = 1 +min_trade_size.tio_usdt = 1 +min_trade_size.iost_btc = 10 +min_trade_size.iost_eth = 10 +min_trade_size.iost_usdt = 10 +min_trade_size.poe_btc = 10 +min_trade_size.poe_eth = 10 +min_trade_size.poe_usdt = 10 +min_trade_size.mof_btc = 1 +min_trade_size.yee_btc = 10 +min_trade_size.mof_eth = 1 +min_trade_size.yee_eth = 10 +min_trade_size.yee_usdt = 10 +min_trade_size.mof_usdt = 1 +min_trade_size.ins_btc = 1 +min_trade_size.ins_eth = 1 +min_trade_size.ins_usdt = 0.1 +min_trade_size.tct_btc = 10 +min_trade_size.tct_eth = 10 +min_trade_size.tct_usdt = 10 +min_trade_size.atl_btc = 1 +min_trade_size.atl_eth = 1 +min_trade_size.atl_usdt = 1 +min_trade_size.theta_btc = 10 +min_trade_size.theta_eth = 10 +min_trade_size.lev_btc = 10 +min_trade_size.theta_usdt = 10 +min_trade_size.lev_eth = 10 +min_trade_size.lev_usdt = 10 +min_trade_size.stc_btc = 10 +min_trade_size.spf_btc = 1 +min_trade_size.stc_eth = 10 +min_trade_size.spf_eth = 1 +min_trade_size.spf_usdt = 1 +min_trade_size.stc_usdt = 10 +min_trade_size.ref_btc = 0.01 +min_trade_size.ref_eth = 0.01 +min_trade_size.ref_usdt = 0.01 +min_trade_size.snc_btc = 1 +min_trade_size.snc_eth = 1 +min_trade_size.snc_usdt = 1 +min_trade_size.pst_btc = 1 +min_trade_size.pst_eth = 1 +min_trade_size.pst_usdt = 1 +min_trade_size.can_btc = 10 +min_trade_size.can_eth = 10 +min_trade_size.can_usdt = 10 +min_trade_size.hot_btc = 10 +min_trade_size.mkr_btc = 0.001 +min_trade_size.mkr_eth = 0.001 +min_trade_size.mkr_usdt = 0.001 +min_trade_size.hot_eth = 10 +min_trade_size.key_btc = 10 +min_trade_size.hot_usdt = 10 +min_trade_size.key_eth = 10 +min_trade_size.key_usdt = 10 +min_trade_size.light_btc = 10 +min_trade_size.light_eth = 10 +min_trade_size.light_usdt = 10 +min_trade_size.true_btc = 1 +min_trade_size.true_eth = 1 +min_trade_size.true_usdt = 1 +min_trade_size.of_btc = 10 +min_trade_size.of_eth = 10 +min_trade_size.of_usdt = 10 +min_trade_size.soc_btc = 10 +min_trade_size.soc_eth = 10 +min_trade_size.soc_usdt = 10 +min_trade_size.wbtc_btc = 10 +min_trade_size.dent_btc = 10 +min_trade_size.dent_eth = 10 +min_trade_size.dent_usdt = 10 +min_trade_size.zen_btc = 0.01 +min_trade_size.zen_eth = 0.01 +min_trade_size.zen_usdt = 0.01 +min_trade_size.hmc_btc = 10 +min_trade_size.hmc_eth = 10 +min_trade_size.hmc_usdt = 10 +min_trade_size.zip_btc = 10 +min_trade_size.zip_eth = 10 +min_trade_size.zip_usdt = 10 +min_trade_size.nano_btc = 0.1 +min_trade_size.nano_eth = 0.1 +min_trade_size.nano_usdt = 0.1 +min_trade_size.cic_btc = 10 +min_trade_size.cic_eth = 10 +min_trade_size.cic_usdt = 10 +min_trade_size.gto_btc = 1 +min_trade_size.gto_eth = 1 +min_trade_size.gto_usdt = 1 +min_trade_size.chat_btc = 10 +min_trade_size.chat_eth = 10 +min_trade_size.chat_usdt = 10 +min_trade_size.insur_btc = 10 +min_trade_size.insur_eth = 10 +min_trade_size.insur_usdt = 10 +min_trade_size.cbt_btc = 10 +min_trade_size.cbt_eth = 10 +min_trade_size.cbt_usdt = 10 +min_trade_size.r_btc = 1 +min_trade_size.r_eth = 1 +min_trade_size.r_usdt = 1 +min_trade_size.uct_btc = 10 +min_trade_size.uct_eth = 1 +min_trade_size.uct_usdt = 1 +min_trade_size.bec_btc = 1 +min_trade_size.bec_eth = 1 +min_trade_size.bec_usdt = 1 +min_trade_size.mith_btc = 1 +min_trade_size.mith_eth = 1 +min_trade_size.mith_usdt = 1 +min_trade_size.abt_btc = 1 +min_trade_size.abt_eth = 1 +min_trade_size.abt_usdt = 1 +min_trade_size.bkx_btc = 1 +min_trade_size.bkx_eth = 1 +min_trade_size.bkx_usdt = 1 +min_trade_size.gtc_btc = 10 +min_trade_size.gtc_eth = 10 +min_trade_size.gtc_usdt = 10 +min_trade_size.auto_btc = 10 +min_trade_size.auto_eth = 10 +min_trade_size.auto_usdt = 10 +min_trade_size.gsc_btc = 10 +min_trade_size.gsc_eth = 10 +min_trade_size.gsc_usdt = 10 +min_trade_size.rfr_btc = 10 +min_trade_size.rfr_eth = 10 +min_trade_size.rfr_usdt = 10 +min_trade_size.trio_btc = 10 +min_trade_size.trio_eth = 10 +min_trade_size.trio_usdt = 10 +min_trade_size.tra_btc = 10 +min_trade_size.tra_eth = 10 +min_trade_size.tra_usdt = 10 +min_trade_size.ren_btc = 10 +min_trade_size.ren_eth = 10 +min_trade_size.ren_usdt = 10 +min_trade_size.wfee_btc = 10 +min_trade_size.wfee_eth = 10 +min_trade_size.wfee_usdt = 10 +min_trade_size.dadi_btc = 1 +min_trade_size.dadi_eth = 1 +min_trade_size.dadi_usdt = 1 +min_trade_size.enj_btc = 10 +min_trade_size.enj_eth = 10 +min_trade_size.enj_usdt = 10 +min_trade_size.ont_btc = 1 +min_trade_size.ont_eth = 1 +min_trade_size.ont_usdt = 1 + +$.GetMinTradeSize = function(exchIndex) { + var currency = exchanges[exchIndex].GetCurrency().toLowerCase() + if (min_trade_size[currency] == null) + return 0 + return min_trade_size[currency] +} diff --git "a/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" "b/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" index 102be53f..00a2b8e9 100644 --- "a/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" +++ "b/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/21856 +策略出处: https://www.fmz.com/strategy/21856 策略名称: python版 Dual Thrust OKCoin 期货 策略作者: 小小梦 策略描述: diff --git "a/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" "b/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" index 37f20c8d..9216ce45 100644 --- "a/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" +++ "b/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/39066 +策略出处: https://www.fmz.com/strategy/39066 策略名称: python版 画线类库 (兼容2-3) 策略作者: 小小梦 策略描述: diff --git "a/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" "b/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" index 2f9d66c3..3eeb0682 100644 --- "a/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" +++ "b/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/24288 +策略出处: https://www.fmz.com/strategy/24288 策略名称: python版CTP商品期货交易类库(支持2-3 测试版) 策略作者: 小小梦 策略描述: diff --git "a/python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.py" "b/python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.py" index 3d9b9ba5..6dfdeb0d 100644 --- "a/python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.py" +++ "b/python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/21104 +策略出处: https://www.fmz.com/strategy/21104 策略名称: python版现货数字货币交易类库 策略作者: 小小梦 策略描述: diff --git "a/stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).js" "b/stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).js" index f0b0c879..d9889072 100644 --- "a/stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).js" +++ "b/stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/20383 +策略出处: https://www.fmz.com/strategy/20383 策略名称: stochRSI策略 (指标框架) 策略作者: 小小梦 策略描述: diff --git "a/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" "b/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" index ffaa3f3b..cbc686c7 100644 --- "a/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" +++ "b/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/62163 +策略出处: https://www.fmz.com/strategy/62163 策略名称: talib简单应用之查找三只乌鸦 策略作者: Zero 策略描述: diff --git "a/\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.js" "b/\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.js" index cb06479d..5f8f0cfc 100644 --- "a/\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.js" +++ "b/\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/82325 +策略出处: https://www.fmz.com/strategy/82325 策略名称: 【001】单平台均衡策略 【研究】 策略作者: 风利 策略描述: diff --git "a/\343\200\220Demo\343\200\221\345\246\202\344\275\225\345\210\251\347\224\250\342\200\234\347\255\226\347\225\245\344\272\244\344\272\222\342\200\234\345\212\250\346\200\201\350\260\203\346\225\264\347\255\226\347\225\245\345\217\202\346\225\260.js" "b/\343\200\220Demo\343\200\221\345\246\202\344\275\225\345\210\251\347\224\250\342\200\234\347\255\226\347\225\245\344\272\244\344\272\222\342\200\234\345\212\250\346\200\201\350\260\203\346\225\264\347\255\226\347\225\245\345\217\202\346\225\260.js" index a8a05658..740c1930 100644 --- "a/\343\200\220Demo\343\200\221\345\246\202\344\275\225\345\210\251\347\224\250\342\200\234\347\255\226\347\225\245\344\272\244\344\272\222\342\200\234\345\212\250\346\200\201\350\260\203\346\225\264\347\255\226\347\225\245\345\217\202\346\225\260.js" +++ "b/\343\200\220Demo\343\200\221\345\246\202\344\275\225\345\210\251\347\224\250\342\200\234\347\255\226\347\225\245\344\272\244\344\272\222\342\200\234\345\212\250\346\200\201\350\260\203\346\225\264\347\255\226\347\225\245\345\217\202\346\225\260.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/8379 +策略出处: https://www.fmz.com/strategy/8379 策略名称: 【Demo】如何利用“策略交互“动态调整策略参数 策略作者: momox 策略描述: diff --git "a/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest.js" "b/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest.js" index 0af859e0..256db892 100644 --- "a/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest.js" +++ "b/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/7547 +策略出处: https://www.fmz.com/strategy/7547 策略名称: 【Demo】速度测试 websocket vs rest 策略作者: momox 策略描述: diff --git "a/\344\270\200\347\233\256\345\235\207\350\241\241.js" "b/\344\270\200\347\233\256\345\235\207\350\241\241.js" index d6d21fd4..e4e1941a 100644 --- "a/\344\270\200\347\233\256\345\235\207\350\241\241.js" +++ "b/\344\270\200\347\233\256\345\235\207\350\241\241.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/55839 +策略出处: https://www.fmz.com/strategy/55839 策略名称: 一目均衡 策略作者: icesun963 策略描述: diff --git "a/\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262 (Copy).js" "b/\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262 (Copy).js" deleted file mode 100644 index a4277892..00000000 --- "a/\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262 (Copy).js" +++ /dev/null @@ -1,74 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/65114 -策略名称: 不要怂就是干 (Copy) -策略作者: woopoin -策略描述: - -"Talk is cheap. Show me the code" - - -注: ` 策略使用了交易模板类库` - -`希望新手从此策略入门, 一步步学习编写策略, 并体验到模拟与真实环境对交易系统的影响` - -https://dn-filebox.qbox.me/fb4d0c7d773ca83e9d0230927705d419dc0bbeaa.png - - -参数 默认值 描述 -------------- ----- ------- -EnterPeriod 2 入市观察期 -FastPeriod 5 入市快线周期 -SlowPeriod 30 入市慢线周期 -PositionRatio true 仓位比例 -Interval 10 轮询周期(秒) -SlidePrice 0.01 滑动值 - -按钮 默认值 描述 ----- ---------- ---- -简单策略 __button__ 不懂 -*/ - -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); - } -} diff --git "a/\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262.js" "b/\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262.js" index 5eee5689..8036595c 100644 --- "a/\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262.js" +++ "b/\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/18943 +策略出处: https://www.fmz.com/strategy/18943 策略名称: 不要怂就是干 策略作者: qq110888000 策略描述: diff --git "a/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" "b/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" index 019edd3d..9b12a102 100644 --- "a/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" +++ "b/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/76827 +策略出处: https://www.fmz.com/strategy/76827 策略名称: 五线向上&&突破前高 策略作者: 围龙小子 策略描述: diff --git "a/\344\273\216\347\254\254\344\270\211\346\226\271\347\275\221\347\253\231\350\216\267\345\217\226K\347\272\277 (0804\346\233\264\346\226\260).js" "b/\344\273\216\347\254\254\344\270\211\346\226\271\347\275\221\347\253\231\350\216\267\345\217\226K\347\272\277 (0804\346\233\264\346\226\260).js" index e65ec1af..d6ef80d5 100644 --- "a/\344\273\216\347\254\254\344\270\211\346\226\271\347\275\221\347\253\231\350\216\267\345\217\226K\347\272\277 (0804\346\233\264\346\226\260).js" +++ "b/\344\273\216\347\254\254\344\270\211\346\226\271\347\275\221\347\253\231\350\216\267\345\217\226K\347\272\277 (0804\346\233\264\346\226\260).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/12977 +策略出处: https://www.fmz.com/strategy/12977 策略名称: 从第三方网站获取K线 (0804更新) 策略作者: 数·狂 策略描述: diff --git "a/\344\273\216\347\254\254\344\270\211\346\226\271\350\216\267\345\217\226K\347\272\277 (\345\225\206\345\223\201\346\234\237\350\264\247\347\211\210) Rev. 161216.js" "b/\344\273\216\347\254\254\344\270\211\346\226\271\350\216\267\345\217\226K\347\272\277 (\345\225\206\345\223\201\346\234\237\350\264\247\347\211\210) Rev. 161216.js" index 7635807c..2e14f932 100644 --- "a/\344\273\216\347\254\254\344\270\211\346\226\271\350\216\267\345\217\226K\347\272\277 (\345\225\206\345\223\201\346\234\237\350\264\247\347\211\210) Rev. 161216.js" +++ "b/\344\273\216\347\254\254\344\270\211\346\226\271\350\216\267\345\217\226K\347\272\277 (\345\225\206\345\223\201\346\234\237\350\264\247\347\211\210) Rev. 161216.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/15498 +策略出处: https://www.fmz.com/strategy/15498 策略名称: 从第三方获取K线 (商品期货版) Rev. 161216 策略作者: 数·狂 策略描述: diff --git "a/\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.js" "b/\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.js" index 4506145e..bdd4479f 100644 --- "a/\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.js" +++ "b/\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/54182 +策略出处: https://www.fmz.com/strategy/54182 策略名称: 仓位均衡策略 策略作者: 春哥 策略描述: diff --git "a/\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.js" "b/\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.js" index d1cbe563..ccc31da2 100644 --- "a/\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.js" +++ "b/\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/69436 +策略出处: https://www.fmz.com/strategy/69436 策略名称: 代替废弃的GetMinStock()函数 策略作者: hugo_zhou 策略描述: diff --git "a/\344\273\267\345\200\2740.418.js" "b/\344\273\267\345\200\2740.418.js" index d6fcc6b7..f0eb7684 100644 --- "a/\344\273\267\345\200\2740.418.js" +++ "b/\344\273\267\345\200\2740.418.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/10744 +策略出处: https://www.fmz.com/strategy/10744 策略名称: 价值0.418 策略作者: kakababy 策略描述: diff --git "a/\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225.js" "b/\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225.js" index 4c7d19c5..a99c648c 100644 --- "a/\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225.js" +++ "b/\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/67128 +策略出处: https://www.fmz.com/strategy/67128 策略名称: 价值平均定投 策略作者: 小码哥 策略描述: diff --git "a/\344\273\267\346\240\274\346\263\242\345\212\250\346\212\245\350\255\246.js" "b/\344\273\267\346\240\274\346\263\242\345\212\250\346\212\245\350\255\246.js" index a736a7a0..0a6a6973 100644 --- "a/\344\273\267\346\240\274\346\263\242\345\212\250\346\212\245\350\255\246.js" +++ "b/\344\273\267\346\240\274\346\263\242\345\212\250\346\212\245\350\255\246.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/885 +策略出处: https://www.fmz.com/strategy/885 策略名称: 价格波动报警 策略作者: Zero 策略描述: diff --git "a/\344\274\240\347\273\237\346\234\237\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247 (CTP).js" "b/\344\274\240\347\273\237\346\234\237\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247 (CTP).js" index 29e73200..2e5b2ff8 100644 --- "a/\344\274\240\347\273\237\346\234\237\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247 (CTP).js" +++ "b/\344\274\240\347\273\237\346\234\237\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247 (CTP).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/5379 +策略出处: https://www.fmz.com/strategy/5379 策略名称: 传统期货差价监控 (CTP) 策略作者: Zero 策略描述: diff --git "a/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.js" "b/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.js" index 87293a1d..e420efef 100644 --- "a/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.js" +++ "b/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/40357 +策略出处: https://www.fmz.com/strategy/40357 策略名称: 使用 BotVS 构建一个机械化策略 策略作者: 小小梦 策略描述: diff --git "a/\345\205\245\351\227\250\346\250\241\346\235\277\344\271\213\345\220\204\344\270\252\345\271\263\345\217\260\344\275\231\351\242\235.js" "b/\345\205\245\351\227\250\346\250\241\346\235\277\344\271\213\345\220\204\344\270\252\345\271\263\345\217\260\344\275\231\351\242\235.js" index 80349d0d..1185b53b 100644 --- "a/\345\205\245\351\227\250\346\250\241\346\235\277\344\271\213\345\220\204\344\270\252\345\271\263\345\217\260\344\275\231\351\242\235.js" +++ "b/\345\205\245\351\227\250\346\250\241\346\235\277\344\271\213\345\220\204\344\270\252\345\271\263\345\217\260\344\275\231\351\242\235.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/48 +策略出处: https://www.fmz.com/strategy/48 策略名称: 入门模板之各个平台余额 策略作者: Zero 策略描述: diff --git "a/\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.js" "b/\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.js" index 16d0e29e..30249525 100644 --- "a/\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.js" +++ "b/\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/25943 +策略出处: https://www.fmz.com/strategy/25943 策略名称: 全球10大交易系统之 Aberration 多品种商品期货交易系统 策略作者: Zero 策略描述: diff --git "a/\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.js" "b/\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.js" index 31e63b58..cc74e608 100644 --- "a/\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.js" +++ "b/\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/82929 +策略出处: https://www.fmz.com/strategy/82929 策略名称: 内外盘期货品种实时差价图 策略作者: Zero 策略描述: diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.js" "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.js" index b12c9e77..6d245a30 100644 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.js" +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/236 +策略出处: https://www.fmz.com/strategy/236 策略名称: 冰山委托 - 买入 策略作者: Zero 策略描述: diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.js" "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.js" index a16dc837..67fc9ff0 100644 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.js" +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/241 +策略出处: https://www.fmz.com/strategy/241 策略名称: 冰山委托 - 卖出 策略作者: Zero 策略描述: diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \346\224\257\346\214\201\344\273\267\346\240\274\350\247\246\345\217\221 BitVC\346\234\237\350\264\247\344\270\223\347\224\250.js" "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \346\224\257\346\214\201\344\273\267\346\240\274\350\247\246\345\217\221 BitVC\346\234\237\350\264\247\344\270\223\347\224\250.js" index 9ad6e384..72f7923e 100644 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \346\224\257\346\214\201\344\273\267\346\240\274\350\247\246\345\217\221 BitVC\346\234\237\350\264\247\344\270\223\347\224\250.js" +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \346\224\257\346\214\201\344\273\267\346\240\274\350\247\246\345\217\221 BitVC\346\234\237\350\264\247\344\270\223\347\224\250.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/951 +策略出处: https://www.fmz.com/strategy/951 策略名称: 冰山委托 - 支持价格触发 BitVC期货专用 策略作者: Zero 策略描述: diff --git "a/\345\207\275\346\225\260\350\207\252\345\212\250\345\256\271\351\224\231\346\250\241\346\235\277.js" "b/\345\207\275\346\225\260\350\207\252\345\212\250\345\256\271\351\224\231\346\250\241\346\235\277.js" index 65dc9786..ac3ff426 100644 --- "a/\345\207\275\346\225\260\350\207\252\345\212\250\345\256\271\351\224\231\346\250\241\346\235\277.js" +++ "b/\345\207\275\346\225\260\350\207\252\345\212\250\345\256\271\351\224\231\346\250\241\346\235\277.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/11609 +策略出处: https://www.fmz.com/strategy/11609 策略名称: 函数自动容错模板 策略作者: Zero 策略描述: diff --git "a/\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.py" "b/\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.py" new file mode 100644 index 00000000..7f57d119 --- /dev/null +++ "b/\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.py" @@ -0,0 +1,24 @@ +''' +策略出处: https://www.fmz.com/strategy/89969 +策略名称: 判断MA线的排列 - btcdw +策略作者: 比特币大王www.btcdw.com +策略描述: + + + +''' + +def main(): # + records = exchange.GetRecords(PERIOD_M3) #获取3分钟K线数据 + ma_5 = TA.MA(records, 5) #返回一个5分钟移动平均线数组 + ma_10 = TA.MA(records, 10) #返回一个10分钟移动平均线数组 + ma_20 = TA.MA(records, 20) #返回一个20分钟移动平均线数组 + if len(ma_5) == len(ma_10) == len(ma_20): #判断3线数组是不是一样长 + for i in range(0, len(ma_5)): #从0开始遍历ma_5数组到最大元素(次数)个数 + if ma_5[i] > ma_10[i] > ma_20[i]: + Log("1") + Sleep(1000) + elif ma_5[i] < ma_10[i]< ma_20[i]: + Sleep(1000) + Log("0") + diff --git "a/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.js" "b/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.js" index d1df18d0..70f36188 100644 --- "a/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.js" +++ "b/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/345 +策略出处: https://www.fmz.com/strategy/345 策略名称: 单平台均衡策略 策略作者: Zero 策略描述: diff --git "a/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.js" "b/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.js" index 3a7cb17f..10855a79 100644 --- "a/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.js" +++ "b/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/2406 +策略出处: https://www.fmz.com/strategy/2406 策略名称: 单点狙击高频加仓自动反手解套算法 V1.2 策略作者: Zero 策略描述: @@ -48,408 +48,409 @@ RestoreAmount false 持仓数量 RestoreProfit false 上次盈利 SaveLocal false 保存本地日志 AutoReverse true 自动反手 +MinStock 0.01 最小交易币数 */ - -var TradeType = OpType == 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; -var OrgAccount = null; -var Counter = {s : 0, f: 0}; -var LastProfit = 0; -var AllProfit = 0; -var LastTicker = null; -function _N(v, precision) { - if (typeof(precision) != 'number') { - precision = 4; - } - var d = parseFloat(v.toFixed(Math.max(10, precision+5))); - s = d.toString().split("."); - if (s.length < 2 || s[1].length <= precision) { - return d; - } - - var b = Math.pow(10, precision); - return Math.floor(d*b)/b; -} - -function EnsureCall(e, method) { - var r; - while (!(r = e[method].apply(this, Array.prototype.slice.call(arguments).slice(2)))) { - Sleep(Interval); - } - return r; -} - -function StripOrders(e, orderId) { - var order = null; - if (typeof(orderId) == 'undefined') { - orderId = null; - } - while (true) { - var dropped = 0; - var orders = EnsureCall(e, 'GetOrders'); - for (var i = 0; i < orders.length; i++) { - if (orders[i].Id == orderId) { - order = orders[i]; - } else { - var extra = ""; - if (orders[i].DealAmount > 0) { - extra = "成交: " + orders[i].DealAmount; - } else { - extra = "未成交"; - } - e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); - dropped++; - } - } - if (dropped == 0) { - break; - } - Sleep(300); - } - return order; -} - -function updateProfit(e, account, ticker) { - if (typeof(account) == 'undefined') { - account = GetAccount(e); - } - if (typeof(ticker) == 'undefined') { - ticker = EnsureCall(e, "GetTicker"); - } - var profit = (((account.Stocks + account.FrozenStocks) - (OrgAccount.Stocks + OrgAccount.FrozenStocks)) * ticker.Last) + ((account.Balance + account.FrozenBalance) - (OrgAccount.Balance + OrgAccount.FrozenBalance)); - LogProfit(_N(profit + LastProfit, 4), "币数:", _N(account.Stocks + account.FrozenStocks, 4), "钱数:", _N(account.Balance + account.FrozenBalance, 4)); -} - - -var preMsg = ""; -function GetAccount(e, waitFrozen) { - if (typeof(waitFrozen) == 'undefined') { - waitFrozen = false; - } - var account = null; - var alreadyAlert = false; - while (true) { - account = EnsureCall(e, "GetAccount"); - if (!waitFrozen || (account.FrozenStocks < e.GetMinStock() && account.FrozenBalance < 0.01)) { - break; - } - if (!alreadyAlert) { - alreadyAlert = true; - Log("发现账户有冻结的钱或币", account); - } - Sleep(Interval); - } - msg = "成功: " + Counter.s + " 次, " + (AutoReverse ? "被":"解") + "套: " + Counter.f + " 次, 当前账户 钱: " + account.Balance + " 币: " + account.Stocks; - if (account.FrozenStocks > 0) { - msg += " 冻结的币: " + account.FrozenStocks; - } - if (account.FrozenBalance > 0) { - msg += " 冻结的钱: " + account.FrozenBalance; - } - - if (LastTicker != null && OrgAccount != null && OrgAccount != null) { - var profit = (((account.Stocks + account.FrozenStocks) - (OrgAccount.Stocks + OrgAccount.FrozenStocks)) * LastTicker.Last) + ((account.Balance + account.FrozenBalance) - (OrgAccount.Balance + OrgAccount.FrozenBalance)); - msg += " 平仓盈亏: " + AllProfit + ", 浮动盈亏: " + _N(profit, 4); - msg += " (初始账户 钱: " + OrgAccount.Balance + " 币 : " + OrgAccount.Stocks + ")"; - } - - - if (msg != preMsg) { - preMsg = msg; - LogStatus(msg, "#ff0000"); - } - return account; -} - -// mode = 0 : direct buy, 1 : buy as buy1 -function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, retryDelay) { - var initAccount = GetAccount(e, true); - var nowAccount = initAccount; - var orderId = null; - var prePrice = 0; - var dealAmount = 0; - var diffMoney = 0; - var isFirst = true; - var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell; - var isBuy = tradeType == ORDER_TYPE_BUY; - while (true) { - var ticker = EnsureCall(e, 'GetTicker'); - LastTicker = ticker; - var tradePrice = 0; - if (isBuy) { - tradePrice = _N((mode == 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4); - } else { - tradePrice = _N((mode == 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4); - } - if (orderId == null) { - if (isFirst) { - isFirst = false; - } else { - nowAccount = GetAccount(e, true); - } - var doAmount = 0; - if (isBuy) { - diffMoney = _N(initAccount.Balance - nowAccount.Balance, 4); - dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 4); - doAmount = Math.min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance-10) / tradePrice, 4)); - } else { - diffMoney = _N(nowAccount.Balance - initAccount.Balance, 4); - dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); - doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); - } - if (doAmount < e.GetMinStock()) { - break; - } - prePrice = tradePrice; - orderId = tradeFunc(tradePrice, doAmount); - } else { - if (Math.abs(tradePrice - prePrice) > maxSpace) { - orderId = null; - } - var order = StripOrders(exchange, orderId); - if (order == null) { - orderId = null; - } - } - Sleep(retryDelay); - } - - if (dealAmount <= 0) { - return null; - } - - return {price: _N(diffMoney / dealAmount, 4), amount: dealAmount}; -} - -function loop(isFirst) { - var minStock = exchange.GetMinStock(); - var initAccount = GetAccount(exchange, true); - Log(initAccount); - var holdPrice = 0; - var holdAmount = 0; - if (RestoreIt && isFirst) { - LastProfit = RestoreProfit; - TradeType = RestoreType == 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; - holdPrice = RestorePrice; - holdAmount = RestoreAmount; - if (holdAmount != 0) { - initAccount = { - Stocks: initAccount.Stocks, - FrozenStocks: initAccount.FrozenStocks, - Balance: initAccount.Balance, - FrozenBalance: initAccount.FrozenBalance, - }; - if (RestoreType == 0) { - initAccount.Stocks -= holdAmount; - initAccount.Balance += (holdPrice * holdAmount); - } else { - initAccount.Stocks += holdAmount; - initAccount.Balance -= (holdPrice * holdAmount); - } - OrgAccount = initAccount; - Log("恢复持仓状态为:", RestoreType == 0 ? "做多" : "做空", "均价:", holdPrice, "数量:", holdAmount); - if (RestoreType == 0) { - holdAmount = Math.min(initAccount.Stocks, holdAmount); - } - } - if (LastProfit != 0) { - AllProfit = LastProfit; - LogProfit(LastProfit, "恢复上次盈利"); - } - } - if (holdAmount == 0) { - var obj = Trade(exchange, TradeType, OpAmount, OpMode, SlidePrice, MaxAmount, MaxSpace, Interval); - if (!obj) { - throw "出师不利, 开仓失败"; - } else { - Log(TradeType == ORDER_TYPE_BUY ? "开多仓完成" : "开空仓完成", "均价:", obj.price, "数量:", obj.amount); - } - Log(GetAccount(exchange, true)); - holdPrice = obj.price; - holdAmount = obj.amount; - } - var openFunc = TradeType == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell; - var coverFunc = TradeType == ORDER_TYPE_BUY ? exchange.Sell : exchange.Buy; - var isFinished = false; - while (!isFinished) { - var account = GetAccount(exchange, true); - var openAmount = 0; - var openPrice = 0; - var coverPrice = 0; - var canOpen = true; - - if (TradeType == ORDER_TYPE_BUY) { - var upLine = AddLine; - openPrice = _N(holdPrice - AddGoal, 4); - openAmount = _N((holdAmount * (holdPrice - openPrice - upLine)) / upLine, 4); - coverPrice = _N(holdPrice + ProfitGoal, 4); - if (_N(account.Balance / openPrice, 4) < openAmount) { - Log("没有钱加多仓, 需要加仓: ", openAmount, "个"); - if (AutoReverse) { - return holdAmount; - } else { - canOpen = false; - } - } - } else { - var upLine = -AddLine; - openPrice = _N(holdPrice + AddGoal, 4); - coverPrice = _N(holdPrice - ProfitGoal, 4); - openAmount = _N((holdAmount * (holdPrice - openPrice - upLine) / upLine), 4); - if (account.Stocks < openAmount) { - Log("没有币加空仓, 需要币:", openAmount); - if (AutoReverse) { - return holdAmount; - } else { - canOpen = false; - } - } - } - if (holdAmount < minStock) { - Log("剩余币数过小, 放弃操作", holdAmount); - return 0; - } - openAmount = Math.max(minStock, openAmount); - - var order_count = 0; - var openId = null; - var coverId = null; - if (!canOpen) { - openId = -1; - Log("进入等待解套模式"); - } - - for (var i = 0; i < 10; i++) { - if (!openId) { - openId = openFunc(openPrice, openAmount); - } - if (!coverId) { - coverId = coverFunc(coverPrice, holdAmount); - } - if (openId && coverId) { - break; - } - Sleep(Interval); - } - if (!openId || !coverId) { - StripOrders(exchange); - throw "下单失败"; - } - if (openId > 0) { - order_count++; - } - if (coverId > 0) { - order_count++; - } - - var preAccount = account; - while (true) { - Sleep(Interval); - var ticker = EnsureCall(exchange, "GetTicker"); - var orders = EnsureCall(exchange, "GetOrders"); - LastTicker = ticker; - var nowAccount = GetAccount(exchange); - var diff = nowAccount.Stocks + nowAccount.FrozenStocks - preAccount.Stocks; - - if (orders.length != order_count || Math.abs(diff) >= minStock) { - StripOrders(exchange); - nowAccount = GetAccount(exchange, true); - //Log(nowAccount); - var diffAmount = nowAccount.Stocks - initAccount.Stocks; - var diffMoney = nowAccount.Balance - initAccount.Balance; - if (Math.abs(diffAmount) < minStock) { - AllProfit= _N(AllProfit + (holdAmount * ProfitGoal), 4); - LogProfit(AllProfit, "平仓完成, 达到目标盈利点, 单次盈利", _N(holdAmount * ProfitGoal, 4)); - initAccount = nowAccount; - isFinished = true; - if (!canOpen) { - Counter.f++; - } - break; - } - var newHoldPrice = 0; - var newHoldAmount = 0; - if (TradeType == ORDER_TYPE_BUY) { - newHoldAmount = _N(diffAmount, 4); - newHoldPrice = _N((-diffMoney) / diffAmount, 4); - } else { - newHoldAmount = _N(-diffAmount, 4); - newHoldPrice = _N(diffMoney / (-diffAmount), 4); - } - // if open again, we need adjust hold positions's price - var isAdd = false; - if (newHoldAmount > holdAmount) { - holdPrice = newHoldPrice; - isAdd = true; - } - holdAmount = newHoldAmount; - if (!isAdd) { - // reset initAccount - initAccount = { - Stocks : nowAccount.Stocks, - Balance : nowAccount.Balance, - FrozenBalance : nowAccount.FrozenBalance, - FrozenStocks : nowAccount.FrozenStocks, - }; - if (TradeType == ORDER_TYPE_BUY) { - initAccount.Stocks -= holdAmount; - initAccount.Balance += holdAmount * holdPrice; - } else { - initAccount.Stocks += holdAmount; - initAccount.Balance -= holdAmount * holdPrice; - } - initAccount.Stocks = _N(initAccount.Stocks, 4); - initAccount.Balance = _N(initAccount.Balance, 4); - Log("持仓前账户调整为: ", initAccount); - } - Log((TradeType == ORDER_TYPE_BUY ? "多仓" : "空仓"), (isAdd ? "加仓后" : "平仓后"), "重新调整持仓, 均价: ", holdPrice, "数量", holdAmount); - Log("买一:", ticker.Buy, "卖一:", ticker.Sell, "上次成交价:", ticker.Last); - Log(nowAccount); - break; - } - } - } - return 0; -} - -function onexit() { - StripOrders(exchange); - Log("Exit"); -} - -function main() { - if (AddLine > AddGoal || AddLine <= 0) { - throw "加仓均价目标错误"; - } - if (exchange.GetName().indexOf("Future") != -1) { - throw "只支持现货, 期货容易爆仓, 暂不支持"; - } - if (exchange.GetRate() != 1) { - Log("已禁用汇率转换"); - exchange.SetRate(1); - } - EnableLogLocal(SaveLocal); - Interval *= 1000; - SetErrorFilter("502:|503:|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF"); - StripOrders(exchange); - OrgAccount = GetAccount(exchange); - var isFirst = true; - LogStatus("启动成功"); - while (true) { - var ret = loop(isFirst); - isFirst = false; - if (ret != 0) { - Counter.f++; - if (TradeType == ORDER_TYPE_BUY) { - TradeType = ORDER_TYPE_SELL; - Log("开始反手做空"); - } else { - TradeType = ORDER_TYPE_BUY; - Log("开始反手做多"); - } - } else { - Counter.s++; - } - Sleep(Interval); - } + +var TradeType = OpType == 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; +var OrgAccount = null; +var Counter = {s : 0, f: 0}; +var LastProfit = 0; +var AllProfit = 0; +var LastTicker = null; +function _N(v, precision) { + if (typeof(precision) != 'number') { + precision = 4; + } + var d = parseFloat(v.toFixed(Math.max(10, precision+5))); + s = d.toString().split("."); + if (s.length < 2 || s[1].length <= precision) { + return d; + } + + var b = Math.pow(10, precision); + return Math.floor(d*b)/b; +} + +function EnsureCall(e, method) { + var r; + while (!(r = e[method].apply(this, Array.prototype.slice.call(arguments).slice(2)))) { + Sleep(Interval); + } + return r; +} + +function StripOrders(e, orderId) { + var order = null; + if (typeof(orderId) == 'undefined') { + orderId = null; + } + while (true) { + var dropped = 0; + var orders = EnsureCall(e, 'GetOrders'); + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == orderId) { + order = orders[i]; + } else { + var extra = ""; + if (orders[i].DealAmount > 0) { + extra = "成交: " + orders[i].DealAmount; + } else { + extra = "未成交"; + } + e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); + dropped++; + } + } + if (dropped == 0) { + break; + } + Sleep(300); + } + return order; +} + +function updateProfit(e, account, ticker) { + if (typeof(account) == 'undefined') { + account = GetAccount(e); + } + if (typeof(ticker) == 'undefined') { + ticker = EnsureCall(e, "GetTicker"); + } + var profit = (((account.Stocks + account.FrozenStocks) - (OrgAccount.Stocks + OrgAccount.FrozenStocks)) * ticker.Last) + ((account.Balance + account.FrozenBalance) - (OrgAccount.Balance + OrgAccount.FrozenBalance)); + LogProfit(_N(profit + LastProfit, 4), "币数:", _N(account.Stocks + account.FrozenStocks, 4), "钱数:", _N(account.Balance + account.FrozenBalance, 4)); +} + + +var preMsg = ""; +function GetAccount(e, waitFrozen) { + if (typeof(waitFrozen) == 'undefined') { + waitFrozen = false; + } + var account = null; + var alreadyAlert = false; + while (true) { + account = EnsureCall(e, "GetAccount"); + if (!waitFrozen || (account.FrozenStocks < MinStock && account.FrozenBalance < 0.01)) { + break; + } + if (!alreadyAlert) { + alreadyAlert = true; + Log("发现账户有冻结的钱或币", account); + } + Sleep(Interval); + } + msg = "成功: " + Counter.s + " 次, " + (AutoReverse ? "被":"解") + "套: " + Counter.f + " 次, 当前账户 钱: " + account.Balance + " 币: " + account.Stocks; + if (account.FrozenStocks > 0) { + msg += " 冻结的币: " + account.FrozenStocks; + } + if (account.FrozenBalance > 0) { + msg += " 冻结的钱: " + account.FrozenBalance; + } + + if (LastTicker != null && OrgAccount != null && OrgAccount != null) { + var profit = (((account.Stocks + account.FrozenStocks) - (OrgAccount.Stocks + OrgAccount.FrozenStocks)) * LastTicker.Last) + ((account.Balance + account.FrozenBalance) - (OrgAccount.Balance + OrgAccount.FrozenBalance)); + msg += " 平仓盈亏: " + AllProfit + ", 浮动盈亏: " + _N(profit, 4); + msg += " (初始账户 钱: " + OrgAccount.Balance + " 币 : " + OrgAccount.Stocks + ")"; + } + + + if (msg != preMsg) { + preMsg = msg; + LogStatus(msg, "#ff0000"); + } + return account; +} + +// mode = 0 : direct buy, 1 : buy as buy1 +function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, retryDelay) { + var initAccount = GetAccount(e, true); + var nowAccount = initAccount; + var orderId = null; + var prePrice = 0; + var dealAmount = 0; + var diffMoney = 0; + var isFirst = true; + var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell; + var isBuy = tradeType == ORDER_TYPE_BUY; + while (true) { + var ticker = EnsureCall(e, 'GetTicker'); + LastTicker = ticker; + var tradePrice = 0; + if (isBuy) { + tradePrice = _N((mode == 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4); + } else { + tradePrice = _N((mode == 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4); + } + if (orderId == null) { + if (isFirst) { + isFirst = false; + } else { + nowAccount = GetAccount(e, true); + } + var doAmount = 0; + if (isBuy) { + diffMoney = _N(initAccount.Balance - nowAccount.Balance, 4); + dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 4); + doAmount = Math.min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance-10) / tradePrice, 4)); + } else { + diffMoney = _N(nowAccount.Balance - initAccount.Balance, 4); + dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); + doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); + } + if (doAmount < MinStock) { + break; + } + prePrice = tradePrice; + orderId = tradeFunc(tradePrice, doAmount); + } else { + if (Math.abs(tradePrice - prePrice) > maxSpace) { + orderId = null; + } + var order = StripOrders(exchange, orderId); + if (order == null) { + orderId = null; + } + } + Sleep(retryDelay); + } + + if (dealAmount <= 0) { + return null; + } + + return {price: _N(diffMoney / dealAmount, 4), amount: dealAmount}; +} + +function loop(isFirst) { + var minStock = MinStock; + var initAccount = GetAccount(exchange, true); + Log(initAccount); + var holdPrice = 0; + var holdAmount = 0; + if (RestoreIt && isFirst) { + LastProfit = RestoreProfit; + TradeType = RestoreType == 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; + holdPrice = RestorePrice; + holdAmount = RestoreAmount; + if (holdAmount != 0) { + initAccount = { + Stocks: initAccount.Stocks, + FrozenStocks: initAccount.FrozenStocks, + Balance: initAccount.Balance, + FrozenBalance: initAccount.FrozenBalance, + }; + if (RestoreType == 0) { + initAccount.Stocks -= holdAmount; + initAccount.Balance += (holdPrice * holdAmount); + } else { + initAccount.Stocks += holdAmount; + initAccount.Balance -= (holdPrice * holdAmount); + } + OrgAccount = initAccount; + Log("恢复持仓状态为:", RestoreType == 0 ? "做多" : "做空", "均价:", holdPrice, "数量:", holdAmount); + if (RestoreType == 0) { + holdAmount = Math.min(initAccount.Stocks, holdAmount); + } + } + if (LastProfit != 0) { + AllProfit = LastProfit; + LogProfit(LastProfit, "恢复上次盈利"); + } + } + if (holdAmount == 0) { + var obj = Trade(exchange, TradeType, OpAmount, OpMode, SlidePrice, MaxAmount, MaxSpace, Interval); + if (!obj) { + throw "出师不利, 开仓失败"; + } else { + Log(TradeType == ORDER_TYPE_BUY ? "开多仓完成" : "开空仓完成", "均价:", obj.price, "数量:", obj.amount); + } + Log(GetAccount(exchange, true)); + holdPrice = obj.price; + holdAmount = obj.amount; + } + var openFunc = TradeType == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell; + var coverFunc = TradeType == ORDER_TYPE_BUY ? exchange.Sell : exchange.Buy; + var isFinished = false; + while (!isFinished) { + var account = GetAccount(exchange, true); + var openAmount = 0; + var openPrice = 0; + var coverPrice = 0; + var canOpen = true; + + if (TradeType == ORDER_TYPE_BUY) { + var upLine = AddLine; + openPrice = _N(holdPrice - AddGoal, 4); + openAmount = _N((holdAmount * (holdPrice - openPrice - upLine)) / upLine, 4); + coverPrice = _N(holdPrice + ProfitGoal, 4); + if (_N(account.Balance / openPrice, 4) < openAmount) { + Log("没有钱加多仓, 需要加仓: ", openAmount, "个"); + if (AutoReverse) { + return holdAmount; + } else { + canOpen = false; + } + } + } else { + var upLine = -AddLine; + openPrice = _N(holdPrice + AddGoal, 4); + coverPrice = _N(holdPrice - ProfitGoal, 4); + openAmount = _N((holdAmount * (holdPrice - openPrice - upLine) / upLine), 4); + if (account.Stocks < openAmount) { + Log("没有币加空仓, 需要币:", openAmount); + if (AutoReverse) { + return holdAmount; + } else { + canOpen = false; + } + } + } + if (holdAmount < minStock) { + Log("剩余币数过小, 放弃操作", holdAmount); + return 0; + } + openAmount = Math.max(minStock, openAmount); + + var order_count = 0; + var openId = null; + var coverId = null; + if (!canOpen) { + openId = -1; + Log("进入等待解套模式"); + } + + for (var i = 0; i < 10; i++) { + if (!openId) { + openId = openFunc(openPrice, openAmount); + } + if (!coverId) { + coverId = coverFunc(coverPrice, holdAmount); + } + if (openId && coverId) { + break; + } + Sleep(Interval); + } + if (!openId || !coverId) { + StripOrders(exchange); + throw "下单失败"; + } + if (openId > 0) { + order_count++; + } + if (coverId > 0) { + order_count++; + } + + var preAccount = account; + while (true) { + Sleep(Interval); + var ticker = EnsureCall(exchange, "GetTicker"); + var orders = EnsureCall(exchange, "GetOrders"); + LastTicker = ticker; + var nowAccount = GetAccount(exchange); + var diff = nowAccount.Stocks + nowAccount.FrozenStocks - preAccount.Stocks; + + if (orders.length != order_count || Math.abs(diff) >= minStock) { + StripOrders(exchange); + nowAccount = GetAccount(exchange, true); + //Log(nowAccount); + var diffAmount = nowAccount.Stocks - initAccount.Stocks; + var diffMoney = nowAccount.Balance - initAccount.Balance; + if (Math.abs(diffAmount) < minStock) { + AllProfit= _N(AllProfit + (holdAmount * ProfitGoal), 4); + LogProfit(AllProfit, "平仓完成, 达到目标盈利点, 单次盈利", _N(holdAmount * ProfitGoal, 4)); + initAccount = nowAccount; + isFinished = true; + if (!canOpen) { + Counter.f++; + } + break; + } + var newHoldPrice = 0; + var newHoldAmount = 0; + if (TradeType == ORDER_TYPE_BUY) { + newHoldAmount = _N(diffAmount, 4); + newHoldPrice = _N((-diffMoney) / diffAmount, 4); + } else { + newHoldAmount = _N(-diffAmount, 4); + newHoldPrice = _N(diffMoney / (-diffAmount), 4); + } + // if open again, we need adjust hold positions's price + var isAdd = false; + if (newHoldAmount > holdAmount) { + holdPrice = newHoldPrice; + isAdd = true; + } + holdAmount = newHoldAmount; + if (!isAdd) { + // reset initAccount + initAccount = { + Stocks : nowAccount.Stocks, + Balance : nowAccount.Balance, + FrozenBalance : nowAccount.FrozenBalance, + FrozenStocks : nowAccount.FrozenStocks, + }; + if (TradeType == ORDER_TYPE_BUY) { + initAccount.Stocks -= holdAmount; + initAccount.Balance += holdAmount * holdPrice; + } else { + initAccount.Stocks += holdAmount; + initAccount.Balance -= holdAmount * holdPrice; + } + initAccount.Stocks = _N(initAccount.Stocks, 4); + initAccount.Balance = _N(initAccount.Balance, 4); + Log("持仓前账户调整为: ", initAccount); + } + Log((TradeType == ORDER_TYPE_BUY ? "多仓" : "空仓"), (isAdd ? "加仓后" : "平仓后"), "重新调整持仓, 均价: ", holdPrice, "数量", holdAmount); + Log("买一:", ticker.Buy, "卖一:", ticker.Sell, "上次成交价:", ticker.Last); + Log(nowAccount); + break; + } + } + } + return 0; +} + +function onexit() { + StripOrders(exchange); + Log("Exit"); +} + +function main() { + if (AddLine > AddGoal || AddLine <= 0) { + throw "加仓均价目标错误"; + } + if (exchange.GetName().indexOf("Future") != -1) { + throw "只支持现货, 期货容易爆仓, 暂不支持"; + } + if (exchange.GetRate() != 1) { + Log("已禁用汇率转换"); + exchange.SetRate(1); + } + EnableLogLocal(SaveLocal); + Interval *= 1000; + SetErrorFilter("502:|503:|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF"); + StripOrders(exchange); + OrgAccount = GetAccount(exchange); + var isFirst = true; + LogStatus("启动成功"); + while (true) { + var ret = loop(isFirst); + isFirst = false; + if (ret != 0) { + Counter.f++; + if (TradeType == ORDER_TYPE_BUY) { + TradeType = ORDER_TYPE_SELL; + Log("开始反手做空"); + } else { + TradeType = ORDER_TYPE_BUY; + Log("开始反手做多"); + } + } else { + Counter.s++; + } + Sleep(Interval); + } } diff --git "a/\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).js" "b/\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).js" index 7439f656..a0603a72 100644 --- "a/\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).js" +++ "b/\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/1084 +策略出处: https://www.fmz.com/strategy/1084 策略名称: 单独计算收益(代码来自zero) 策略作者: botvsing 策略描述: diff --git "a/\345\215\225\350\276\271\347\275\221\346\240\274.js" "b/\345\215\225\350\276\271\347\275\221\346\240\274.js" new file mode 100644 index 00000000..66e798f5 --- /dev/null +++ "b/\345\215\225\350\276\271\347\275\221\346\240\274.js" @@ -0,0 +1,170 @@ +/* +策略出处: https://www.fmz.com/strategy/88472 +策略名称: 单边网格 +策略作者: 6821281 +策略描述: + +测试的时候填写起始价格来测试是否正常 +起始价格不填写为现价买入+价格区间买入 +微信173970984 + + +参数 默认值 描述 +----------- ----- ------- +buyjingdu 2 下单价格精度 +buymount 3 下单数量精度 +buypersent true 下单百分比 +buylimit 0.01 最小交易量 +reffertime 3000 刷新时间间隔 +moneybt 100 网格的价格间距 +startpricex false 起始价格 +liruncha 0.1 利润差价 +*/ + +//获取账户余额 +var startPrice= 0; +function getBalancex(){ + var balance = exchange.GetAccount(); + Log("余额:", balance.Balance,"币余额:", balance.Stocks); + return balance; +} + + +//获取币种现价 +function getPrice(typex){ + var NowPrice =exchange.GetTicker(); + if(typex=='buy'){ + + Log("当前买入价格:"+(NowPrice.Buy)) + return NowPrice.Buy; + } + if(typex=='sell'){ + Log("当前卖出价格:"+(NowPrice.Sell)) + return NowPrice.Sell; + } +} + +//取消所有买单操作重新下单 +function cancelOrders(){ + //获取所有未成交订单 + var orders = _C(exchange.GetOrders); + for(var z in orders){ + //# Log("当前订单类型:",orders[z].Type,"订单Id:",orders[z].Id); + if(orders[z].Type==0){ + exchange.CancelOrder(orders[z].Id) + Log("取消之前的挂单成功,id:",orders[z].Id); + } + } + /* + for(var i=0;i0){ + price=startpricex-moneybt; + }else{ + price=price-moneybt; //实际价格为当前价格减去区间价格 + } + startPrice=price; + var balancex = getBalancex(); + balanceAmount = balancex.Balance; + + //需要购买的数量 + doAmount = (balanceAmount*(buypersent/100))/price + + + + var id = 0; + if(doAmount>buylimit){ + saveBuyId=id= exchange.Buy(price, doAmount); + Log("下单成功id:", id," 价格:", price," 数量:", doAmount); + }else{ + Log("可买数量低于最小交易量:", buylimit," 数量:", doAmount); + } +} + + +//根据上次的ID来检查订单状态 然后出售 +function doSellTrading2(){ + //获取订单状态 + Log("上一订单ID:", saveBuyId); + if(saveBuyId!=0){ + var order = exchange.GetOrder(saveBuyId); + if(order){ + if(order.Status==ORDER_STATE_CLOSED){ + leftStocks=leftStocks-orderList[i].Amount + var sellPrice = order.Price+liruncha; + var sellAmount = order.Amount; + var id=exchange.Sell(sellPrice, sellAmount); + Log("出售成功id:", id," 价格:", sellPrice," 数量:", sellAmount); + } + } + } + +} + + + + + + + + + +//定时扫描是否有买单成交 并出售对应数量 +function doSellTrading(){ + //如果余额大于零 + balan = getBalancex() + leftStocks=balan.Stocks; + if(balan.Stocks>0){ + var orderList = exchange.GetTrades() + //理论检测前20条数据即可 + if(orderList){ + for(i=0;i<=100;i++){ + //Log("查看订单信息:",orderList); + if(orderList[i].Type==0 && leftStocks>orderList[i].Amount){ + leftStocks=leftStocks-orderList[i].Amount + var sellPrice = orderList[i].Price+liruncha; + var sellAmount = orderList[i].Amount; + var id=exchange.Sell(sellPrice, sellAmount); + Log("出售成功id:", id," 价格:", sellPrice," 数量:", sellAmount); + } + } + } + } +} + + +function onTick(){ + //在这里写策略逻辑,将会不断调用exchange + doSellTrading2() + doTradingBuy() +} +/* +function main(){ + var id = exchange.Sell(99999, 1); + var order = exchange.GetOrder(id);//参数id为订单号码,需填入你想要查询的订单的号码 + Log("Id", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:", + order.DealAmount, "Status:", order.Status, "Type:", order.Type); +} +*/ +function main(){ + exchange.SetPrecision(buyjingdu, buymount); + while(true){ + onTick(); + Sleep(reffertime); + } +} diff --git "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.py" "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.py" index 32216310..cd181163 100644 --- "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.py" +++ "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/53512 +策略出处: https://www.fmz.com/strategy/53512 策略名称: 双平台对冲 练习用 求交流求指点 策略作者: perseus 策略描述: diff --git "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS) (Copy).js" "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS) (Copy).js" index 4bfe7fa3..d5dbda3b 100644 --- "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS) (Copy).js" +++ "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS) (Copy).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/61405 +策略出处: https://www.fmz.com/strategy/61405 策略名称: 双平台对冲js版本(two platforms hedging-JS) (Copy) 策略作者: ellajella-0378 策略描述: diff --git "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" index 89dab984..3de68802 100644 --- "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" +++ "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/57556 +策略出处: https://www.fmz.com/strategy/57556 策略名称: 双平台对冲js版本(two platforms hedging-JS) 策略作者: 7meter 策略描述: diff --git "a/\345\217\226\346\266\210\346\211\200\346\234\211\350\256\242\345\215\225.js" "b/\345\217\226\346\266\210\346\211\200\346\234\211\350\256\242\345\215\225.js" index 5e0f0f64..0f397fcf 100644 --- "a/\345\217\226\346\266\210\346\211\200\346\234\211\350\256\242\345\215\225.js" +++ "b/\345\217\226\346\266\210\346\211\200\346\234\211\350\256\242\345\215\225.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/280 +策略出处: https://www.fmz.com/strategy/280 策略名称: 取消所有订单 策略作者: Zero 策略描述: diff --git "a/\345\220\204\345\244\247\345\271\263\345\217\260API\345\217\257\347\224\250\347\216\207\347\273\237\350\256\241.js" "b/\345\220\204\345\244\247\345\271\263\345\217\260API\345\217\257\347\224\250\347\216\207\347\273\237\350\256\241.js" index c7c8876f..0bf880b6 100644 --- "a/\345\220\204\345\244\247\345\271\263\345\217\260API\345\217\257\347\224\250\347\216\207\347\273\237\350\256\241.js" +++ "b/\345\220\204\345\244\247\345\271\263\345\217\260API\345\217\257\347\224\250\347\216\207\347\273\237\350\256\241.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/4404 +策略出处: https://www.fmz.com/strategy/4404 策略名称: 各大平台API可用率统计 策略作者: Zero 策略描述: diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\270\273\345\212\233\345\220\210\347\272\246\350\277\207\346\273\244.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\270\273\345\212\233\345\220\210\347\272\246\350\277\207\346\273\244.js" index 483992f1..dd82415b 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\270\273\345\212\233\345\220\210\347\272\246\350\277\207\346\273\244.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\270\273\345\212\233\345\220\210\347\272\246\350\277\207\346\273\244.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/9837 +策略出处: https://www.fmz.com/strategy/9837 策略名称: 商品期货主力合约过滤 策略作者: Zero 策略描述: diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223(\345\242\236\345\212\240\344\270\213\351\231\220\344\273\267\345\215\225\345\212\237\350\203\275).js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223(\345\242\236\345\212\240\344\270\213\351\231\220\344\273\267\345\215\225\345\212\237\350\203\275).js" index 3b0d1c65..5360a05d 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223(\345\242\236\345\212\240\344\270\213\351\231\220\344\273\267\345\215\225\345\212\237\350\203\275).js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223(\345\242\236\345\212\240\344\270\213\351\231\220\344\273\267\345\215\225\345\212\237\350\203\275).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/14198 +策略出处: https://www.fmz.com/strategy/14198 策略名称: 商品期货交易类库(增加下限价单功能) 策略作者: edwardgyw 策略描述: diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" index fb8b0e19..4cc38b1b 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/12961 +策略出处: https://www.fmz.com/strategy/12961 策略名称: 商品期货交易类库 策略作者: Zero 策略描述: diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.js" index e7a6f799..14b154c6 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/37793 +策略出处: https://www.fmz.com/strategy/37793 策略名称: 商品期货查看账户详细信息 策略作者: Zero 策略描述: diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\347\273\223\347\256\227\345\215\225\345\271\263\344\273\223\347\233\210\344\272\217\345\216\206\345\217\262\346\237\245\350\257\242.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\347\273\223\347\256\227\345\215\225\345\271\263\344\273\223\347\233\210\344\272\217\345\216\206\345\217\262\346\237\245\350\257\242.js" index ccee7ae3..e5726895 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\347\273\223\347\256\227\345\215\225\345\271\263\344\273\223\347\233\210\344\272\217\345\216\206\345\217\262\346\237\245\350\257\242.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\347\273\223\347\256\227\345\215\225\345\271\263\344\273\223\347\233\210\344\272\217\345\216\206\345\217\262\346\237\245\350\257\242.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/38083 +策略出处: https://www.fmz.com/strategy/38083 策略名称: 商品期货结算单平仓盈亏历史查询 策略作者: Zero 策略描述: diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.js" new file mode 100644 index 00000000..e960e0ff --- /dev/null +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.js" @@ -0,0 +1,138 @@ +/* +策略出处: https://www.fmz.com/strategy/79351 +策略名称: 商品期货跟单系统 +策略作者: Hukybo +策略描述: + + + +*/ + +var arr = []; + +//下单 +function trade(symbol, type, unit) { + var acc = _C(exchanges[0].GetAccount).Balance; //主账户 + for (var i = 1; i < exchanges.length; i++) { + var ac = _C(exchanges[i].GetAccount).Balance; //子账户 + var dw = Math.floor(unit / (acc / ac)); //按资金比例下单 + if (dw < 1) { + Log(i, ' 号账户资金不足'); + continue; + } + var mp = _C(exchanges[i].GetPosition); //子持仓 + var npm = $.NewPositionManager(exchanges[i]); + if (type == 11) { + npm.OpenLong(symbol, dw); + Log(i, ' 号账户:', symbol, ':多开:', dw, ' 张'); + } else if (type == -11) { + npm.OpenShort(symbol, dw); + Log(i, ' 号账户:', symbol, ':空开:', dw, ' 张'); + } else if (type == 10 || type == -10) { + for (var v = 0; v < mp.length; v++) { + if (mp[v].ContractType == symbol) { + npm.Cover(symbol, dw); + if (type == 10) { + Log(i, ' 号账户:', symbol, ':多平:', dw, ' 张'); + } else { + Log(i, ' 号账户:', symbol, ':空平:', dw, ' 张'); + } + } + } + } else if (type == 100 || type == -100) { + for (var k = 0; k < mp.length; k++) { + if (mp[k].ContractType == symbol) { + npm.Cover(symbol, mp[k].Amount); + Log(i, ' 号账户:', symbol, ':全平'); + } + } + } + } +} + +//匹配 +function Comparison(arr) { + for (var x in arr[1]) { + if (arr[0][x]) { + if (arr[1][x].Type == arr[0][x].Type) { + if (arr[1][x].Amount - arr[0][x].Amount > 0) { + if (arr[1][x].Type == "多") { + trade(x, 11, arr[1][x].Amount - arr[0][x].Amount); //多头加仓 + } else if (arr[1][x].Type == "空") { + trade(x, -11, arr[1][x].Amount - arr[0][x].Amount); //空头加仓 + } + } else if (arr[1][x].Amount - arr[0][x].Amount < 0) { + if (arr[1][x].Type == "多") { + trade(x, 10, arr[0][x].Amount - arr[1][x].Amount); //多头减仓 + } else if (arr[1][x].Type == "空") { + trade(x, -10, arr[0][x].Amount - arr[1][x].Amount); //空头减仓 + } + } + } else { + if (arr[1][x].Type == "多") { + trade(x, -100, arr[0][x].Amount); + trade(x, 11, arr[1][x].Amount); //空头反手为多头 + } else if (arr[1][x].Type == "空") { + trade(x, 100, arr[0][x].Amount); + trade(x, -11, arr[1][x].Amount); //多头反手为空头 + } + } + } else { + if (arr[1][x].Type == "多") { + trade(x, 11, arr[1][x].Amount); //多开 + } else if (arr[1][x].Type == "空") { + trade(x, -11, arr[1][x].Amount); //空开 + } + } + } + for (var y in arr[0]) { + if (!arr[1][y]) { + if (arr[0][y].Type == "多") { + trade(y, 100, arr[0][y].Amount); //多平 + } else if (arr[0][y].Type == "空") { + trade(y, -100, arr[0][y].Amount); //空平 + } + } + } +} + +//数据处理 +function data() { + var mp = _C(exchanges[0].GetPosition); + var allDic = {}; + for (var v = 0; v < mp.length; v++) { + var name = mp[v].ContractType; + allDic[name] = {}; + allDic[name]["Amount"] = mp[v].Amount; + var bs = ""; + if (mp[v].Type == 0 || mp[v].Type == 2) { + bs = "多" + } else { + bs = "空" + } + allDic[name]["Type"] = bs; + } + arr.push(allDic); + if (arr.length > 2) { + arr.shift(); + Comparison(arr); + } +} + +function main() { + for (var i = 0; i < exchanges.length; i++) { + if (exchanges[i].GetName() !== 'Futures_CTP') { + throw '只支持 CTP !请检查第 ' + i + ' 个账户' + } + } + SetErrorFilter("not login|ready|初始化"); + while (true) { + if (exchanges[0].IO("status")) { + data(); + LogStatus("开盘时间,与交易服务器连接成功。") + } else { + LogStatus("\n警告! 与交易服务器连接断开", "#DF0101", "\n", "\n未登录状态或该交易所已经闭市。", "#DF0101"); + } + Sleep(100); + } +} diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \345\215\225\345\223\201\347\247\215\345\245\227\345\210\251\345\220\210\347\272\246.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \345\215\225\345\223\201\347\247\215\345\245\227\345\210\251\345\220\210\347\272\246.js" index fda4380d..cb424231 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \345\215\225\345\223\201\347\247\215\345\245\227\345\210\251\345\220\210\347\272\246.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \345\215\225\345\223\201\347\247\215\345\245\227\345\210\251\345\220\210\347\272\246.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/27122 +策略出处: https://www.fmz.com/strategy/27122 策略名称: 商品期货跨期对冲 - 单品种套利合约 策略作者: Zero 策略描述: @@ -7,22 +7,25 @@ 使用套利合约进行对冲优点是双向开仓速度快, 滑点少, 策略实盘测试通过. -参数 默认值 描述 ------------ --------------- --------- -Symbol SPD MA705&MA709 套利合约 -HedgeSpread 15 开仓价差 -CoverSpread 5 平仓价差 -OpAmount true 开仓手数 -CoverAll false 启动时平掉所有仓位 -Reset false 启动时重置所有信息 -AutoRestore true 启动时自动恢复仓位 +参数 默认值 描述 +------------ --------------- --------- +Symbol SPD MA705&MA709 套利合约 +HedgeSpread 15 正溢价开仓价差 +CoverSpread 5 正溢价平仓价差 +RHedgeSpread 2 负溢价开仓价差 +RCoverSpread 10 负溢价平仓价差 +OpAmount true 开仓手数 +CoverAll false 启动时平掉所有仓位 +Reset false 启动时重置所有信息 +AutoRestore true 启动时自动恢复仓位 按钮 默认值 描述 -------- ---------- ------ CoverALL __button__ 平掉所有仓位 */ -function Hedge(q, e, initAccount, symbol, hedgeSpread, coverSpread) { + +function Hedge(q, e, initAccount, symbol, hedgeSpread, coverSpread, rHedgeSpread, rCoverSpread) { var self = {} self.q = q self.initAccount = initAccount @@ -32,6 +35,8 @@ function Hedge(q, e, initAccount, symbol, hedgeSpread, coverSpread) { self.isBusy = false self.hedgeSpread = hedgeSpread self.coverSpread = coverSpread + self.rHedgeSpread = rHedgeSpread + self.rCoverSpread = rCoverSpread self.insDetail = null; self.opAmount = OpAmount var arr = symbol.split('&'); @@ -81,17 +86,17 @@ function Hedge(q, e, initAccount, symbol, hedgeSpread, coverSpread) { var action = 0; // 1: A sell B buy 2: A buy B sell if (self.status == 0) { - if (ticker.Sell > self.hedgeSpread) { + if (ticker.Sell >= self.hedgeSpread) { Log("开仓 ", self.pairA, "卖", self.pairB, "买", ticker.Buy, '#ff0000') action = 2 - } else if (-ticker.Buy > self.hedgeSpread) { + } else if (ticker.Buy <= self.rHedgeSpread) { Log("开仓 ", self.pairA, "买", self.pairB, "卖", ticker.Buy, '#ff0000') action = 1 } } else if (self.status == 2 && ticker.Buy <= self.coverSpread) { Log("平仓", self.pairA, "买", self.pairB, "卖", ticker.Sell, '#ff0000') action = 2 - } else if (self.status == 1 && ticker.Sell <= self.coverSpread) { + } else if (self.status == 1 && ticker.Sell >= self.rCoverSpread) { Log("平仓", self.pairA, "卖", self.pairB, "买",ticker.Buy, '#ff0000') action = 1 } diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \347\231\276\350\241\214\344\273\243\347\240\201\345\256\236\347\216\260.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \347\231\276\350\241\214\344\273\243\347\240\201\345\256\236\347\216\260.js" index b23d92ad..63236e70 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \347\231\276\350\241\214\344\273\243\347\240\201\345\256\236\347\216\260.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \347\231\276\350\241\214\344\273\243\347\240\201\345\256\236\347\216\260.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/23896 +策略出处: https://www.fmz.com/strategy/23896 策略名称: 商品期货跨期对冲 - 百行代码实现 策略作者: Zero 策略描述: diff --git "a/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.py" "b/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.py" index 7f57dac2..169ae26c 100644 --- "a/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.py" +++ "b/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/61867 +策略出处: https://www.fmz.com/strategy/61867 策略名称: 回测保存K线到本地CSV 策略作者: botvsing 策略描述: diff --git "a/\345\233\276\350\241\250\346\250\241\346\235\277\357\274\210\345\242\236\345\212\240\347\212\266\346\200\201\346\240\217\350\241\250\346\240\274\357\274\211.js" "b/\345\233\276\350\241\250\346\250\241\346\235\277\357\274\210\345\242\236\345\212\240\347\212\266\346\200\201\346\240\217\350\241\250\346\240\274\357\274\211.js" deleted file mode 100644 index e10982ac..00000000 --- "a/\345\233\276\350\241\250\346\250\241\346\235\277\357\274\210\345\242\236\345\212\240\347\212\266\346\200\201\346\240\217\350\241\250\346\240\274\357\274\211.js" +++ /dev/null @@ -1,346 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/20967 -策略名称: 图表模板(增加状态栏表格) -策略作者: 小小梦 -策略描述: - -图表模板 - - -参数 默认值 描述 --------------- ----- -------- -indicatorsName 指标轴1 指标轴 -indicators_1 指标1 指标1 -indicators_2 指标2 指标2 -Interval 500 间隔(毫秒) -isOpenRightY true 是否开启右边Y轴 -lineType line 指标线类型 -*/ - -/* -这个是一个图表模板,详细用法见广场帖子。 -*/ -//----------------------------------图表模块---------------------------------------------------------------- -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: isOpenRightY //生成右边Y轴 ceshi - } - ], - series: [//系列 - {type:'candlestick',yAxis:0,name:'K',id:'KLine',data:[]}, - {type:'flags',onSeries:'KLine',data:[]}, - {name:indicators_1,type:lineType,yAxis:isOpenRightY?1:0,data:[]}, - {name:indicators_2,type:lineType,yAxis:isOpenRightY?1:0,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 lastRecordsTime = 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,message){ - var msg = ""; - var fcolor = ""; // ceshi - var strState = "";//ceshi - msg = "均价:"+price+"币数:"+amount; - switch(state){ - case 3:strState = "自定义信息";fcolor = "black";msg = message;break; - 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}); -} -//----------------------------------图表模块over------------------------------------------------------------ -//----------------------------------状态栏表格模块----------------------------------------------------------- -var TV = null; //表格对象,控制表格内容。 -var objTable = null;//用于显示表格的对象。 -function CreateObjectString(cols,rows){ - var i = cols;// column 列 - var j = rows;// row 行 - var firstCols = 'a'; - var charValue = 0; - var firstName = ""; //对象字符串成员的字母部分 - var lastName = ""; //对象字符串成员的数字部分 - var strMember = ""; //对象字符串成员 - var objStr = "";//返回的字符串 - if(i > 26){ - throw "ERROR column must less 26"; - } - var strHead = '{'; - var strEnd = '}'; - for(var n = 0 ; n < j; n++){ - //处理行 - for(var m = 0 ; m < i; m++){ - //处理列 处理 abc , 数字=n - charValue = firstCols.charCodeAt();//取字符的编码 - firstName = String.fromCharCode(charValue + m); - lastName = n; - if(n === j - 1 && m === i - 1 ){ - strMember = '"' + firstName + lastName + '"' + ':' + '""'; - }else{ - strMember = '"' + firstName + lastName + '"' + ':' + '""' + ','; - } - objStr += strMember; - } - } - objStr = strHead + objStr + strEnd; - return objStr; -} - -var g_cols = 0; -var g_rows = 0; -$.TableInit = function(cols,rows){ - g_cols = cols; - g_rows = rows; - var str = CreateObjectString(cols,rows);//生成 TV对象 字符串 - TV = JSON.parse(str); // 解析字符串生成 TV对象 - var tableString = CreateTableString(cols,rows);//生成表格对象字符串 - objTable = JSON.parse(tableString);//解析表格对象字符串 - LogStatus("当前时间:" + (new Date()) + "\n" + "`" + JSON.stringify(objTable) + "`");//初次显示 表格对象到 状态栏 - //ConnectDate(cols,rows);//初次链接数据 - return TV;//返回 TV对象 -}; -function ConnectDate(cols,rows){//关联函数 - //处理cols - var i = 0;//控制 objTable.cols - for(var unit1 in TV){ - if(i < cols){ - objTable.cols[i] = TV[unit1]; - }else{ - break; - } - i++; - } - //处理rows - var m = 0;//m控制 第几行 - var n = 0;//n控制 第几个 - var o = 1;//跳过cols 部分的计数 - for(var unit2 in TV){ - if( o <= cols){ - o++; - continue; - } - if(n >= cols){ - n = 0; - m++; - } - objTable.rows[m][n] = TV[unit2]; - n++; - } -} -function CreateTableString(cols,rows){ - var strHead = '{'; - var strEnd = '}'; - var srtTable_type = ' "type": "table",'; - var strTable_title = ' "title": "运行信息",'; - var strTable_cols_begin = ' "cols" : ['; - var strTable_cols_end = '],'; - var strTable_rows_begin = ' "rows" : ['; - var strTable_rows_end = ']'; - var strCols = ""; - - var length = 0; - for(var y in TV){// 获得 TV对象的 成员个数 - length++; - } - - var i = 1; - for(var x in TV){// 初始化 strCols - if(i >= cols){ - strCols += '"' + "TV." + x + '"' ; - break; - }else{ - strCols += '"' + "TV." + x + '"' + ','; - } - i++; - } - - i = 1;//控制循环 一行cols 后重置的计数 - var n = 1; //用于最后一次 不加 都好的 计数 - var m = 1; //用于跳过cols 部分的计数 - var strRowsUnit = ""; - var strRows = ""; - length = length - cols; - for(var z in TV){ - if(m <= cols){//跳过 表格cols 部分 - m++; - continue; - } - - if(i >= cols){ - strRowsUnit += '"' + "TV." + z + '"' ; - i = 1;//重置i - if(n < length){ - strRowsUnit = '[' + strRowsUnit + ']' + ','; - }else if(n === length){ - strRowsUnit = '[' + strRowsUnit + ']'; - } - strRows += strRowsUnit; - strRowsUnit = "";//重置 - }else{ - strRowsUnit += '"' + "TV." + z + '"' + ','; - i++; - } - n++; - } - var tableString = strHead + srtTable_type + strTable_title + strTable_cols_begin + strCols + strTable_cols_end + strTable_rows_begin + strRows + strTable_rows_end + strEnd; - return tableString; -} -$.UpdateLogStatus = function(msg) { //更新状态栏 - //列用ABC表示,行用0123表示 - ConnectDate(g_cols,g_rows);//链接数据 - LogStatus("当前时间:" + (new Date()) + "msg:" + msg + "\n" + "`" + JSON.stringify(objTable) + "`");//更新状态栏 -}; -//----------------------------------状态栏表格模块over------------------------------------------------------- -//----------------------------------导出函数---------------------------------------------------------------- -$.SignOP = function(time,price,amount,state,message){//该函数作用是在策略运行时,在K线图表上标记“开多仓”,“开空仓”,“平仓” 的位置。 - //参数time: 在策略中使用此函数的时间,一般用(new Date()).getTime() , price:这个参数是在标签上显示 价格(多空平), amount:这个参数是在标签上显示 数量(成交) ,state: 这个参数是用来控制标记的类型,state = 1开多 ,2开空 ,0 平仓 - if(arguments.length < 4){ - Log("SignOP 函数 必须传入4个参数 : time、price、amount、state"); - return; - } - if(typeof(message) === "undefined"){ - message = ""; - } - SignOP(time,price,amount,state,message); -}; -$.Draw = function(records){ - Draw(records); -}; -$.AddZhiBiao = function(zhibiao_Array,records,index){//该函数是在图表上添加指标线,zhibiao_Array:这个参数是指标数据(数组),records:产生指标数据的 原始K线数据,index:指标线的编号,从1开始递增 - if(records[records.length - 1].Time === lastRecordsTime){ - chart.add([index+1,[records[records.length - 1].Time,zhibiao_Array[zhibiao_Array.length - 1]],-1]); - }else{ - chart.add([index+1,[records[records.length - 2].Time,zhibiao_Array[zhibiao_Array.length - 2]],-1]); - chart.add([index+1,[records[records.length - 1].Time,zhibiao_Array[zhibiao_Array.length - 1]]]); - //lastRecordsTime = records[records.length - 1].Time; //测试 取消 - } - //chart.update(ChartObj); //测试取消 -}; -$.UpdateChart = function(records){//更新图表,每次添加指标线,添加标签 后需要更新 才有效。 records: K线原始数据 - if(records[records.length - 1].Time !== lastRecordsTime){ - lastRecordsTime = records[records.length - 1].Time; - } - chart.update(ChartObj); - chart.reset(500);//默认 保留500个K线 -}; -//----------------------------------导出函数over----------------------------------------------------------- -//测试 -function main(){ - ///*测试图表功能 - var i = 0; - var records = exchange.GetRecords(); - while(!records || records.length < 5){ - records = exchange.GetRecords(); - Sleep(500); - } - var zhibiao = [1,2,3,5,6,4,1,21,5];//ceshi - var zhibiao2 = [11,22,44,57,8,77,5]; - - //$.SignOP((new Date()).getTime(),null,null,3,"自定义信息标记到图表上");// 测试标记 自定义信息 到图表上 - while(i < 500){ - Draw(records); - if(i===20){ - //Sleep(60*60*1000); - SignOP((new Date()).getTime(),2900,1,1); - $.SignOP((new Date()).getTime(),null,null,3,"自定义信息标记到图表上");// 测试标记 自定义信息 到图表上 - } - //zhibiao.shift(); - //zhibiao.push(zhibiao[zhibiao.length - 1] + 1);//ceshi - //Log("ceshi"); //ceshi - $.AddZhiBiao(zhibiao,records,1); - //$.AddZhiBiao(zhibiao2,records,2); - //Log("ceshi"); //ceshi - - //Draw(records); - //Log("ceshi1"); //ceshi - Sleep(200); - records = exchange.GetRecords(); - $.UpdateChart(records);//更新图表 - i++; - } - //*/ - /*测试状态栏表格功能*/ - var cols = 6;//列 设置一个变量 代表 列 - var rows = 4;//行 设置一个变量 代表 行 - $.TableInit(cols,rows); //初始化 状态栏 会显示 各个单元格的 坐标 - ///* - for(var x in TV){ - TV[x] = "lalala";// 全部单元格写成 lalala - } - //更新表格 显示 lalala, 表头 数据不能重复 ,否则显示不出来。 - /* - TV.a0 = "a0"; - TV.b0 = "b0"; - TV.c0 = "c0"; - TV.d0 = "d0"; - TV.e0 = "e0"; - TV.f0 = "f0";//先把 表头数据写成不一样的 - */ - $.UpdateLogStatus(cols,rows);//更新 状态栏表格 - - ///* - //怎么在 表格里面写入数据呢? - var num = 100; - var text = "文本:测试表格文本"; - var obj = {name:"对象",age:"19",sex:"girl"}; - var array = ["数组",22,33,54]; - TV.a1 = num; - TV.c2 = text; - TV.b3 = obj; - TV.b0 = array; - - $.UpdateLogStatus(cols,rows);//再次更新 状态栏表格 - //*/ -} -/*修改 -1、增加了是否开启右边坐标轴 -2、增加参数 lineType : spline / line -*/ diff --git "a/\345\233\276\350\241\250\347\225\214\351\235\242\344\277\241\346\201\257\345\261\225\347\244\272\345\256\236\344\276\2131.js" "b/\345\233\276\350\241\250\347\225\214\351\235\242\344\277\241\346\201\257\345\261\225\347\244\272\345\256\236\344\276\2131.js" index 870767c1..acbaabfb 100644 --- "a/\345\233\276\350\241\250\347\225\214\351\235\242\344\277\241\346\201\257\345\261\225\347\244\272\345\256\236\344\276\2131.js" +++ "b/\345\233\276\350\241\250\347\225\214\351\235\242\344\277\241\346\201\257\345\261\225\347\244\272\345\256\236\344\276\2131.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/36026 +策略出处: https://www.fmz.com/strategy/36026 策略名称: 图表界面信息展示实例1 策略作者: 太极 策略描述: diff --git "a/\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2.py" "b/\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2.py" index 25f4c7b9..7cf46c82 100644 --- "a/\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2.py" +++ "b/\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/21369 +策略出处: https://www.fmz.com/strategy/21369 策略名称: 均线-趋势_数字货币策略V0.2 策略作者: 太极 策略描述: diff --git "a/\345\235\207\347\272\277MA\346\214\207\346\240\207\344\275\277\347\224\250\350\214\203\344\276\213.js" "b/\345\235\207\347\272\277MA\346\214\207\346\240\207\344\275\277\347\224\250\350\214\203\344\276\213.js" deleted file mode 100644 index f1a0af7a..00000000 --- "a/\345\235\207\347\272\277MA\346\214\207\346\240\207\344\275\277\347\224\250\350\214\203\344\276\213.js" +++ /dev/null @@ -1,28 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/46484 -策略名称: 均线MA指标使用范例 -策略作者: yilidalei -策略描述: - - - -*/ - -function main(){ - while(true){ - var records = exchange.GetRecords(PERIOD_D1) - if(!records || records.length < 60){ - continue - } - - $.PlotRecords(records, 'K线 - MA60') - - var MA60 = TA.MA(records, 60) - - $.PlotLine('MA60', MA60[MA60.length - 1], records[records.length - 1].Time) - - LogStatus(_D(), '\n', "当前K线bar", records[records.length - 1], '\n', "当前MA60指标:", MA60[MA60.length - 1]) - - Sleep(500) - } -} diff --git "a/\345\235\207\347\272\277\347\255\226\347\225\245 30 \350\241\214\346\220\236\345\256\232.js" "b/\345\235\207\347\272\277\347\255\226\347\225\245 30 \350\241\214\346\220\236\345\256\232.js" index 1ba0ed58..f8d7145b 100644 --- "a/\345\235\207\347\272\277\347\255\226\347\225\245 30 \350\241\214\346\220\236\345\256\232.js" +++ "b/\345\235\207\347\272\277\347\255\226\347\225\245 30 \350\241\214\346\220\236\345\256\232.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/12348 +策略出处: https://www.fmz.com/strategy/12348 策略名称: 均线策略 30 行搞定 策略作者: Zero 策略描述: diff --git "a/\345\235\207\347\272\277\347\255\226\347\225\245\357\274\210python\347\211\210\357\274\211.py" "b/\345\235\207\347\272\277\347\255\226\347\225\245\357\274\210python\347\211\210\357\274\211.py" index b8158360..4e5c4745 100644 --- "a/\345\235\207\347\272\277\347\255\226\347\225\245\357\274\210python\347\211\210\357\274\211.py" +++ "b/\345\235\207\347\272\277\347\255\226\347\225\245\357\274\210python\347\211\210\357\274\211.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/21157 +策略出处: https://www.fmz.com/strategy/21157 策略名称: 均线策略(python版) 策略作者: 小小梦 策略描述: diff --git "a/\345\237\272\344\272\216CCI\345\221\250\346\234\237\346\200\247\345\214\272\351\227\264\344\272\244\346\230\223\347\255\226\347\225\245.js" "b/\345\237\272\344\272\216CCI\345\221\250\346\234\237\346\200\247\345\214\272\351\227\264\344\272\244\346\230\223\347\255\226\347\225\245.js" new file mode 100644 index 00000000..18ac7bc0 --- /dev/null +++ "b/\345\237\272\344\272\216CCI\345\221\250\346\234\237\346\200\247\345\214\272\351\227\264\344\272\244\346\230\223\347\255\226\347\225\245.js" @@ -0,0 +1,73 @@ +/* +策略出处: https://www.fmz.com/strategy/60287 +策略名称: 基于CCI周期性区间交易策略 +策略作者: 深蓝 +策略描述: + + + + +参数 默认值 描述 +--------- ------ ----- +Diff 40 周期区间 +Length 100 周期长度 +AvgLength 10 CCI均值 +Name rb1810 合约代码 +*/ + +/*backtest +start: 2015-01-01 09:00:00 +end: 2018-04-22 15:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","minfee":0,"fee":[0,0]}] +*/ + + +//语法固定格式,调用main主函数 +function main() { + //调用商品期货交易类库中的CTA框架 + $.CTA(Name, function(st) { + //获取K线数组 + var j = st.records; + //指标运算参考的最大K线数量 + if (j.length < Length) { + return; + } + //获取上根K线的收盘价 + var c1 = j[j.length - 2].Close; + //获取前根K线的收盘价 + var c2 = j[j.length - 3].Close; + //获取CCI指标数组 + var cci = talib.CCI(j, Length); + //计算上根K线的CCI平均值 + var sum1 = 0; + for (var i = cci.length - 1 - 1; i >= cci.length - AvgLength - 1; i--) { + sum1 += cci[i]; + } + var ccima1 = sum1 / AvgLength; + //计算前根K线的CCI平均值 + var sum2 = 0; + for (var k = cci.length - 1 - 2; k >= cci.length - AvgLength - 2; k--) { + sum2 += cci[k]; + } + var ccima2 = sum2 / AvgLength; + //获取当前的持仓数量,正数指多仓, 负数指空仓, 0则不持仓 + var mp = st.position.amount; + //如果当前无持仓,并且上根K线的收盘价大于上根K线的MA值,并且上根K线的K值大于上根K线的D值,开多单 + if (mp === 0 && ccima2 < Diff && ccima1 > Diff) { + return 1; //如果当前无持仓,指定返回值为N,就是开N手多单。 + } + //如果当前无持仓,并且上根K线的收盘价小于上根K线的MA值,并且上根K线的K值小于上根K线的D值,开空单 + if (mp === 0 && ccima2 > -Diff && ccima1 < -Diff) { + return -1; //如果当前无持仓,指定返回值为-N,就是开N手空单。 + } + //如果当前持有多单,并且上根K线的K值小于上根K线的D值,平多单 + if (mp > 0 && ccima2 > Diff && ccima1 < Diff) { + return -1; //如果当前有多单,指定返回值为-N,就是平N手多单。 + } + //如果当前持有空单,并且上根K线的K值大于上根K线的D值,平空单 + if (mp < 0 && ccima2 < -Diff && ccima1 > -Diff) { + return 1; //如果当前有空单,指定返回值为N,就是平N手空单。 + } + }); +} diff --git "a/\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.js" "b/\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.js" index 6c7e750e..4baa2e57 100644 --- "a/\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.js" +++ "b/\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/47144 +策略出处: https://www.fmz.com/strategy/47144 策略名称: 多均线策略 策略作者: 小小梦 策略描述: diff --git "a/\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).js" "b/\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).js" index c5459b5c..3d917027 100644 --- "a/\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).js" +++ "b/\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/99 +策略出处: https://www.fmz.com/strategy/99 策略名称: 多平台强制滑动平仓(买一价) 策略作者: Zero 策略描述: diff --git "a/\345\244\232\345\271\263\345\217\260\350\264\246\346\210\267\347\273\237\350\256\241.js" "b/\345\244\232\345\271\263\345\217\260\350\264\246\346\210\267\347\273\237\350\256\241.js" index a6be8af5..8400cfbd 100644 --- "a/\345\244\232\345\271\263\345\217\260\350\264\246\346\210\267\347\273\237\350\256\241.js" +++ "b/\345\244\232\345\271\263\345\217\260\350\264\246\346\210\267\347\273\237\350\256\241.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/7827 +策略出处: https://www.fmz.com/strategy/7827 策略名称: 多平台账户统计 策略作者: 数·狂 策略描述: diff --git "a/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\346\267\261\345\272\246\344\277\241\346\201\257.js" "b/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\346\267\261\345\272\246\344\277\241\346\201\257.js" index 78a13eb4..9e7099af 100644 --- "a/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\346\267\261\345\272\246\344\277\241\346\201\257.js" +++ "b/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\346\267\261\345\272\246\344\277\241\346\201\257.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/3651 +策略出处: https://www.fmz.com/strategy/3651 策略名称: 多线程获取多个交易的深度信息 策略作者: Zero 策略描述: diff --git "a/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\350\264\246\346\210\267\344\277\241\346\201\257.js" "b/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\350\264\246\346\210\267\344\277\241\346\201\257.js" index b6164066..741b2786 100644 --- "a/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\350\264\246\346\210\267\344\277\241\346\201\257.js" +++ "b/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\350\264\246\346\210\267\344\277\241\346\201\257.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/3297 +策略出处: https://www.fmz.com/strategy/3297 策略名称: 多线程获取多个交易的账户信息 策略作者: Zero 策略描述: diff --git "a/\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.js" "b/\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.js" index b22c7130..584033cf 100644 --- "a/\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.js" +++ "b/\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/58179 +策略出处: https://www.fmz.com/strategy/58179 策略名称: 如何找出一定Bar数量的 K线前期高点、低点 及 Demo 程序 策略作者: 小小梦 策略描述: diff --git "a/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210 (Copy).js" "b/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210 (Copy).js" deleted file mode 100644 index 69d77ff4..00000000 --- "a/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210 (Copy).js" +++ /dev/null @@ -1,76 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/83805 -策略名称: 定投简单版 (Copy) -策略作者: thifeathe -策略描述: - - - - -参数 默认值 描述 ------------------- ----- ----- -singleInvestAmount 0.1 单次买入量 -*/ - -// botvs@620e5a1b33965b615ef40e1d29cd2c44 - -/*backtest - start: 2017-12-01 - end: 2018-01-01 - period: 60 - mode: 2 -*/ - -function dateFormat(date, format) { - var o = { - "M+": date.getMonth() + 1, //月份 - "d+": date.getDate(), //日 - "h+": date.getHours(), //小时 - "m+": date.getMinutes(), //分 - "s+": date.getSeconds(), //秒 - "q+": Math.floor((date.getMonth() + 3) / 3), //季度 - "S": date.getMilliseconds() //毫秒 - }; - if (/(y+)/.test(format)) { - format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length)); - } - - for (var k in o) { - if (new RegExp("(" + k + ")").test(format)) { - format = format.replace(RegExp.$1, (RegExp.$1.length == 1) ? - (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); - } - } - - return format; -} - - -function main() { - Log(exchange.GetAccount()); - - //最近一次投资的日期 - var lastInvestDate = ''; - - while (true) { - //每次轮询,间隔时间为60秒 - Sleep(60 * 1000); - - //如果当前日期和最近一次投资日期相同,说明当天已经投过了,跳过 - var date = dateFormat(new Date(), "yyyy-MM-dd"); - if (date == lastInvestDate) { - continue; - } - - lastInvestDate = date; - Log("日期: " + date); - - //获取当前深度 - var depth = exchange.GetDepth(); - - //以买1价挂一个买入单 - var buy1price = depth.Bids[0].Price; - exchange.Buy(buy1price, singleInvestAmount / buy1price); - } -} - diff --git "a/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.js" "b/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.js" index 1baa1d28..1791a637 100644 --- "a/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.js" +++ "b/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/67098 +策略出处: https://www.fmz.com/strategy/67098 策略名称: 定投简单版 策略作者: 小码哥 策略描述: diff --git "a/\345\256\232\346\234\237\345\256\232\351\242\235\346\212\225\350\265\204BTC\347\233\210\345\210\251\351\252\214\350\257\201.js" "b/\345\256\232\346\234\237\345\256\232\351\242\235\346\212\225\350\265\204BTC\347\233\210\345\210\251\351\252\214\350\257\201.js" index ee8aecc3..e8ce8c3b 100644 --- "a/\345\256\232\346\234\237\345\256\232\351\242\235\346\212\225\350\265\204BTC\347\233\210\345\210\251\351\252\214\350\257\201.js" +++ "b/\345\256\232\346\234\237\345\256\232\351\242\235\346\212\225\350\265\204BTC\347\233\210\345\210\251\351\252\214\350\257\201.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/16845 +策略出处: https://www.fmz.com/strategy/16845 策略名称: 定期定额投资BTC盈利验证 策略作者: 春哥 策略描述: diff --git "a/\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.js" "b/\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.js" index f84f1738..6abd4653 100644 --- "a/\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.js" +++ "b/\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/64 +策略出处: https://www.fmz.com/strategy/64 策略名称: 定点进场下单定点离场卖单 策略作者: Zero 策略描述: diff --git "a/\345\256\236\347\233\230\350\264\246\346\210\267\346\250\241\346\213\237\345\231\250.js" "b/\345\256\236\347\233\230\350\264\246\346\210\267\346\250\241\346\213\237\345\231\250.js" deleted file mode 100644 index 97db2cb6..00000000 --- "a/\345\256\236\347\233\230\350\264\246\346\210\267\346\250\241\346\213\237\345\231\250.js" +++ /dev/null @@ -1,362 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/35977 -策略名称: 实盘账户模拟器 -策略作者: 小小梦 -策略描述: - -实盘 账户模拟器 -用于在实盘环境中,模拟交易,不真实下单。 -减少测试成本。 - - -参数 默认值 描述 -------------------- ------------------------ ------- -VirtualExchangeList 0, 3, 10000; 1, 4, 15000 模拟交易所列表 -isUse true 是否启用 -*/ - -/*参数 -*/ -//功能函数 -var VirtualIndex = 0; -var Originals = []; -var Accounts = []; -var VirtualOrderID = 0; -var VirtualOrders = []; -var BUY = 0; -var SELL = 1; - -// 功能函数 -function CalcMarketOrderDealPrice(Amount, current_e_Index, direction){ - var depth = null; - var dealPrice = null; - while(true){ - depth = exchanges[current_e_Index].GetDepth(); - if(depth && depth.Asks.length !== 0 && depth.Bids.length !== 0){ - break; - } - Sleep(500); - } - var deep = null; - var sumAmount = 0; - var sumPay = 0; - direction == BUY ? deep = depth.Asks : deep = depth.Bids; - for(var i = 0 ; i < deep.length ; i++){ - sumAmount += deep[i].Amount; - if(Amount < sumAmount){ - sumPay += (Amount - (sumAmount - deep[i].Amount)); - dealPrice = _N(sumPay / Amount); - } - sumPay += deep[i].Amount * deep[i].Price; - } - return dealPrice; -} - -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; -}; - -function init(){ - if(isUse){ - var maxlenth = exchanges.length; - var VE_str = VirtualExchangeList.split(';'); - var VES = []; - if(maxlenth < VE_str.length){ - throw "VirtualExchangeList 参数 与 添加的交易所 不匹配!--> VirtualExchangeList:" + VirtualExchangeList; - } - - for(var i = 0 ; i < VE_str.length; i++){ - var ele_array = VE_str[i].split(','); - - if(ele_array.length !== 3 || isNaN(Number(ele_array[0])) || isNaN(Number(ele_array[1])) || isNaN(Number(ele_array[2]))){ - throw "VirtualExchangeList 参数错误: " + ele_array; - } - var VE = { - exchangeIndex : Number(ele_array[0]), - VirtualStocks : Number(ele_array[1]), - VirtualBalance : Number(ele_array[2]), - }; - VES.push(VE); - } - for(var x = 0 ; x < VES.length ; x++){ - $.OpenVirtual(exchanges[VES[x].exchangeIndex], VES[x].VirtualStocks, VES[x].VirtualBalance); - Log("初始化交易所模拟账户,名称:", exchanges[VES[x].exchangeIndex].GetName(), "模拟账户信息:", _C(exchanges[VES[x].exchangeIndex].GetAccount), "手续费:",exchanges[VES[x].exchangeIndex].GetFee()); - } - } -} - -// 导出函数 -$.OpenVirtual = function(e, Stocks, Balance){ - var obj = {}; - if(typeof(e) !== "object"){ - throw "需要模拟的交易所对象错误,e参数类型:" + typeof(e); - } - if(e.GetName() === 'undefined'){ - throw "参数e 不是交易所对象:"; - } - - VirtualIndex++; - e.VirtualIndex = VirtualIndex; - - var Original = { - IndexOn_exchanges : null, - Name : null, - GetAccount : null, - Buy : null, - Sell : null, - GetOrder : null, - Go : null, - Fee : null, - }; - - var current_e_Index = null; - for(var i = 0; i < exchanges.length; i++){ - if(exchanges[i].VirtualIndex === VirtualIndex){ - current_e_Index = i; - } - } - - // 储存原始 引用, 其它数据 - Original.IndexOn_exchanges = current_e_Index; - Original.GetAccount = e.GetAccount; - Original.Buy = e.Buy; - Original.Sell = e.Sell; - Original.GetOrder = e.GetOrder; - Original.Go = e.Go; - Original.Name = e.GetName(); - Original.Fee = e.GetFee(); - - var Account = { - Stocks: Stocks, // Stocks - FrozenStocks : 0, // FrozenStocks - Balance : Balance, // Balance - FrozenBalance : 0 // FrozenBalance - }; - - Accounts[current_e_Index] = Account; - Originals[current_e_Index] = Original; - - // 替换API - exchanges[current_e_Index].GetAccount = function(){ - // 需要深拷贝 - return cloneObj(Accounts[current_e_Index]); // clone - } - - exchanges[current_e_Index].Buy = function(Price, Amount){ - // 处理默认参数 - var args = arguments; - var parm = ""; - if(args && args.length > 2){ - for(var j = 2 ; j < args.length; j++){ - parm += args[j]; - } - } - - if(Price == -1){ // 处理市价单 - // 输出Log - Log(Originals[current_e_Index].Name, "              买入  " + "市价单" + "   " + Amount + "  " + parm + "#007FFF"); // blue - var dealPrice = CalcMarketOrderDealPrice(Amount, current_e_Index, BUY); // 根据市价单下单量计算盘口 可吃单的实际成交价。 - - - if(dealPrice * Amount > Accounts[current_e_Index].Balance){ - Log("错误:没有足够的钱买:", "数量:", Amount, Accounts[current_e_Index]); - return; - } - // 更新账户数据 - Accounts[current_e_Index].Stocks += (Amount - Originals[current_e_Index].Fee.Buy * Amount); // 扣除手续费 - Accounts[current_e_Index].Balance -= Amount * dealPrice; - - // 返回ID - if(VirtualOrderID > Number.MAX_VALUE - 100){ - VirtualOrderID = 0; - } - VirtualOrderID++; - - // 模拟产生order - var order = {"Id": VirtualOrderID, "Price": Price, "Amount": Amount, "DealAmount": Amount, "Type": 0, "Status": 1, "AvgPrice": dealPrice}; - VirtualOrders.push(order); - - return VirtualOrderID; - }else{ // 限价单处理的有问题 - // 输出Log - Log(Originals[current_e_Index].Name, "              买入  " + Price + "   " + Amount + "  " + parm + "#007FFF"); // blue - - var ticker = _C(exchanges[current_e_Index].GetTicker); - if(Price > ticker.Last + 10 || Price < ticker.Last - 10){ - Log("错误:下单价格无效,当前最后成交价:", ticker.Last, "ticker:", ticker); - return; - } - if(Price * Amount > Accounts[current_e_Index].Balance){ - Log("错误:下单价格无效,没有足够的钱买, Price:", Price, "数量:", Amount); - return; - } - // 更新账户数据 - Accounts[current_e_Index].Stocks += Amount; - Accounts[current_e_Index].Balance -= Amount * Price; - - // 返回ID - if(VirtualOrderID > Number.MAX_VALUE - 100){ - VirtualOrderID = 0; - } - VirtualOrderID++; - - // 模拟产生order - var order = {"Id": VirtualOrderID, "Price": Price, "Amount": Amount, "DealAmount": Amount, "Type": 0, "Status": 1, "AvgPrice": Price}; - VirtualOrders.push(order); - - return VirtualOrderID; - } - } - - exchanges[current_e_Index].Sell = function(Price, Amount){ - //Log("测试Sell"); // 测试 - // 处理默认参数 - var args = arguments; - var parm = ""; - if(args && args.length > 2){ - for(var j = 2 ; j < args.length; j++){ - parm += args[j]; - } - } - - if(Price == -1){ // 处理市价单 - // 输出Log - Log(Originals[current_e_Index].Name, "              卖出  " + "市价单" + "   " + Amount + "  " + parm + "#32CD32"); // green - var dealPrice = CalcMarketOrderDealPrice(Amount, current_e_Index, SELL); // 根据市价单下单量计算盘口 可吃单的实际成交价。 - - if(Amount > Accounts[current_e_Index].Stocks){ - Log("错误:没有足够的 标的物:", "数量:", Amount, Accounts[current_e_Index]); - return; - } - // 更新账户数据 - Accounts[current_e_Index].Stocks -= Amount; - Accounts[current_e_Index].Balance += (Amount * dealPrice - Originals[current_e_Index].Fee.Sell * Amount * dealPrice); // 扣除手续费 - - // 返回ID - if(VirtualOrderID > Number.MAX_VALUE - 100){ - VirtualOrderID = 0; - } - VirtualOrderID++; - - // 模拟产生order - var order = {"Id": VirtualOrderID, "Price": Price, "Amount": Amount, "DealAmount": Amount, "Type": 1, "Status": 1, "AvgPrice": dealPrice}; - VirtualOrders.push(order); - - return VirtualOrderID; - }else{ // 限价单处理的有问题 - // 输出Log - Log(Originals[current_e_Index].Name, "              卖出  " + Price + "   " + Amount + "  " + parm + "#32CD32"); // green - - var ticker = _C(exchanges[current_e_Index].GetTicker); - if(Price > ticker.Last + 10 || Price < ticker.Last - 10){ - Log("错误:下单价格无效,当前最后成交价:", ticker.Last, "ticker:", ticker); - return; - } - if(Amount > Accounts[current_e_Index].Stocks){ - Log("错误:下单价格无效,没有足够的 标的物, Price:", Price, "数量:", Amount); - return; - } - // 更新账户数据 - Accounts[current_e_Index].Stocks -= Amount; - Accounts[current_e_Index].Balance += Amount * Price; - - // 返回ID - if(VirtualOrderID > Number.MAX_VALUE - 100){ - VirtualOrderID = 0; - } - VirtualOrderID++; - - // 模拟产生order - var order = {"Id": VirtualOrderID, "Price": Price, "Amount": Amount, "DealAmount": Amount, "Type": 1, "Status": 1, "AvgPrice": Price}; - VirtualOrders.push(order); - - return VirtualOrderID; - } - } - - exchanges[current_e_Index].GetOrder = function(OrderId){ - if(VirtualOrders.length > 300){ - VirtualOrders.shift(); - } - for(var i = 0 ; i < VirtualOrders.length ; i++){ - if(OrderId == VirtualOrders[i].Id){ - return VirtualOrders[i]; - } - } - Log("错误:查询无此ID订单", OrderId); - return null; - } - - exchanges[current_e_Index].Go = function(arg1){ - var args = arguments; - if(arg1 == "Buy" || arg1 == "Sell" || arg1 == "GetAccount" || arg1 == "GetOrder"){ - var GoObj = {}; - if(arg1 == "Buy"){ - GoObj.wait = function(time){ - return exchanges[current_e_Index].Buy(args[1], args[2]); - } - return GoObj; - }else if(arg1 == "Sell"){ - GoObj.wait = function(time){ - return exchanges[current_e_Index].Sell(args[1], args[2]); - } - return GoObj; - }else if(arg1 == "GetAccount"){ - GoObj.wait = function(time){ - return exchanges[current_e_Index].GetAccount(); - } - return GoObj; - }else if(arg1 == "GetOrder"){ - GoObj.wait = function(time){ - return exchanges[current_e_Index].GetOrder(args[1]); - } - return GoObj; - } - }else{ - // exchanges[current_e_Index].Go = Originals[current_e_Index].Go; - // Log(current_e_Index, Originals[current_e_Index].Go, arg1, args); // ceshi - if(args.length === 3){ - return Originals[current_e_Index].Go(arg1, args[1], args[2]); - }else if(args.length === 2){ - return Originals[current_e_Index].Go(arg1, args[1]); - }else if(args.length === 1){ - return Originals[current_e_Index].Go(arg1); - } - } - } - -}; - -$.CloseVirtual = function(e){ - -}; - -$.SetSloid = function(){ - -}; - -// 测试 -function main(){ - Log(exchange.GetAccount()) - Log(exchange.Go("GetDepth").wait()) - $.OpenVirtual(exchange, 20, 300); - var initAccount = exchange.GetAccount(); - Log(initAccount); - Log(exchange.Go("GetDepth").wait()) -} - -/* -1、order 的结构 {"Id": 3, "Price": 1111, "Amount": 12, "DealAmount": 12, "Type": 1, "Status": 1, "AvgPrice": 0} // 0 Buy 1 Sell -*/ diff --git "a/\345\257\271\345\206\2622.7\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241\347\263\273\347\273\237 \346\224\257\346\214\201\345\244\232\347\273\204\350\264\246\345\217\267\347\273\237\350\256\241.js" "b/\345\257\271\345\206\2622.7\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241\347\263\273\347\273\237 \346\224\257\346\214\201\345\244\232\347\273\204\350\264\246\345\217\267\347\273\237\350\256\241.js" index 39efde51..bc068dba 100644 --- "a/\345\257\271\345\206\2622.7\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241\347\263\273\347\273\237 \346\224\257\346\214\201\345\244\232\347\273\204\350\264\246\345\217\267\347\273\237\350\256\241.js" +++ "b/\345\257\271\345\206\2622.7\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241\347\263\273\347\273\237 \346\224\257\346\214\201\345\244\232\347\273\204\350\264\246\345\217\267\347\273\237\350\256\241.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/18678 +策略出处: https://www.fmz.com/strategy/18678 策略名称: 对冲2.7收益率统计系统 支持多组账号统计 策略作者: Zero 策略描述: diff --git "a/\345\267\256\344\273\267\347\233\221\346\216\247.js" "b/\345\267\256\344\273\267\347\233\221\346\216\247.js" index c1ec183a..d0a9115b 100644 --- "a/\345\267\256\344\273\267\347\233\221\346\216\247.js" +++ "b/\345\267\256\344\273\267\347\233\221\346\216\247.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/1340 +策略出处: https://www.fmz.com/strategy/1340 策略名称: 差价监控 策略作者: Zero 策略描述: diff --git "a/\345\270\201\345\256\211\345\207\272\345\224\256\346\211\200\346\234\211\345\261\261\345\257\250\345\270\201.js" "b/\345\270\201\345\256\211\345\207\272\345\224\256\346\211\200\346\234\211\345\261\261\345\257\250\345\270\201.js" new file mode 100644 index 00000000..ce6b8953 --- /dev/null +++ "b/\345\270\201\345\256\211\345\207\272\345\224\256\346\211\200\346\234\211\345\261\261\345\257\250\345\270\201.js" @@ -0,0 +1,55 @@ +/* +策略出处: https://www.fmz.com/strategy/97629 +策略名称: 币安出售所有山寨币 +策略作者: Zero +策略描述: + + + + +参数 默认值 描述 +--------- ----- --------------------- +quoteZone 0 交易区: BTC|ETH|BNB|USDT +*/ + +function main() { + var quoteCurrency = ['BTC', 'ETH', 'BNB', 'USDT'][quoteZone]; + Log("当前交易区", quoteCurrency); + var symbols = JSON.parse(_C(HttpQuery, "https://api.binance.com/api/v1/exchangeInfo")).symbols; + _.each(_C(exchange.GetAccount).Info.balances, function(ele) { + if (ele.asset == quoteCurrency) { + return + } + var totalV = parseFloat(ele.free) + parseFloat(ele.locked); + if (totalV == 0) { + return; + } + var cfg = _.findWhere(symbols, {symbol: ele.asset+quoteCurrency}); + if (!cfg) { + Log("没有找到", ele.asset, "交易对的配置", ele); + return; + } + var filter = _.findWhere(cfg.filters, {filterType: "LOT_SIZE"}); + if (!filter) { + return; + } + + var v = _N(parseInt(totalV/filter.stepSize)*filter.stepSize, cfg.baseAssetPrecision); + if (v > 0) { + Log(ele, "stepSize", filter.stepSize); + exchange.IO("currency", ele.asset + "_"+quoteCurrency); + while (true) { + var orders = _C(exchange.GetOrders); + _.each(orders, function(order) { + exchange.CancelOrder(order.Id); + }); + if (orders.length == 0) { + break; + } + } + exchange.Sell(-1, v); + Log(ele); + } + }); + Log("操作完成, 当前", quoteCurrency, "数量", _C(exchange.GetAccount).Balance); +} diff --git "a/\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.py" "b/\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.py" index 25686e0d..6595cfd3 100644 --- "a/\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.py" +++ "b/\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/52801 +策略出处: https://www.fmz.com/strategy/52801 策略名称: 布林均线突破_vnpy_botvs实现版 策略作者: ipqhjjybj 策略描述: diff --git "a/\345\271\263\345\217\260\344\273\267\346\240\274\346\214\207\346\240\207\347\233\221\346\216\2471.1.js" "b/\345\271\263\345\217\260\344\273\267\346\240\274\346\214\207\346\240\207\347\233\221\346\216\2471.1.js" index c1631f4d..a5f89828 100644 --- "a/\345\271\263\345\217\260\344\273\267\346\240\274\346\214\207\346\240\207\347\233\221\346\216\2471.1.js" +++ "b/\345\271\263\345\217\260\344\273\267\346\240\274\346\214\207\346\240\207\347\233\221\346\216\2471.1.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/12442 +策略出处: https://www.fmz.com/strategy/12442 策略名称: 平台价格指标监控1.1 策略作者: tfboys 策略描述: diff --git "a/\345\271\263\345\217\260\344\273\267\346\240\274\346\257\224\350\276\2031.0.js" "b/\345\271\263\345\217\260\344\273\267\346\240\274\346\257\224\350\276\2031.0.js" index 783d68bc..184f2884 100644 --- "a/\345\271\263\345\217\260\344\273\267\346\240\274\346\257\224\350\276\2031.0.js" +++ "b/\345\271\263\345\217\260\344\273\267\346\240\274\346\257\224\350\276\2031.0.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/8266 +策略出处: https://www.fmz.com/strategy/8266 策略名称: 平台价格比较1.0 策略作者: tfboys 策略描述: diff --git "a/\345\271\275\347\201\265\344\272\244\346\230\223\350\200\205\347\255\226\347\225\245 (Share 1512580165).js" "b/\345\271\275\347\201\265\344\272\244\346\230\223\350\200\205\347\255\226\347\225\245 (Share 1512580165).js" index 8b9d8cd9..2110b7e5 100644 --- "a/\345\271\275\347\201\265\344\272\244\346\230\223\350\200\205\347\255\226\347\225\245 (Share 1512580165).js" +++ "b/\345\271\275\347\201\265\344\272\244\346\230\223\350\200\205\347\255\226\347\225\245 (Share 1512580165).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/62303 +策略出处: https://www.fmz.com/strategy/62303 策略名称: 幽灵交易者策略 (Share 1512580165) 策略作者: ellajella-0378 策略描述: diff --git "a/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.js" "b/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.js" index 58449c0d..86aeb639 100644 --- "a/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.js" +++ "b/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/304 +策略出处: https://www.fmz.com/strategy/304 策略名称: 抢盘口做市策略 - 对敲 策略作者: Zero 策略描述: diff --git "a/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \351\253\230\351\242\221\351\200\274\350\277\221\345\236\213.js" "b/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \351\253\230\351\242\221\351\200\274\350\277\221\345\236\213.js" index b1b26d5d..e9a67cd8 100644 --- "a/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \351\253\230\351\242\221\351\200\274\350\277\221\345\236\213.js" +++ "b/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \351\253\230\351\242\221\351\200\274\350\277\221\345\236\213.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/348 +策略出处: https://www.fmz.com/strategy/348 策略名称: 抢盘口做市策略 - 高频逼近型 策略作者: Zero 策略描述: @@ -17,6 +17,7 @@ Step 0.1 网格间隔(元) Lot 0.05 手数 MaxNets 20 最大网格数 DisableLog false 关闭订单跟踪 +MinStock 0.01 最小交易币数 */ function adjustFloat(v) { @@ -130,7 +131,7 @@ function main() { InitAccount = GetAccount(); Log(InitAccount); LoopInterval = Math.max(LoopInterval, 1); - Lot = Math.max(exchange.GetMinStock(), Lot); + Lot = Math.max(MinStock, Lot); while (true) { onTick(); Sleep(LoopInterval * 1000); diff --git "a/\346\214\207\346\225\260\351\207\217\345\214\226.js" "b/\346\214\207\346\225\260\351\207\217\345\214\226.js" new file mode 100644 index 00000000..72c0eee9 --- /dev/null +++ "b/\346\214\207\346\225\260\351\207\217\345\214\226.js" @@ -0,0 +1,222 @@ +/* +策略出处: https://www.fmz.com/strategy/91704 +策略名称: 指数量化 +策略作者: 6821281 +策略描述: + + + + +参数 默认值 描述 +---------- ----- -------------------------------- +junxianx true 均线值 +junxiant true 均线天数 +rise_fall 0 当前时间的前一小时或前一日收盘价: 请选择|小时|日 +rise_warn true 涨幅预警值 +fall_warn true 跌幅预警值 +macdwarn 8000 macd提醒值 +macdzhouqi 0 macd周期: 1分钟|5分钟|15分钟|30分钟|1小时|一天 +kdj1 9 周期1值 +kdj2 3 周期2值 +kdj3 3 周期3值 +kdjkwarn true k提醒值 +kdjdwarn true d提醒值 +kdjjwarn true j提醒值 +kdjtp 0 周期均线类型: 1分钟|5分钟|15分钟|30分钟|1小时|一天 +*/ + + +//均线模块 +function juxian(){ + var records = exchange.GetRecords() + if (records && records.length > junxiant) { + var ema = TA.EMA(records, junxiant) // K线bar 数量满足指标计算周期。 + + if(ema[ema.length-2]>junxianx && ema[ema.length-1]>junxianx){ + Log("均线值超过设定值!当前日均线:",ema[ema.length-1]," 前一均线值:",ema[ema.length-2],"设定均线值为:",junxianx); + } + + + + if(ema[ema.length-2]0 && ((nowPrice-lastPrice)/lastPrice)>(rise_warn/100)){ + Log("当前价格:",nowPrice,"上一收盘价:",lastPrice,"涨幅达到:"+rise_warn+"%") + } + //跌幅 + if((lastPrice-nowPrice)>0 && ((lastPrice-nowPrice)/lastPrice)>(fall_warn/100)){ + Log("当前价格:",nowPrice,"上一收盘价:",lastPrice,"跌幅达到:"+rise_warn+"%") + } + //跌幅 +} + +//macd提醒值 +function macdwarning(){ + if(!macdzhouqi){ + macdzhouqi=0; + } + var macdarr = new Array(); + macdarr[0]=PERIOD_M1; + macdarr[1]=PERIOD_M5; + macdarr[2]=PERIOD_M15; + macdarr[3]=PERIOD_M30; + macdarr[4]=PERIOD_H1; + macdarr[5]=PERIOD_D1; + var records = exchange.GetRecords(macdarr[macdzhouqi]);//可以填入不同k线周期,比如PERIOD_M1,PERIOD_M30,PERIOD_H1...... + var macd = TA.MACD(records, 12, 26, 9); + if( macd[2][macd[2].length-2]>macdwarn && macd[2][macd[2].length-1]>macdwarn){ + + Log("前一Macd值大于设定值 当前Macd值大于设定值!前一值:", + macd[2][macd[2].length-2],"当前值:",macd[2][macd[2].length-1],"设定值",macdwarn); + + } + + + if( macd[2][macd[2].length-2] kdjkwarn && k[k.length-1] >kdjkwarn){ + + Log("前一K值,当前K值 大于预警值!前一:",k[k.length-2],"当前:",k[k.length-1],"预警:",kdjkwarn); + } + + + if(d[d.length-2] > kdjdwarn && d[d.length-1] >kdjdwarn){ + + Log("前一d值,当前d值 大于预警值! 前一:",d[d.length-2],"当前:",d[d.length-1],"预警:",kdjdwarn); + } + + + if(j[j.length-2] > kdjjwarn && j[j.length-1] >kdjjwarn){ + + Log("前一j值,当前j值 大于预警值! 前一:",j[j.length-2],"当前:",j[j.length-1],"预警:",kdjjwarn); + } + if(k[k.length-2] 0) { - extra = "成交: " + orders[i].DealAmount; - } else { - extra = "未成交"; - } - e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); - dropped++; - } - } - if (dropped === 0) { - break; - } - Sleep(RetryDelay); - } - return order; -} - -// mode = 0 : direct buy, 1 : buy as buy1 -function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, retryDelay) { - var initAccount = GetAccount(e, true); - var nowAccount = initAccount; - var orderId = null; - var prePrice = 0; - var dealAmount = 0; - var diffMoney = 0; - var isFirst = true; - var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell; - var isBuy = tradeType == ORDER_TYPE_BUY; - while (true) { - var ticker = _C(e.GetTicker); - var tradePrice = 0; - if (isBuy) { - tradePrice = _N((mode === 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4); - } else { - tradePrice = _N((mode === 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4); - } - if (!orderId) { - if (isFirst) { - isFirst = false; - } else { - nowAccount = GetAccount(e, true); - } - var doAmount = 0; - if (isBuy) { - diffMoney = _N(initAccount.Balance - nowAccount.Balance, 4); - dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 8); // 如果保留小数过少,会引起在小交易量交易时,计算出的成交价格误差较大。 - doAmount = Math.min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance - 10) / tradePrice, 4)); - } else { - diffMoney = _N(nowAccount.Balance - initAccount.Balance, 4); - dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 8); - doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); - } - if (doAmount < _GetMinStocks) { - break; - } - prePrice = tradePrice; - orderId = tradeFunc(tradePrice, doAmount, ticker); - if (!orderId) { - CancelPendingOrders(e, tradeType); - } - } else { - if (mode === 0 || (Math.abs(tradePrice - prePrice) > maxSpace)) { - orderId = null; - } - var order = StripOrders(e, orderId); - if (!order) { - orderId = null; - } - } - Sleep(retryDelay); - } - - if (dealAmount <= 0) { - return null; - } - - return { - price: _N(diffMoney / dealAmount, 4), - amount: dealAmount - }; -} - -$.Buy = function(e, amount) { - if (typeof(e) === 'number') { - amount = e; - e = exchange; - } - return Trade(e, ORDER_TYPE_BUY, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); -}; - -$.Sell = function(e, amount) { - if (typeof(e) === 'number') { - amount = e; - e = exchange; - } - return Trade(e, ORDER_TYPE_SELL, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); -}; - -$.CancelPendingOrders = function(e, orderType) { - if (typeof(orderType) === 'undefined') { - if (typeof(e) === 'number') { - orderType = e; - e = exchange; - } else if (typeof(e) === 'undefined') { - e = exchange; - } - } - return CancelPendingOrders(e, orderType); -}; - -$.GetAccount = function(e) { - if (typeof(e) === 'undefined') { - e = exchange; - } - return _C(e.GetAccount); -}; - -var _MACalcMethod = [TA.EMA, TA.MA, talib.KAMA][MAType]; - -// 返回上穿的周期数. 正数为上穿周数, 负数表示下穿的周数, 0指当前价格一样 -$.Cross = function(a, b) { - var crossNum = 0; - var arr1 = []; - var arr2 = []; - if (Array.isArray(a)) { - arr1 = a; - arr2 = b; - } else { - var records = null; - while (true) { - records = exchange.GetRecords(); - if (records && records.length > a && records.length > b) { - break; - } - Sleep(RetryDelay); - } - arr1 = _MACalcMethod(records, a); - arr2 = _MACalcMethod(records, b); - } - if (arr1.length !== arr2.length) { - throw "array length not equal"; - } - for (var i = arr1.length-1; i >= 0; i--) { - if (typeof(arr1[i]) !== 'number' || typeof(arr2[i]) !== 'number') { - break; - } - if (arr1[i] < arr2[i]) { - if (crossNum > 0) { - break; - } - crossNum--; - } else if (arr1[i] > arr2[i]) { - if (crossNum < 0) { - break; - } - crossNum++; - } else { - break; - } - } - return crossNum; -}; - -// 期货部分 -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) && direction == PD_LONG) || ((positions[i].Type == PD_SHORT) && 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; - var step = 0; - while (true) { - var needOpen = opAmount; - if (isFirst) { - isFirst = false; - } else { - positionNow = GetPosition(e, contractType, direction); - if (positionNow) { - needOpen = opAmount - (positionNow.Amount - initAmount); - } - } - if (needOpen < 1) { - break; - } - if (step > max_open_lv) { - break; - } - var amount = needOpen; - e.SetDirection(direction == PD_LONG ? "buy" : "sell"); - var orderId; - if (direction == PD_LONG) { - orderId = e.Buy(price + F_SlidePrice * (1 + step), amount, "开多仓", contractType, price); - } else { - orderId = e.Sell(price - F_SlidePrice * (1 + step), amount, "开空仓", contractType, price); - } - while (true) { - var orders = _C(e.GetOrders); - if (orders.length === 0) { - break; - } - Sleep(Interval); - for (var j = 0; j < orders.length; j++) { - e.CancelOrder(orders[j].Id); - if (j < (orders.length - 1)) { - Sleep(Interval); - } - } - } - step += lv; - } - 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, OP_amount, direction) { - var initP = null; - var positions = null; - var isFirst = true; - var ID = null; - var step = 0; - var index = 0; - while (true) { - var n = 0; - positions = _C(e.GetPosition); - if (isFirst === true) { - if (typeof(direction) === 'undefined' && positions.length > 1 || (direction !== PD_LONG && direction !== PD_SHORT && typeof(direction) !== 'undefined')) { - throw "有多,空双向持仓,并且参数direction未明确方向!或 direction 参数异常:" + direction; - } - initP = positions; - isFirst = false; - } - for (var i = 0; i < positions.length; i++) { - if (positions[i].ContractType != contractType || (positions[i].Type !== direction && typeof(direction) !== 'undefined')) { - continue; - } - var amount = 0; - if (typeof(OP_amount) === 'undefined') { - amount = positions[i].Amount; - } else { - amount = OP_amount - (initP[i].Amount - positions[i].Amount); - } - - if (amount === 0) { - continue; - } - if (positions[i].Type == PD_LONG) { - e.SetDirection("closebuy"); - ID = e.Sell(price - F_SlidePrice * (1 + step), amount, "平多仓", contractType, price); - n++; - } else if (positions[i].Type == PD_SHORT) { - e.SetDirection("closesell"); - ID = e.Buy(price + F_SlidePrice * (1 + step), amount, "平空仓", contractType, price); - n++; - } - index = i; - } - if (n === 0) { - break; - } - Sleep(Interval); - if (typeof(ID) !== 'number') { - Log("ID:", ID); - continue; - } - - e.CancelOrder(ID); - step += lv; - if (step > max_cover_lv) { - break; - } - } - - var nowP = _C(e.GetPosition); - if (!nowP[index] || nowP[index].Type !== initP[index].Type) { - return initP.length === 0 ? 0 : initP[index].Amount; - } else { - var diff = initP[index].Amount - nowP[index].Amount; - return diff; - } -} - -var PositionManager = (function() { - function PositionManager(e) { - if (typeof(e) === 'undefined') { - e = exchange; - } - if (e.GetName() !== 'Futures_OKCoin' && e.GetName() !== 'Futures_BitVC') { - throw 'Only support Futures_OKCoin & Futures_BitVC'; - } - 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); - }; - - 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, OP_amount, direction) { - if (!this.account) { - this.account = _C(exchange.GetAccount); - } - return Cover(this.e, contractType, price, OP_amount, direction); - }; - - PositionManager.prototype.Profit = function(contractType) { - var accountNow = _C(this.e.GetAccount); - Log("NOW:", accountNow, "--account:", this.account); - return _N(accountNow.Balance - this.account.Balance); - }; - - return PositionManager; -})(); - -$.NewPositionManager = function(e) { - return new PositionManager(e); -}; - - -// 测试代码 -function main() { - if (exchange.GetName() === 'Futures_OKCoin') { - var info = exchange.SetContractType("this_week"); - Log("info 返回值:", info); - Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); - var depth = exchange.GetDepth(); - var p = $.NewPositionManager(); - p.OpenShort("this_week", 10, depth.Bids[0].Price - 2); - Log(exchange.GetPosition()); - Sleep(500 * 1000); - depth = exchange.GetDepth(); - var ret = p.Cover("this_week", depth.Bids[0].Price + 2, 5); - Log("cover ret:", ret); - //LogProfit(p.Profit()); - Log(exchange.GetPosition()); - Log("-----------------------------测试分割线----------------------------------------"); - var depth = exchange.GetDepth(); - p.OpenLong("this_week", 20, depth.Bids[0].Price + 2); - Log(exchange.GetPosition()); - Sleep(500 * 1000); - depth = exchange.GetDepth(); - var ret = p.Cover("this_week", depth.Bids[0].Price - 2, 10, PD_LONG); - Log("cover ret:", ret); - Log(exchange.GetPosition()); - Log("-----------------------------测试分割线----------------------------------------"); - var ret = p.Cover("this_week", depth.Bids[0].Price - 3, 10, PD_LONG); - Log("cover ret:", ret); - var ret = p.Cover("this_week", depth.Bids[0].Price + 3, 5, PD_SHORT); - Log("cover ret:", ret); - Log(exchange.GetPosition()); - } else if (exchange.GetName() === 'Futures_BitVC') { - var info = exchange.SetContractType("week"); - Log("info 返回值:", info); - Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); - var depth = exchange.GetDepth(); - var p = $.NewPositionManager(); - p.OpenLong("week", 500, depth.Bids[0].Price + 2); - Log(exchange.GetPosition()); - Sleep(500 * 1000); - depth = exchange.GetDepth(); - var ret = p.Cover("week", depth.Bids[0].Price - 2, 500); - Log("cover ret:", ret); - Log(exchange.GetPosition()); - Log("-----------------------------测试分割线----------------------------------------"); - var info = exchange.SetContractType("week"); - Log("info 返回值:", info); - Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); - var depth = exchange.GetDepth(); - p.OpenShort("week", 600, depth.Bids[0].Price - 2); - Log(exchange.GetPosition()); - Sleep(500 * 1000); - depth = exchange.GetDepth(); - var ret = p.Cover("week", depth.Bids[0].Price + 2, 500, PD_SHORT); - Log("cover ret:", ret); - Log(exchange.GetPosition()); - Log("-----------------------------测试分割线----------------------------------------"); - var ret = p.Cover("week", depth.Bids[0].Price + 3, 100, PD_SHORT); - Log("cover ret:", ret); - //p.Cover("week", depth.Asks[0].Price - 3, 300, PD_LONG); - Log(exchange.GetPosition()); - } else if(exchange.GetName() === 'huobi' || exchange.GetName() === 'OKCoin'){ - Log($.GetAccount()); - Log($.Buy(0.5)); - Log($.Sell(0.5)); - exchange.Buy(1000, 3); - $.CancelPendingOrders(exchanges[0]); - Log($.Cross(30, 7)); - Log($.Cross([1,2,3,2.8,3.5], [3,1.9,2,5,0.6])); - } -} - diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" index edf9d79f..4a7575f1 100644 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/57267 +策略出处: https://www.fmz.com/strategy/57267 策略名称: 数字货币交易类库 (期货支持OKCoin期货-BitVC, 支持$.CTA函数) 策略作者: 小小梦 策略描述: diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.py" "b/\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.py" index 7098101c..3a3388a6 100644 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.py" +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/54256 +策略出处: https://www.fmz.com/strategy/54256 策略名称: 数字货币定投 策略作者: ankye 策略描述: diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" index 572c121e..ddac8b71 100644 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/10989 +策略出处: https://www.fmz.com/strategy/10989 策略名称: 数字货币现货交易类库 策略作者: Zero 策略描述: diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.cpp" "b/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.cpp" deleted file mode 100644 index 259b6127..00000000 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223c++.cpp" +++ /dev/null @@ -1,317 +0,0 @@ -/* -策略出处: https://www.botvs.com/strategy/62140 -策略名称: 数字货币现货交易类库c++ -策略作者: 小小梦 -策略描述: - -使用了botvs最新支持的c++编写策略,如果使用有问题,欢迎在下面留言,我会经常来巡逻的! -如果托管者在2017年12月之后没有更新,请更新下托管者 - - -参数 默认值 描述 ----------- ------- ----------------------- -OpMode 0 下单方式: 吃单|挂单 -MaxSpace 0.5 挂单失效距离 -SlidePrice 0.1 下单滑动价(元) -MaxAmount 0.8 开仓最大单次下单量 -RetryDelay 500 失败重试(毫秒) -MAType 0 均线算法: EMA|MA|AMA(自适应均线) -MinStock 0.001 最小交易量 -*/ - -#include -#include -#include -#include - -using namespace std; -double min(double a, double b, double c){ - double d = a < b ? a : b; - return d < c ? d : c; -} - -struct withdraw_ret{ - json ret; - string withdraw_id; -}; - -withdraw_ret withdraw (Exchange &e, string ¤cy, string &address,string &amount, string &fee, string &password){ - string withdraw_id; - json ret; - transform(currency.begin(), currency.end(), currency.begin(),::tolower); - if(e.GetName() == "OKCoin_EN"){ - ret = e.IO("api", "POST", "/api/v1/withdraw.do", "symbol="+currency+"_usd&chargefee=" + fee + "&trade_pwd=" + password + "&withdraw_address=" + address + "&withdraw_amount=" + amount); - if (!ret.is_null() && !ret.is_boolean() && !(ret["withdraw_id"].is_null())) { - withdraw_id = ret["withdraw_id"]; - } else { - string err = GetLastError(); - if (!err.empty() && err.find("10031") != -1) { - Log("OKCoin_EN 需6个网络确认后方能提现"); - } - } - } else if(e.GetName() == "Huobi"){ - if (currency == "bch") { - currency = "bcc"; - } - ret = e.IO("api", "POST", "/v1/dw/withdraw-virtual/create", "currency="+currency+"&fee=" + fee + "&address=" + address + "&amount=" + amount); - if (!ret.is_null() && !ret.is_boolean() && !ret["withdraw_id"].is_null()) { - withdraw_id = ret["data"]; - } - } else if(e.GetName() == "Bithumb"){ - string cu; - transform(currency.begin(), currency.end(), cu.begin(),::toupper); - ret = e.IO("api", "POST", "/trade/btc_withdrawal", "currency="+cu+"&address=" + address + "&units=" + amount); - if (!ret.is_null() && !ret.is_boolean() && ret["status"].get() == "0") { - withdraw_id = "9999"; - } - } else if(e.GetName() == "GateIO"){ - ret = e.IO("api", "POST", "/api2/1/private/withdraw", "currency="+currency+"&address=" + address + "&amount=" + amount); - if (!ret.is_null() && !ret.is_boolean() && ret["code"].get() == "0") { - withdraw_id = "9999"; - } - } else if(e.GetName() == "ZB"){ - ret = e.IO("api", "POST", "/api/withdraw", "method=withdraw&itransfer=0¤cy="+currency+"&receiveAddr=" + address + "&amount=" + amount+"&fees="+fee+"&safePwd="+password); - if (!ret.is_null() && !ret.is_boolean() && ret["code"].get() == "0") { - withdraw_id = ret["id"]; - } - } else if(e.GetName() == "Bitfinex"){ - vector cMap = {"btc","ltc","eth","zec","etc","xmr","omni","usd","dash","xrp","eos"}; - vector cMap2 = {"bitcoin","litecoin","litecoin","ethereum","ethereumc","zcash","monero","mastercoin","wire","dash","ripple","eos"}; - int cMap_index = -1; - for(int i = 0;i() == "true") { - withdraw_id = ret["result"]["uuid"]; - } - } else if(e.GetName() == "Binance"){ - ret = e.IO("api", "POST", "/wapi/v1/withdraw.html", "amount=" + amount + "&asset=" + currency + "&address=" + address); - if (!ret.is_null() && !ret.is_boolean() && ret["success"].get() == "true") { - withdraw_id = "9999"; - } - } else if("OKEX"){ - ret = e.IO("api", "POST", "/api/v1/withdraw.do", "target=address&withdraw_amount=" + amount + "&symbol="+currency+"_usd&withdraw_address=" + address+"&chargefee="+fee+"&trade_pwd="+password); - if (!ret.is_null() && !ret.is_boolean() && ret["result"].get() == "true") { - withdraw_id = ret["withdraw_id"]; - } - } else{ - throw("不支持的操作"); - } - return {ret, withdraw_id}; -} - -void CancelPendingOrders(Exchange &e,size_t orderType){ - while(true){ - auto orders = e.GetOrders(); - if(orders.size() <= 0){ - Sleep(RetryDelay); - continue; - } - size_t processed = 0; - for(size_t j = 0;j < orders.size();j++){ - if(typeid(orderType) == typeid(size_t) && orders[j].Type != orderType){ - continue; - } - e.CancelOrder(orders[j].Id, orders[j]); - processed++; - if (j < (orders.size() - 1)) { - Sleep(RetryDelay); - } - } - if (processed == 0) { - break; - } - } -} - -Account GetAccount(Exchange &e, bool waitFrozen = false){ - Account account; - bool alreadyAlert = false; - while(true){ - account = _C(e.GetAccount); - if (!waitFrozen || (account.FrozenStocks < MinStock && account.FrozenBalance < 0.01)) { - break; - } - if (!alreadyAlert) { - alreadyAlert = true; - Log("发现账户有冻结的钱或币", account); - } - Sleep(RetryDelay); - } - return account; -} - -Order StripOrders(Exchange &e, TId &orderId){ - Order order; - while(true){ - size_t dropped = 0; - auto orders = _C(e.GetOrders); - for(size_t i = 0; i < orders.size(); i++){ - if (orders[i].Id.s == orderId.s) { - order = orders[i]; - } else{ - string extra; - if (orders[i].DealAmount > 0) { - extra = "成交: " + to_string(orders[i].DealAmount); - } else{ - extra = "未成交"; - } - e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); - dropped++; - } - } - if(dropped == 0){ - break; - } - Sleep(RetryDelay); - } - return order; -} - -MarketOrder Trade(Exchange &e,size_t tradeType,double tradeAmount,size_t mode,double slidePrice,double maxAmount,double maxSpace,size_t retryDelay) { - auto initAccount = GetAccount(e, true); - auto nowAccount = initAccount; - TId orderId; - double prePrice = 0; - double dealAmount = 0; - double diffMoney = 0; - bool isFirst = true; - //0为买,1为卖 - size_t tradeFunc = tradeType == ORDER_TYPE_BUY ? 0 : 1; - bool isBuy = tradeType == ORDER_TYPE_BUY; - while(true){ - auto ticker = _C(e.GetTicker); - double tradePrice = 0.0; - if(isBuy){ - tradePrice = _N((mode == 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4); - } else{ - tradePrice = _N((mode == 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4); - } - if(orderId.Valid){ - if (isFirst) { - isFirst = false; - } else { - nowAccount = GetAccount(e, true); - } - double doAmount = 0.0; - if (isBuy) { - diffMoney = _N(initAccount.Balance - nowAccount.Balance, 4); - dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 4); - doAmount = min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance - 10) / tradePrice, 4)); - } else{ - diffMoney = _N(nowAccount.Balance - initAccount.Balance, 4); - dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); - doAmount = min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); - } - if (doAmount < MinStock) { - break; - } - prePrice = tradePrice; - if(tradeFunc == 0){ - orderId = e.Buy(tradePrice, doAmount, ticker); - } else { - orderId = e.Sell(tradePrice, doAmount, ticker); - } - if (!orderId) { - CancelPendingOrders(e, tradeType); - } - } else{ - if (mode == 0 || (abs(tradePrice - prePrice) > maxSpace)) { - orderId.Valid = false; - } - auto order = StripOrders(e, orderId); - if (order.is_null()) { - orderId.Valid = false; - } - } - Sleep(retryDelay); - } - if (dealAmount <= 0) { - MarketOrder ret; - return ret; - } - return { _N(diffMoney / dealAmount, 4), dealAmount }; -} - -MarketOrder Buy(Exchange &e, double amount){ - return Trade(e, ORDER_TYPE_BUY, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); -} - -MarketOrder Buy(double e, double amount){ - amount = e; - return Trade(exchange, ORDER_TYPE_BUY, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); -} - -MarketOrder Sell(Exchange &e,double amount) { - return Trade(e, ORDER_TYPE_SELL, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); -} - -MarketOrder Sell(double e,double amount) { - amount = e; - return Trade(exchange, ORDER_TYPE_SELL, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); -} - -size_t Cross(size_t a, size_t b){ - size_t crossNum = 0; - vector arr1; - vector arr2; - Records records; - while (true) { - records = _C(exchange.GetRecords); - if (records.size() > a && records.size() > b) { - break; - } - Sleep(RetryDelay); - } - if(MAType == 0){ - arr1 = TA.EMA(records, a); - arr2 = TA.EMA(records, b); - } else if(MAType == 1){ - arr1 = TA.MA(records, a); - arr2 = TA.MA(records, b); - } else{ - arr1 = talib.KAMA(records, a); - arr2 = talib.KAMA(records, b); - } - if(sizeof(arr1) != sizeof(arr2)){ - Log("array length not equal"); - throw("array length not equal"); - } - crossNum = _Cross(arr1, arr2); - return crossNum; -} - -void main(){ - auto i = exchange.IO("api", "GET", "/v1/pubticker/btcusd", ""); - Log(i["bid"]); - -} diff --git "a/\346\226\260\346\211\213\345\205\245\351\227\250\344\271\213 - \344\270\213\344\271\260\345\215\225\345\215\226\345\215\225.js" "b/\346\226\260\346\211\213\345\205\245\351\227\250\344\271\213 - \344\270\213\344\271\260\345\215\225\345\215\226\345\215\225.js" index 4b3ab64a..65b9bf51 100644 --- "a/\346\226\260\346\211\213\345\205\245\351\227\250\344\271\213 - \344\270\213\344\271\260\345\215\225\345\215\226\345\215\225.js" +++ "b/\346\226\260\346\211\213\345\205\245\351\227\250\344\271\213 - \344\270\213\344\271\260\345\215\225\345\215\226\345\215\225.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/796 +策略出处: https://www.fmz.com/strategy/796 策略名称: 新手入门之 - 下买单卖单 策略作者: Zero 策略描述: diff --git "a/\346\250\241\346\235\277\345\272\223\344\275\277\347\224\250\344\276\213\345\255\220.js" "b/\346\250\241\346\235\277\345\272\223\344\275\277\347\224\250\344\276\213\345\255\220.js" index c2d55757..945508db 100644 --- "a/\346\250\241\346\235\277\345\272\223\344\275\277\347\224\250\344\276\213\345\255\220.js" +++ "b/\346\250\241\346\235\277\345\272\223\344\275\277\347\224\250\344\276\213\345\255\220.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/10991 +策略出处: https://www.fmz.com/strategy/10991 策略名称: 模板库使用例子 策略作者: Zero 策略描述: diff --git "a/\346\257\2171\345\210\206\351\222\237\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\345\267\256\344\273\267(by JackConan).js" "b/\346\257\2171\345\210\206\351\222\237\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\345\267\256\344\273\267(by JackConan).js" index d987c78a..f4de43f2 100644 --- "a/\346\257\2171\345\210\206\351\222\237\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\345\267\256\344\273\267(by JackConan).js" +++ "b/\346\257\2171\345\210\206\351\222\237\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\345\267\256\344\273\267(by JackConan).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/98 +策略出处: https://www.fmz.com/strategy/98 策略名称: 每1分钟统计各个平台间的差价(by JackConan) 策略作者: yzl_126@126.com 策略描述: diff --git "a/\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.js" "b/\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.js" index 75177771..8aa092ef 100644 --- "a/\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.js" +++ "b/\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/30573 +策略出处: https://www.fmz.com/strategy/30573 策略名称: 比特币现货阶梯差价对冲 策略作者: 我要发 策略描述: diff --git "a/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" "b/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" index 0a79d3ca..c916f4b2 100644 --- "a/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" +++ "b/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/40155 +策略出处: https://www.fmz.com/strategy/40155 策略名称: 测试 默认 参数组功能 策略作者: 小小梦 策略描述: diff --git "a/\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).js" "b/\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).js" index 9c0132f6..edcdc5cf 100644 --- "a/\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).js" +++ "b/\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/22838 +策略出处: https://www.fmz.com/strategy/22838 策略名称: 测试-CTP商品期货连接状态 (图表显示) 策略作者: 小小梦 策略描述: @@ -160,7 +160,7 @@ function main() { } chart.update(ChartCfg); - $.UpdateLogStatus("time:" + (new Date())); //更新 状态栏 图表内容 + $.UpDateLogStatus("time:" + (new Date())); //更新 状态栏 图表内容 lastState = state; //当前状态更新到上次状态 Sleep(1000 * 5); } diff --git "a/\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211.js" "b/\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211.js" index cc8d16d1..3c4a621d 100644 --- "a/\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211.js" +++ "b/\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/28128 +策略出处: https://www.fmz.com/strategy/28128 策略名称: 测试-布林带策略(基于策略框架) 策略作者: 小小梦 策略描述: @@ -191,8 +191,10 @@ function Loop(){//循环主体 var boll = TA.BOLL(records, 20, 2); // 调用布林指标 var up = boll[0]; var down = boll[2]; + var mid = boll[1] $.AddZhiBiao(up, records, 1); $.AddZhiBiao(down, records, 2); + $.AddZhiBiao(mid, records, 3); /* 求一个简单的策略,哪位大神出手帮助一下 okcoin现货btc,1小时布林线,价格上穿布林线下轨买入,价格上穿布林线上轨卖出 diff --git "a/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.js" "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.js" index 4e489a7d..023d89b4 100644 --- "a/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.js" +++ "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/38203 +策略出处: https://www.fmz.com/strategy/38203 策略名称: 测试多图表展示 策略作者: Zero 策略描述: diff --git "a/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.py" "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.py" index cf92c660..0edf2f8b 100644 --- "a/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.py" +++ "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/84042 +策略出处: https://www.fmz.com/strategy/84042 策略名称: 测试多图表展示Python版 策略作者: 小小梦 策略描述: diff --git "a/\347\224\273\347\272\277\347\261\273\345\272\223.js" "b/\347\224\273\347\272\277\347\261\273\345\272\223.js" index 8ffd49a4..f399d1d6 100644 --- "a/\347\224\273\347\272\277\347\261\273\345\272\223.js" +++ "b/\347\224\273\347\272\277\347\261\273\345\272\223.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/27293 +策略出处: https://www.fmz.com/strategy/27293 策略名称: 画线类库 策略作者: Zero 策略描述: diff --git "a/\347\233\221\350\247\206\345\271\266\346\230\276\347\244\272\345\244\232\344\270\252\345\271\263\345\217\260\347\232\204\345\205\250\351\203\250\350\265\204\344\272\247\346\200\273\345\222\214\347\232\204\345\217\230\345\214\226.js" "b/\347\233\221\350\247\206\345\271\266\346\230\276\347\244\272\345\244\232\344\270\252\345\271\263\345\217\260\347\232\204\345\205\250\351\203\250\350\265\204\344\272\247\346\200\273\345\222\214\347\232\204\345\217\230\345\214\226.js" index 5fbba4e4..ea465fe2 100644 --- "a/\347\233\221\350\247\206\345\271\266\346\230\276\347\244\272\345\244\232\344\270\252\345\271\263\345\217\260\347\232\204\345\205\250\351\203\250\350\265\204\344\272\247\346\200\273\345\222\214\347\232\204\345\217\230\345\214\226.js" +++ "b/\347\233\221\350\247\206\345\271\266\346\230\276\347\244\272\345\244\232\344\270\252\345\271\263\345\217\260\347\232\204\345\205\250\351\203\250\350\265\204\344\272\247\346\200\273\345\222\214\347\232\204\345\217\230\345\214\226.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/443 +策略出处: https://www.fmz.com/strategy/443 策略名称: 监视并显示多个平台的全部资产总和的变化 策略作者: Zero 策略描述: diff --git "a/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.js" "b/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.js" index 6537d40f..d63cbe0c 100644 --- "a/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.js" +++ "b/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/40266 +策略出处: https://www.fmz.com/strategy/40266 策略名称: 知乎专栏 实例文章策略 策略作者: yilidalei 策略描述: diff --git "a/\347\237\255\344\277\241\351\200\232\347\237\245\346\216\245\345\217\243\346\265\213\350\257\225.js" "b/\347\237\255\344\277\241\351\200\232\347\237\245\346\216\245\345\217\243\346\265\213\350\257\225.js" index efa18b1d..00c59c5d 100644 --- "a/\347\237\255\344\277\241\351\200\232\347\237\245\346\216\245\345\217\243\346\265\213\350\257\225.js" +++ "b/\347\237\255\344\277\241\351\200\232\347\237\245\346\216\245\345\217\243\346\265\213\350\257\225.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/653 +策略出处: https://www.fmz.com/strategy/653 策略名称: 短信通知接口测试 策略作者: Zero 策略描述: diff --git "a/\347\237\255\344\277\241\351\200\232\347\237\245\347\261\273\345\272\223.js" "b/\347\237\255\344\277\241\351\200\232\347\237\245\347\261\273\345\272\223.js" index 726fbb34..76c5d0c9 100644 --- "a/\347\237\255\344\277\241\351\200\232\347\237\245\347\261\273\345\272\223.js" +++ "b/\347\237\255\344\277\241\351\200\232\347\237\245\347\261\273\345\272\223.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/26921 +策略出处: https://www.fmz.com/strategy/26921 策略名称: 短信通知类库 策略作者: Zero 策略描述: diff --git "a/\347\240\264\345\206\260\350\200\205.js" "b/\347\240\264\345\206\260\350\200\205.js" index 12f8b9d9..df39e7f4 100644 --- "a/\347\240\264\345\206\260\350\200\205.js" +++ "b/\347\240\264\345\206\260\350\200\205.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/9929 +策略出处: https://www.fmz.com/strategy/9929 策略名称: 破冰者 策略作者: Zero 策略描述: @@ -28,6 +28,7 @@ RestoreAmount false 持仓数量 RestoreProfit false 上次盈利 SaveLocal false 保存本地日志 StopLoss 8 止损(元) +MinStock 0.01 最小交易币数 */ var TradeType = null; @@ -112,7 +113,7 @@ function GetAccount(e, waitFrozen) { var alreadyAlert = false; while (true) { account = EnsureCall(e, "GetAccount"); - if (!waitFrozen || (account.FrozenStocks < e.GetMinStock() && account.FrozenBalance < 0.01)) { + if (!waitFrozen || (account.FrozenStocks < MinStock && account.FrozenBalance < 0.01)) { break; } if (!alreadyAlert) { @@ -174,7 +175,7 @@ function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); } - if (doAmount < e.GetMinStock()) { + if (doAmount < MinStock) { break; } prePrice = tradePrice; @@ -199,7 +200,7 @@ function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, } function loop(isFirst) { - var minStock = exchange.GetMinStock(); + var minStock = MinStock; var initAccount = GetAccount(exchange, true); Log(initAccount); var holdPrice = 0; diff --git "a/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.js" "b/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.js" index 07fe567b..e2c9f53e 100644 --- "a/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.js" +++ "b/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/34388 +策略出处: https://www.fmz.com/strategy/34388 策略名称: 移植 OKCoin 韭菜收割机 策略作者: Zero 策略描述: diff --git "a/\347\252\234\345\244\251\347\214\264 - \347\247\273\345\212\250\346\255\242\346\215\237\347\211\210.js" "b/\347\252\234\345\244\251\347\214\264 - \347\247\273\345\212\250\346\255\242\346\215\237\347\211\210.js" index da76ac80..416675d2 100644 --- "a/\347\252\234\345\244\251\347\214\264 - \347\247\273\345\212\250\346\255\242\346\215\237\347\211\210.js" +++ "b/\347\252\234\345\244\251\347\214\264 - \347\247\273\345\212\250\346\255\242\346\215\237\347\211\210.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/13594 +策略出处: https://www.fmz.com/strategy/13594 策略名称: 窜天猴 - 移动止损版 策略作者: Zero 策略描述: diff --git "a/\347\252\234\345\244\251\347\214\264 \345\244\232\347\251\272\350\276\203\351\207\217 \347\210\206\347\240\264\347\211\210.js" "b/\347\252\234\345\244\251\347\214\264 \345\244\232\347\251\272\350\276\203\351\207\217 \347\210\206\347\240\264\347\211\210.js" index bd346233..5008303a 100644 --- "a/\347\252\234\345\244\251\347\214\264 \345\244\232\347\251\272\350\276\203\351\207\217 \347\210\206\347\240\264\347\211\210.js" +++ "b/\347\252\234\345\244\251\347\214\264 \345\244\232\347\251\272\350\276\203\351\207\217 \347\210\206\347\240\264\347\211\210.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/13597 +策略出处: https://www.fmz.com/strategy/13597 策略名称: 窜天猴 多空较量 爆破版 策略作者: Zero 策略描述: diff --git "a/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" "b/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" index 24fba127..92bf191b 100644 --- "a/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" +++ "b/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/30861 +策略出处: https://www.fmz.com/strategy/30861 策略名称: 策略框架模板 策略作者: 小小梦 策略描述: @@ -20,14 +20,15 @@ var TASK_COVER = 5; https://www.botvs.com/bbs-topic/634 -参数 默认值 描述 ----------- ----- ----------- -OpMode 0 下单方式: 吃单|挂单 -MaxSpace 0.5 挂单失效距离 -SlidePrice 0.1 下单滑动价(元) -MaxAmount 0.8 开仓最大单次下单量 -RetryDelay 500 失败重试(毫秒) -Interval 500 轮询间隔 +参数 默认值 描述 +---------- ------ ----------- +OpMode 0 下单方式: 吃单|挂单 +MaxSpace 0.5 挂单失效距离 +SlidePrice 0.1 下单滑动价(元) +MaxAmount 0.8 开仓最大单次下单量 +RetryDelay 500 失败重试(毫秒) +Interval 500 轮询间隔 +_minStock 0.01 最小交易币数 */ // 模板全局变量 @@ -80,7 +81,7 @@ function GetAccount(e, waitFrozen) { var alreadyAlert = false; while (true) { account = _C(e.GetAccount); - if (!waitFrozen || (account.FrozenStocks < e.GetMinStock() && account.FrozenBalance < 0.01)) { + if (!waitFrozen || (account.FrozenStocks < _minStock && account.FrozenBalance < 0.01)) { break; } if (!alreadyAlert) { @@ -156,7 +157,7 @@ function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); } - if (doAmount < e.GetMinStock()) { + if (doAmount < _minStock) { break; } prePrice = tradePrice; @@ -211,7 +212,7 @@ function TasksInit(tasks){ task.AddAmount = 0; task.StopLossAmount = 0; task.STATE = IDLE; - task.minStock = _C(task.Exchange.GetMinStock); + task.minStock = _minStock; // _C(task.Exchange.GetMinStock); 修改 , 废弃了 GetMinStock 函数 task.initAccount = _C(task.Exchange.GetAccount); task.Currency = _C(task.Exchange.GetCurrency); task.Name = _C(task.Exchange.GetName); diff --git "a/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.js" "b/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.js" index 556be227..f01e9ab2 100644 --- "a/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.js" +++ "b/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/57029 +策略出处: https://www.fmz.com/strategy/57029 策略名称: 简单多品种商品期货均线策略 策略作者: Zero 策略描述: diff --git "a/\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.js" "b/\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.js" index 7ebdfcbc..0b786b7c 100644 --- "a/\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.js" +++ "b/\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/1125 +策略出处: https://www.fmz.com/strategy/1125 策略名称: 统计K线回测是否存在趋势 策略作者: botvsing 策略描述: diff --git "a/\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\344\273\267(by JackConan).js" "b/\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\344\273\267(by JackConan).js" index 0ff8fbe3..a6f00294 100644 --- "a/\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\344\273\267(by JackConan).js" +++ "b/\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\344\273\267(by JackConan).js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/86 +策略出处: https://www.fmz.com/strategy/86 策略名称: 统计各个平台间的最大差价(by JackConan) 策略作者: yzl_126@126.com 策略描述: diff --git "a/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).js" "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).js" new file mode 100644 index 00000000..299f4634 --- /dev/null +++ "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).js" @@ -0,0 +1,476 @@ +/* +策略出处: https://www.fmz.com/strategy/8474 +策略名称: 网格变形策略之单边网格 (OK期货) +策略作者: Zero +策略描述: + +网格可以自定义方向 +先买后卖: +网格会从首价格开始向下挂买单, 每个买单间隔 "价格间隔" 这个参数, 挂单数量为"单笔数量", 挂够 "总数量" 个买单, 有任意买单成交以后, 程序会在买价基础上加 "价差(元)" 这个参数的的值的价格挂出卖单, 卖出, 卖出以后,重新按原来这个网格的价格挂买入单 +先卖后买: +操作刚好相反 + +策略最大的风险就是单边行情, 价格波动超出网格范围. + +网格带有自动止损和移动功能 + + +参数 默认值 描述 +----------------- ----- ------------------ +ContractTypeIdx 0 合约品种: 当周|次周|季度 +OpType 0 网格方向: 先买后卖|先卖后买 +FirstPriceAuto false 首价格自动 +FirstPrice 100 首价格 +AllNum 10 总数量 +PriceGrid true 价格间隔 +PriceDiff 2 价差(元) +AmountType 0 订单大小: 买卖同量|自定义量 +AmountOnce true 单笔数量 +BAmountOnce true 买单大小 +SAmountOnce true 卖单大小 +MarginLevelIdx 0 杠杆大小: 10|20 +EnableProtectDiff false 开启价差保护 +ProtectDiff 20 入市价差保护 +CancelAllWS true 停止时取消取有挂单 +CheckInterval 2000 轮询间隔 +Interval 1300 失败重试间隔 +RestoreProfit false 恢复上次盈利 +LastProfit false 上次盈利 +ProfitAsOrg false 上次盈利算入均价 +EnableStopLoss false 开启止损 +StopLoss 0.1 最大浮动亏损 +StopLossMode 0 止损后操作: 回收并退出|回收再撒网 +AutoMove false 自动移动 +MaxDistance 20 最大距离(元) +MaxIdle 7200 最大空闲(秒) + +按钮 默认值 描述 +---- ---------- ---------- +收网 __button__ 停止并平衡到初始状态 +*/ + +var isFuture = false; + +function hasOrder(orders, orderId) { + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == orderId) { + return true; + } + } + return false; +} + + +function cancelPending() { + var ret = false; + while (true) { + if (ret) { + Sleep(Interval); + } + var orders = _C(exchange.GetOrders); + if (orders.length == 0) { + break; + } + + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]); + ret = true; + } + } + return ret; +} + + +function balanceAccount(orgAccount, initAccount) { + if (isFuture) { + while (true) { + cancelPending(); + var positions = _C(exchange.GetPosition); + if (positions.length === 0 ) { + var accountNow = _C(exchange.GetAccount); + LogProfit(_N(accountNow.Stocks - orgAccount.Stocks), "可用保证金:", accountNow.Stocks); + return; + } + for (var i = 0; i < positions.length; i++) { + if (positions[i].Type == PD_LONG) { + exchange.SetDirection("closebuy"); + exchange.Sell(positions[i].Amount); + } else { + exchange.SetDirection("closesell"); + exchange.Buy(positions[i].Amount); + } + } + Sleep(Interval); + } + } + var account = _C(exchange.GetAccount); + while (true) { + var diff = _N(account.Stocks - initAccount.Stocks); + if (Math.abs(diff) < exchange.GetMinStock()) { + break; + } + var depth = _C(exchange.GetDepth); + var books = diff > 0 ? depth.Bids : depth.Asks; + var n = 0; + var price = 0; + for (var i = 0; i < books.length; i++) { + n += books[i].Amount; + if (n >= Math.abs(diff)) { + price = books[i].Price; + break; + } + } + Log("开始平衡", (diff > 0 ? "卖出" : "买入"), Math.abs(diff), "个币"); + if (diff > 0) { + exchange.Sell(price - 0.2, diff); + } else { + exchange.Buy(price + 0.2, -diff); + } + Sleep(1000); + cancelPending(); + account = _C(exchange.GetAccount); + } + Log("平衡完成", account); +} + +var STATE_WAIT_OPEN = 0; +var STATE_WAIT_COVER = 1; +var STATE_WAIT_CLOSE = 2; +var ProfitCount = 0; +var BuyFirst = (OpType == 0); +var IsSupportGetOrder = true; +var LastBusy = 0; +var LastFloatProfit = 0; + +function setBusy() { + LastBusy = new Date(); +} + +function isTimeout() { + if (MaxIdle <= 0) { + return false; + } + var now = new Date(); + if (((now.getTime() - LastBusy.getTime()) / 1000) >= MaxIdle) { + LastBusy = now; + return true; + } + return false; +} + +function onexit() { + if (CancelAllWS) { + Log("正在退出, 尝试取消所有挂单"); + cancelPending(); + } + Log("策略成功停止"); + Log(_C(exchange.GetAccount)); +} + + +function fishing(orgAccount, fishCount) { + setBusy(); + var account = _C(exchange.GetAccount); + Log(account); + var InitAccount = account; + var ticker = _C(exchange.GetTicker); + var amount = _N(AmountOnce); + var amountB = amount; + var amountS = amount; + if (typeof(AmountType) !== 'undefined' && AmountType == 1) { + amountB = BAmountOnce; + amountS = SAmountOnce; + } + if (FirstPriceAuto) { + FirstPrice = BuyFirst ? _N(ticker.Buy - PriceGrid) : _N(ticker.Sell + PriceGrid); + } + // Initialize fish table + var fishTable = {}; + var uuidTable = {}; + var needStocks = 0; + var needMoney = 0; + var actualNeedMoney = 0; + var actualNeedStocks = 0; + var notEnough = false; + var canNum = 0; + var marginLevel = [10,20][MarginLevelIdx]; + exchange.SetMarginLevel(marginLevel); + for (var idx = 0; idx < AllNum; idx++) { + var price = _N(BuyFirst ? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)); + if (isFuture) { + needStocks += ((100 * amountB) / price) / marginLevel; + if (_N(needStocks) <= _N(account.Stocks)) { + actualNeedStocks = needStocks; + canNum++; + } else { + notEnough = true; + } + } else { + needStocks += amountS; + needMoney += price * amountB; + if (BuyFirst) { + if (_N(needMoney) <= _N(account.Balance)) { + actualNeedMondy = needMoney; + actualNeedStocks = needStocks; + canNum++; + } else { + notEnough = true; + } + } else { + if (_N(needStocks) <= _N(account.Stocks)) { + actualNeedMondy = needMoney; + actualNeedStocks = needStocks; + canNum++; + } else { + notEnough = true; + } + } + } + fishTable[idx] = STATE_WAIT_OPEN; + uuidTable[idx] = -1; + } + if (EnableProtectDiff) { + if (BuyFirst && (FirstPrice - ticker.Sell) > ProtectDiff) { + throw "首次买入价比市场卖1价高" + _N(FirstPrice - ticker.Sell) + ' 元'; + } else if (!BuyFirst && (ticker.Buy - FirstPrice) > ProtectDiff) { + throw "首次卖出价比市场买1价高 " + _N(ticker.Buy - FirstPrice) + ' 元'; + } + } + if (BuyFirst && !isFuture) { + if (account.Balance < _N(needMoney)) { + if (fishCount == 1) { + throw "资金不足, 需要"+ _N(needMoney) + "元"; + } else { + Log("资金不足, 需要", _N(needMoney), "元, 程序只做", canNum, "个网格 #ff0000"); + } + } else { + Log('预计动用资金: ', _N(needMoney), "元"); + } + } else { + if (account.Stocks < _N(needStocks)) { + if (fishCount == 1) { + throw "币数不足, 需要 "+ _N(needStocks) + " 个币"; + } else { + Log("资金不足, 需要", _N(needStocks), "个币, 程序只做", canNum, "个网格 #ff0000"); + } + } else { + Log('预计动用币数: ', _N(needStocks), "个"); + } + } + + var OpenFunc = BuyFirst ? exchange.Buy : exchange.Sell; + var CoverFunc = BuyFirst ? exchange.Sell : exchange.Buy; + var ts = new Date(); + var preMsg = ""; + var profitMax = 0; + while (true) { + var now = new Date(); + if (now.getTime() - ts.getTime() > 5000) { + if (typeof(GetCommand) == 'function' && GetCommand() == "收网") { + Log("开始执行命令进行收网操作"); + balanceAccount(orgAccount, InitAccount); + return false; + } + ts = now; + var msg = ""; + var positions, isHold; + var ticker = _C(exchange.GetTicker); + var nowAccount = _C(exchange.GetAccount); + if (isFuture) { + positions = _C(exchange.GetPosition); + isHold = positions.length > 0; + if (isHold) { + msg += "持仓: " + positions[0].Amount + " 持仓均价: " + _N(positions[0].Price) + " 浮动盈亏: " + _N(positions[0].Profit); + if (EnableStopLoss && -positions[0].Profit >= StopLoss) { + Log("当前浮动盈亏", positions[0].Profit, "开始止损"); + balanceAccount(orgAccount, InitAccount); + if (StopLossMode === 0) { + throw "止损退出"; + } else { + return true; + } + } + } else { + msg += "空仓"; + } + msg += " 可用保证金: " + nowAccount.Stocks; + + } else { + isHold = Math.abs(amount_diff) >= exchange.GetMinStock(); + + var amount_diff = (nowAccount.Stocks + nowAccount.FrozenStocks) - (InitAccount.Stocks + InitAccount.FrozenStocks); + var money_diff = (nowAccount.Balance + nowAccount.FrozenBalance) - (InitAccount.Balance + InitAccount.FrozenBalance); + var floatProfit = _N(money_diff + (amount_diff * ticker.Last)); + var floatProfitAll = _N((nowAccount.Balance + nowAccount.FrozenBalance - orgAccount.Balance - orgAccount.FrozenBalance) + ((nowAccount.Stocks + nowAccount.FrozenStocks - orgAccount.Stocks - orgAccount.FrozenStocks) * ticker.Last)); + LastFloatProfit = floatProfitAll; + profitMax = Math.max(floatProfit, profitMax); + if (EnableStopLoss) { + if ((profitMax - floatProfit) >= StopLoss) { + Log("当前浮动盈亏", floatProfit, "利润最高点: ", profitMax, "开始止损"); + balanceAccount(orgAccount, InitAccount); + if (StopLossMode === 0) { + throw "止损退出"; + } else { + return true; + } + } + } + if (isHold) { + if (RestoreProfit && ProfitAsOrg) { + if (BuyFirst) { + money_diff += LastProfit; + } else { + money_diff -= LastProfit; + } + } + var hold_amount = amount_diff; + var hold_price = (-money_diff) / amount_diff; + if (!BuyFirst) { + hold_amount = -amount_diff; + hold_price = (money_diff) / -amount_diff; + } + msg = (BuyFirst ? "做多: " : "做空: ") + _N(hold_amount, 4) + " 个币, 均价: " + _N(hold_price); + } else { + msg += "空仓"; + } + msg += " 当前网格浮动盈亏: " + floatProfit + " 总浮动盈亏: " + floatProfitAll + " 第 " + fishCount + " 次撒网 最新币价: " + _N(ticker.Last); + } + if (isHold) { + setBusy(); + } + + var distance = 0; + if (AutoMove) { + if (BuyFirst) { + distance = ticker.Last - FirstPrice; + } else { + distance = FirstPrice - ticker.Last; + } + var refish = false; + if (!isHold && isTimeout()) { + Log("空仓过久, 开始移动网格"); + refish = true; + } + if (distance > MaxDistance) { + Log("价格超出网格区间过多, 开始移动网格, 当前距离: ", _N(distance), "当前价格:", ticker.Last); + refish = true; + } + if (refish) { + balanceAccount(orgAccount, InitAccount); + return true; + } + } + + if (AutoMove && distance > 0) { + msg += " (离网格" + (BuyFirst ? "向上" : "向下") + "偏离: " + _N(distance) + " 元)"; + } + if (msg != preMsg) { + LogStatus(msg); + preMsg = msg; + } + + } + var orders = _C(exchange.GetOrders); + for (var idx = 0; idx < canNum; idx++) { + var openPrice = _N(BuyFirst ? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)); + var coverPrice = _N(BuyFirst ? openPrice + PriceDiff : openPrice - PriceDiff); + var state = fishTable[idx]; + var fishId = uuidTable[idx]; + if (hasOrder(orders, fishId)) { + continue; + } + + if (fishId != -1 && IsSupportGetOrder) { + var order = exchange.GetOrder(fishId); + if (!order) { + Log("获取订单信息失败, ID: ", fishId); + continue; + } + if (order.Status == ORDER_STATE_PENDING) { + Log("订单状态为未完成, ID: ", fishId); + continue; + } + } + + if (state == STATE_WAIT_COVER) { + if (isFuture) { + exchange.SetDirection(BuyFirst ? "closebuy" : "closesell"); + } + var coverId = CoverFunc(coverPrice, BuyFirst ? amountS : amountB, BuyFirst ? '完成买单:' : '完成卖单:', openPrice); + if (coverId > 0) { + fishTable[idx] = STATE_WAIT_CLOSE; + uuidTable[idx] = coverId; + } + } else if (state == STATE_WAIT_OPEN || state == STATE_WAIT_CLOSE) { + if (isFuture) { + exchange.SetDirection(BuyFirst ? "buy" : "sell"); + } + var openId = OpenFunc(openPrice, BuyFirst ? amountB : amountS); + if (openId > 0) { + fishTable[idx] = STATE_WAIT_COVER; + uuidTable[idx] = openId; + if (state == STATE_WAIT_CLOSE) { + ProfitCount++; + if (AmountType === 0) { + Log((BuyFirst ? '完成卖单: ' : '完成买单: ') + coverPrice); + } else { + Log((BuyFirst ? '完成卖单: ' : '完成买单: ') + coverPrice); + } + if (!isFuture) { + var account = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + var initNet = _N(((InitAccount.Stocks + InitAccount.FrozenStocks) * ticker.Buy) + InitAccount.Balance + InitAccount.FrozenBalance, 8); + var nowNet = _N(((account.Stocks + account.FrozenStocks) * ticker.Buy) + account.Balance + account.FrozenBalance, 8); + var actualProfit = _N(((nowNet - initNet)) * 100 / initNet, 8); + LogProfit(LastFloatProfit, "总浮动盈亏率:", _N(LastFloatProfit * 100 / actualNeedMondy, 4), '%'); + } + } + } + } + } + Sleep(CheckInterval); + } + return true; +} + +function main() { + if (typeof(AmountType) === 'undefined') { + AmountType = 0; + } + IsSupportGetOrder = exchange.GetName().indexOf('itstamp') == -1; + if (!IsSupportGetOrder) { + Log(exchange.GetName(), "不支持GetOrder, 可能影响策略稳定性."); + } + + isFuture = exchange.GetName().indexOf("Future") != -1; + if (AmountType === 0) { + BAmountOnce = AmountOnce; + SAmountOnce = AmountOnce; + } + if (exchange.GetName() == "Futures_OKCoin" && (AmountOnce.toString().indexOf(".") != -1 || BAmountOnce.toString().indexOf(".") != -1 || SAmountOnce.toString().indexOf(".") != -1)) { + throw "OKCoin期货下单数必须为整数"; + } + + SetErrorFilter("502:|503:|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|refused|EOF|When"); + + exchange.SetRate(1); + Log('已经禁用汇率转换, 当前货币为', exchange.GetBaseCurrency()); + + if (!RestoreProfit) { + LastProfit = 0; + } + exchange.SetContractType(["this_week", "next_week", "quarter"][ContractTypeIdx]); + var orgAccount = _C(exchange.GetAccount); + var fishCount = 1; + while (true) { + if (!fishing(orgAccount, fishCount)) { + break; + } + fishCount++; + Log("第", fishCount, "次重新撒网..."); + FirstPriceAuto = true; + Sleep(1000); + } +} + + diff --git "a/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" index bc0e18c5..c80ae495 100644 --- "a/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" +++ "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/629 +策略出处: https://www.fmz.com/strategy/629 策略名称: 网格变形策略之单边网格 策略作者: Zero 策略描述: diff --git "a/\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.js" "b/\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.js" index b2f9cdf6..3450b1c5 100644 --- "a/\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.js" +++ "b/\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/67495 +策略出处: https://www.fmz.com/strategy/67495 策略名称: 网格(波段)香农版 策略作者: 小码哥 策略描述: diff --git "a/\350\202\241\347\245\250\350\257\201\345\210\270\346\237\245\350\257\242\344\271\260\345\215\226\347\244\272\344\276\213.js" "b/\350\202\241\347\245\250\350\257\201\345\210\270\346\237\245\350\257\242\344\271\260\345\215\226\347\244\272\344\276\213.js" index ec28908e..a4c9a977 100644 --- "a/\350\202\241\347\245\250\350\257\201\345\210\270\346\237\245\350\257\242\344\271\260\345\215\226\347\244\272\344\276\213.js" +++ "b/\350\202\241\347\245\250\350\257\201\345\210\270\346\237\245\350\257\242\344\271\260\345\215\226\347\244\272\344\276\213.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/5541 +策略出处: https://www.fmz.com/strategy/5541 策略名称: 股票证券查询买卖示例 策略作者: Zero 策略描述: diff --git "a/\350\214\203\344\276\213-\345\256\232\346\227\266\346\265\213\350\257\225\345\276\256\344\277\241\346\266\210\346\201\257\346\216\250\351\200\201.js" "b/\350\214\203\344\276\213-\345\256\232\346\227\266\346\265\213\350\257\225\345\276\256\344\277\241\346\266\210\346\201\257\346\216\250\351\200\201.js" index a46b8819..a2f06de0 100644 --- "a/\350\214\203\344\276\213-\345\256\232\346\227\266\346\265\213\350\257\225\345\276\256\344\277\241\346\266\210\346\201\257\346\216\250\351\200\201.js" +++ "b/\350\214\203\344\276\213-\345\256\232\346\227\266\346\265\213\350\257\225\345\276\256\344\277\241\346\266\210\346\201\257\346\216\250\351\200\201.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/15098 +策略出处: https://www.fmz.com/strategy/15098 策略名称: 范例-定时测试微信消息推送 策略作者: 小小梦 策略描述: diff --git "a/\350\216\267\345\217\226OK\346\234\237\350\264\247\345\256\236\346\227\266\351\231\220\344\273\267.js" "b/\350\216\267\345\217\226OK\346\234\237\350\264\247\345\256\236\346\227\266\351\231\220\344\273\267.js" index 846c2ebb..98e9f5b0 100644 --- "a/\350\216\267\345\217\226OK\346\234\237\350\264\247\345\256\236\346\227\266\351\231\220\344\273\267.js" +++ "b/\350\216\267\345\217\226OK\346\234\237\350\264\247\345\256\236\346\227\266\351\231\220\344\273\267.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/17028 +策略出处: https://www.fmz.com/strategy/17028 策略名称: 获取OK期货实时限价 策略作者: 数·狂 策略描述: diff --git "a/\350\216\267\345\217\226\345\221\250K\347\272\277.js" "b/\350\216\267\345\217\226\345\221\250K\347\272\277.js" index e3e779bc..9ae91b16 100644 --- "a/\350\216\267\345\217\226\345\221\250K\347\272\277.js" +++ "b/\350\216\267\345\217\226\345\221\250K\347\272\277.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/20226 +策略出处: https://www.fmz.com/strategy/20226 策略名称: 获取周K线 策略作者: 数·狂 策略描述: diff --git "a/\350\216\267\345\217\226\345\222\214\350\256\257\346\234\237\350\264\247\346\225\260\346\215\256\357\274\210Python\347\211\210\346\234\254\357\274\211.py" "b/\350\216\267\345\217\226\345\222\214\350\256\257\346\234\237\350\264\247\346\225\260\346\215\256\357\274\210Python\347\211\210\346\234\254\357\274\211.py" index 9ed6add4..135c7303 100644 --- "a/\350\216\267\345\217\226\345\222\214\350\256\257\346\234\237\350\264\247\346\225\260\346\215\256\357\274\210Python\347\211\210\346\234\254\357\274\211.py" +++ "b/\350\216\267\345\217\226\345\222\214\350\256\257\346\234\237\350\264\247\346\225\260\346\215\256\357\274\210Python\347\211\210\346\234\254\357\274\211.py" @@ -1,5 +1,5 @@ ''' -策略出处: https://www.botvs.com/strategy/26017 +策略出处: https://www.fmz.com/strategy/26017 策略名称: 获取和讯期货数据(Python版本) 策略作者: edwardgyw 策略描述: diff --git "a/\350\236\215\350\265\204\350\236\215\345\270\201\347\273\237\350\256\241.js" "b/\350\236\215\350\265\204\350\236\215\345\270\201\347\273\237\350\256\241.js" index d8df7b73..5e0d267c 100644 --- "a/\350\236\215\350\265\204\350\236\215\345\270\201\347\273\237\350\256\241.js" +++ "b/\350\236\215\350\265\204\350\236\215\345\270\201\347\273\237\350\256\241.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/8954 +策略出处: https://www.fmz.com/strategy/8954 策略名称: 融资融币统计 策略作者: 数·狂 策略描述: diff --git "a/\350\256\241\345\210\222\345\247\224\346\211\230\344\271\260\345\205\245.js" "b/\350\256\241\345\210\222\345\247\224\346\211\230\344\271\260\345\205\245.js" index 64077aad..b930ccbf 100644 --- "a/\350\256\241\345\210\222\345\247\224\346\211\230\344\271\260\345\205\245.js" +++ "b/\350\256\241\345\210\222\345\247\224\346\211\230\344\271\260\345\205\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/638 +策略出处: https://www.fmz.com/strategy/638 策略名称: 计划委托买入 策略作者: Zero 策略描述: @@ -7,14 +7,15 @@ 计划委托买入, 在价格涨超或者跌破指定的价格后进行买入操作, 如果使用市价单,只写购买金额就可以了,如果限价单,需要指定限价单的价格和个数 -参数 默认值 描述 ---------------- ----- ------------- -OpType 0 下单类型: 市价单|限价单 -TriggerPrice 2600 触发价格 -MarketUsedMoney 10000 市价单 - 购买金额 -BuyPrice 2610 限价单 - 买入价格 -BuyAmount 3 限价单 - 买入数量 -LoopInterval 200 检测间隔(豪秒) +参数 默认值 描述 +--------------- -------- ------------- +OpType 0 下单类型: 市价单|限价单 +TriggerPrice 2600 触发价格 +MarketUsedMoney 10000 市价单 - 购买金额 +BuyPrice 2610 限价单 - 买入价格 +BuyAmount 3 限价单 - 买入数量 +LoopInterval 200 检测间隔(豪秒) +MinStock 0.01 最小交易币数 */ @@ -98,7 +99,7 @@ function cancelPending() { function ensureBuy() { var account = GetAccount(); var initAccount = account; - var minStock = exchange.GetMinStock(); + var minStock = MinStock; var isfirst = true; var c = 0; while (true) { diff --git "a/\350\256\241\345\210\222\345\247\224\346\211\230\345\215\226\345\207\272.js" "b/\350\256\241\345\210\222\345\247\224\346\211\230\345\215\226\345\207\272.js" index de740fa7..b0e6b9a3 100644 --- "a/\350\256\241\345\210\222\345\247\224\346\211\230\345\215\226\345\207\272.js" +++ "b/\350\256\241\345\210\222\345\247\224\346\211\230\345\215\226\345\207\272.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/747 +策略出处: https://www.fmz.com/strategy/747 策略名称: 计划委托卖出 策略作者: Zero 策略描述: @@ -14,6 +14,7 @@ TriggerPrice 2600 触发价格 SellPrice 2610 限价单 - 卖出价格 SellAmount 3 卖出数量 LoopInterval true 检测间隔(秒) +MinStock 0.01 最小交易币数 */ @@ -97,7 +98,7 @@ function cancelPending() { function ensureSell() { var account = GetAccount(); var initAccount = account; - var minStock = exchange.GetMinStock(); + var minStock = MinStock; var isfirst = true; while (true) { cancelPending(); diff --git "a/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.js" "b/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.js" index 59a6744d..f55a9b65 100644 --- "a/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.js" +++ "b/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/8916 +策略出处: https://www.fmz.com/strategy/8916 策略名称: 记录净资产变动情况2.0 策略作者: 中本姜(青铜机器人) 策略描述: diff --git "a/\350\264\246\346\210\267\344\275\231\351\242\235\345\217\230\345\212\250\351\202\256\347\256\261\346\217\220\351\206\222, \346\224\257\346\214\201\346\267\273\345\212\240\345\244\232\344\270\252\344\272\244\346\230\223\346\211\200.js" "b/\350\264\246\346\210\267\344\275\231\351\242\235\345\217\230\345\212\250\351\202\256\347\256\261\346\217\220\351\206\222, \346\224\257\346\214\201\346\267\273\345\212\240\345\244\232\344\270\252\344\272\244\346\230\223\346\211\200.js" index f8ff27f5..66741271 100644 --- "a/\350\264\246\346\210\267\344\275\231\351\242\235\345\217\230\345\212\250\351\202\256\347\256\261\346\217\220\351\206\222, \346\224\257\346\214\201\346\267\273\345\212\240\345\244\232\344\270\252\344\272\244\346\230\223\346\211\200.js" +++ "b/\350\264\246\346\210\267\344\275\231\351\242\235\345\217\230\345\212\250\351\202\256\347\256\261\346\217\220\351\206\222, \346\224\257\346\214\201\346\267\273\345\212\240\345\244\232\344\270\252\344\272\244\346\230\223\346\211\200.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/2006 +策略出处: https://www.fmz.com/strategy/2006 策略名称: 账户余额变动邮箱提醒, 支持添加多个交易所 策略作者: Zero 策略描述: diff --git "a/\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.js" "b/\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.js" index 9fc12462..10f041cc 100644 --- "a/\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.js" +++ "b/\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/179 +策略出处: https://www.fmz.com/strategy/179 策略名称: 趋势跟踪震荡策略 策略作者: Zero 策略描述: diff --git "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237.js" "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237.js" index 83a587ff..4d67f130 100644 --- "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237.js" +++ "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/35986 +策略出处: https://www.fmz.com/strategy/35986 策略名称: 转换任意K线周期 策略作者: 小小梦 策略描述: diff --git "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180118).js" "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180627).js" similarity index 96% rename from "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180118).js" rename to "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180627).js" index 5d8079eb..7d567ebe 100644 --- "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180118).js" +++ "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180627).js" @@ -1,6 +1,6 @@ /* -策略出处: https://www.botvs.com/strategy/41163 -策略名称: 转换任意K线周期管理模板(最近更新20180118) +策略出处: https://www.fmz.com/strategy/41163 +策略名称: 转换任意K线周期管理模板(最近更新20180627) 策略作者: 中本姜(青铜机器人) 策略描述: @@ -55,6 +55,8 @@ UI_NewCycleForMS 1000*60*60*2 合成周期毫秒数 period: 60 */ /* +20180627 + 修改了天无法整合的bug 20180118 屏蔽掉一些log输出 更新于20171114 @@ -253,8 +255,8 @@ function _RecordsManager(NewCycleForMS, Name) { // 判断时间戳, 找到 基础K线 相对于 目标K线的起始时间。 var objTime = new Date(); - var isFirstFind = true; - var FirstStamp = null; + var isFirstFind = true; + var FirstStamp = null; for (var i = 0; i < AssRecords.length; i++) { objTime.setTime(AssRecords[i].Time); var ret = GetDHM(objTime, BaseCycle, NewCycleForMS); @@ -299,7 +301,7 @@ function _RecordsManager(NewCycleForMS, Name) { var is_bad = false; var start_time = AssRecords[n].Time; var stop_time = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Time + BaseCycle; - if (start_time % NewCycleForMS != 0) { + if (ret[2] != DAY && start_time % NewCycleForMS != 0) { //Log("过滤起始时间不正确的k线组合", EasyReadTime(start_time)); is_bad = true; } @@ -316,10 +318,10 @@ function _RecordsManager(NewCycleForMS, Name) { BarObj.High = Calc_High(AssRecords, n, BaseCycle, NewCycleForMS); BarObj.Low = Calc_Low(AssRecords, n, BaseCycle, NewCycleForMS); BarObj.Close = AssRecords[n + (NewCycleForMS / BaseCycle) - 1].Close; - BarObj.Volume = 0; - for (var j = n; j < n + (NewCycleForMS / BaseCycle); j++) { - BarObj.Volume += AssRecords[j].Volume; - } + BarObj.Volume = 0; + for (var j = n; j < n + (NewCycleForMS / BaseCycle); j++) { + BarObj.Volume += AssRecords[j].Volume; + } AfterAssRecords.push(cloneObj(BarObj)); n += (NewCycleForMS / BaseCycle) } @@ -338,7 +340,7 @@ function _RecordsManager(NewCycleForMS, Name) { for(var index_n = n + 1 ;index_n < AssRecords.length; index_n++){ max = Math.max(max, AssRecords[index_n].High); min = Math.min(min, AssRecords[index_n].Low); - BarObj.Volume += AssRecords[index_n].Volume; + BarObj.Volume += AssRecords[index_n].Volume; } BarObj.High = max; BarObj.Low = min; @@ -381,8 +383,8 @@ $.RecordsManager = function (NewCycleForMS, Name) { if (typeof NewCycleForMS === 'undefined') { NewCycleForMS = UI_NewCycleForMS; } - var RecordsManager = new _RecordsManager(NewCycleForMS, Name); - return RecordsManager; + var RecordsManager = new _RecordsManager(NewCycleForMS, Name); + return RecordsManager; } function main() { diff --git "a/\350\277\275\346\266\250\346\235\200\350\267\214.py" "b/\350\277\275\346\266\250\346\235\200\350\267\214.py" new file mode 100644 index 00000000..ef036928 --- /dev/null +++ "b/\350\277\275\346\266\250\346\235\200\350\267\214.py" @@ -0,0 +1,49 @@ +''' +策略出处: https://www.fmz.com/strategy/96634 +策略名称: 追涨杀跌 +策略作者: ChildeTang +策略描述: + + + + +参数 默认值 描述 +------ ----- ---- +PERIOD 60 周期 +LENGTH 1440 长度 +''' + +list=[] + +def doTicker(): + #Log(exchange.GetAccount()) + #Log(list) + ticker = exchange.GetTicker() + last = ticker.Last + if len(list) < LENGTH: + list.append(last) + else: + pMax = max(list) + pMin = min(list) + if last > pMax: + Log("buy " + str(exchange.GetAccount())) + account = exchange.GetAccount() + if account.Balance > last: + #id = exchange.Buy(last, 1) + id = exchange.Buy(-1, 1) + Log("buy id --> " + str(id)) + elif last < pMin: + Log("sell " + str(exchange.GetAccount())) + account = exchange.GetAccount() + if account.Stocks > 0: + #id = exchange.Sell(last, 1) + id = exchange.Sell(-1, 1) + Log("sell id --> " + str(id)) + list.pop(0) + list.append(last) + +def main(): + while(true): + doTicker() #执行策略 + Sleep(PERIOD * 1000) #休息一段时间 + diff --git "a/\351\230\266\346\242\257\344\270\213\345\215\225 - \345\217\257\350\256\276\347\275\256\350\247\246\345\217\221\344\273\267\346\240\274.js" "b/\351\230\266\346\242\257\344\270\213\345\215\225 - \345\217\257\350\256\276\347\275\256\350\247\246\345\217\221\344\273\267\346\240\274.js" index f6f6e251..76c72600 100644 --- "a/\351\230\266\346\242\257\344\270\213\345\215\225 - \345\217\257\350\256\276\347\275\256\350\247\246\345\217\221\344\273\267\346\240\274.js" +++ "b/\351\230\266\346\242\257\344\270\213\345\215\225 - \345\217\257\350\256\276\347\275\256\350\247\246\345\217\221\344\273\267\346\240\274.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/639 +策略出处: https://www.fmz.com/strategy/639 策略名称: 阶梯下单 - 可设置触发价格 策略作者: Zero 策略描述: diff --git "a/\351\235\236\345\270\270\347\256\200\345\215\225\347\232\204\347\255\226\347\225\245\357\274\214\344\275\206\346\230\257\345\276\210\346\234\211\346\225\210.js" "b/\351\235\236\345\270\270\347\256\200\345\215\225\347\232\204\347\255\226\347\225\245\357\274\214\344\275\206\346\230\257\345\276\210\346\234\211\346\225\210.js" index 48431958..7f6c96a0 100644 --- "a/\351\235\236\345\270\270\347\256\200\345\215\225\347\232\204\347\255\226\347\225\245\357\274\214\344\275\206\346\230\257\345\276\210\346\234\211\346\225\210.js" +++ "b/\351\235\236\345\270\270\347\256\200\345\215\225\347\232\204\347\255\226\347\225\245\357\274\214\344\275\206\346\230\257\345\276\210\346\234\211\346\225\210.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/15085 +策略出处: https://www.fmz.com/strategy/15085 策略名称: 非常简单的策略,但是很有效 策略作者: jiebang 策略描述: diff --git "a/\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220.js" "b/\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220.js" new file mode 100644 index 00000000..bd7e6cff --- /dev/null +++ "b/\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220.js" @@ -0,0 +1,78 @@ +/* +策略出处: https://www.fmz.com/strategy/59356 +策略名称: 顺大势逆小势策略之代码实现及可行性分析 +策略作者: 深蓝 +策略描述: + + + + +参数 默认值 描述 +----- ----- ----- +maLen 100 maLen +kd1 50 kd1 +kd2 15 kd2 +*/ + +//语法固定格式,调用main主函数 +function main() { + + //调用商品期货交易类库中的CTA框架 + $.CTA("RM000", function(st) { + + //获取K线数组 + var j = st.records; + + //指标运算参考的最大K线数量 + if (j.length < 100) { + return; + } + + //获取上根K线的收盘价 + var c = j[j.length - 2].Close; + + //获取KDJ指标数组 + var kds = TA.KDJ(j, kd1, kd2, kd2); + + //获取KDJ指标K的数组 + var ks = kds[0]; + + //获取KDJ指标D的数组 + var ds = kds[1]; + + //获取上根K线的K值 + var k = ks[ks.length - 2].toFixed(2); + + //获取上根K线的D值 + var d = ds[ds.length - 2].toFixed(2); + + //获取均线数组 + var mas = TA.MA(j, 100); + + //获取上根K线的MA值 + var ma = mas[mas.length - 2]; + + //获取当前的持仓数量,正数指多仓, 负数指空仓, 0则不持仓 + var mp = st.position.amount; + + //如果当前持有多单,并且上根K线的K值小于上根K线的D值,平多单 + if (mp > 0 && k < d) { + return -1; //如果当前有多单,指定返回值为-N,就是平N手多单。 + } + + //如果当前持有空单,并且上根K线的K值大于上根K线的D值,平空单 + if (mp < 0 && k > d) { + return 1; //如果当前有空单,指定返回值为N,就是平N手空单。 + } + + //如果当前无持仓,并且上根K线的收盘价大于上根K线的MA值,并且上根K线的K值大于上根K线的D值,开多单 + if (mp === 0 && c > ma && k > d) { + return 1; //如果当前无持仓,指定返回值为N,就是开N手多单。 + } + + //如果当前无持仓,并且上根K线的收盘价小于上根K线的MA值,并且上根K线的K值小于上根K线的D值,开空单 + if (mp === 0 && c < ma && k < d) { + return -1; //如果当前无持仓,指定返回值为-N,就是开N手空单。 + } + }); +} diff --git "a/\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213 - Penny Jump.js" "b/\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213 - Penny Jump.js" index bb3d1cdc..5120799b 100644 --- "a/\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213 - Penny Jump.js" +++ "b/\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213 - Penny Jump.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/358 +策略出处: https://www.fmz.com/strategy/358 策略名称: 高频交易策略之 - Penny Jump 策略作者: Zero 策略描述: diff --git "a/\351\253\230\351\242\221\346\224\266\345\211\262\346\234\272\344\270\200\345\217\267.js" "b/\351\253\230\351\242\221\346\224\266\345\211\262\346\234\272\344\270\200\345\217\267.js" index 42d89f5e..d06a6f9b 100644 --- "a/\351\253\230\351\242\221\346\224\266\345\211\262\346\234\272\344\270\200\345\217\267.js" +++ "b/\351\253\230\351\242\221\346\224\266\345\211\262\346\234\272\344\270\200\345\217\267.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/6237 +策略出处: https://www.fmz.com/strategy/6237 策略名称: 高频收割机一号 策略作者: Zero 策略描述: diff --git "a/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.js" "b/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.js" index 544cc146..bbd87e8a 100644 --- "a/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.js" +++ "b/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.js" @@ -1,5 +1,5 @@ /* -策略出处: https://www.botvs.com/strategy/20663 +策略出处: https://www.fmz.com/strategy/20663 策略名称: (13)策略框架 策略作者: 小小梦 策略描述: From 5ac7b446ef37b75852fe99200919ab213bab0cee Mon Sep 17 00:00:00 2001 From: Zero Date: Sat, 8 Dec 2018 12:40:55 +0800 Subject: [PATCH 06/19] update --- ...250\241\345\236\213 (Share 1513096985).js" | 234 -- ...72\345\223\201\347\255\226\347\225\245.js" | 25 - ...77\346\234\272\345\231\250\344\272\272.md" | 44 +- ...47\225\245 (\345\201\232\347\251\272).md" | 65 + ...14\345\276\222\347\255\226\347\225\245.md" | 65 + ...10\346\225\231\345\255\246\357\274\211.md" | 87 + ...10\346\225\231\345\255\246\357\274\211.md" | 86 + ...40\345\200\215\347\256\227\346\263\225.md" | 62 +- ...60\346\211\213\345\205\245\351\227\250.js" | 27 - ...60\346\211\213\345\205\245\351\227\250.md" | 47 + ...55\344\277\241\351\200\232\347\237\245.md" | 50 +- ...-V\345\217\215\347\255\226\347\225\245.md" | 179 + ...60\345\215\226\347\273\237\350\256\241.md" | 70 + ...00\345\215\225\346\265\213\350\257\225.md" | 29 +- ...56\346\222\244\345\215\225) JavaScript.md" | 75 + ...266\346\222\244\345\215\225) Python2-3.md" | 443 +++ ...Bitmex position-change push(websocket).md" | 44 + ...5\351\227\250 \347\255\226\347\225\245.md" | 69 +- ...03\347\224\250\344\276\213\345\255\220.md" | 29 +- ...44\346\230\223\347\255\226\347\225\245.md" | 81 +- ...344\272\206SSL\351\252\214\350\257\201.md" | 49 +- ...Record_Cycle.js => Convert_Record_Cycle.md | 38 +- ...Feature.js => Dual Thrust OKEX Feature.md | 54 +- ...6\350\257\255\350\250\200\347\211\210).md" | 77 + ...Thrust OKCoin \346\234\237\350\264\247.md" | 54 +- ...350\264\247 (\346\225\231\345\255\246).md" | 166 + ...06\345\223\201\346\234\237\350\264\247.md" | 56 +- Dynamic Balance Strategy.md | 106 + ...1\346\200\273\345\210\206\344\272\253).js" | 146 - ...247 - Fomo3D Smart Contract Monitoring.md" | 126 + ...15\344\276\233\345\272\224\351\207\217.md" | 51 + GuoJian_First.md | 85 + ...e_BTC-ETH Demo.js => Hedge_BTC-ETH Demo.md | 38 +- Iceberg Buy Order.js => Iceberg Buy Order.md | 52 +- ...26\347\225\245\346\241\206\346\236\266.md" | 27 +- ..."JS\347\211\210\346\234\254Dual Thrust.md" | 29 +- ...6\347\225\245_\344\275\216\351\242\221.md" | 27 +- MA5.md | 81 + ...04\345\220\210\347\255\226\347\225\245.md" | 99 + ...13\345\212\277\344\272\244\346\230\223.md" | 27 +- ...32\346\212\225\347\255\226\347\225\245.md" | 59 +- ...30\345\270\246\346\255\242\346\215\237.md" | 58 +- ...3\350\257\225\344\275\277\347\224\250).md" | 564 ++++ ...23\345\257\271\344\277\241\346\201\257.md" | 2884 +++++++++++++++++ ...37\347\216\260\345\257\271\345\206\262.md" | 621 ++++ OkEX Websocket Realtime.md | 140 + ...347\216\260\350\264\247;TBD) Python2-3.md" | 344 ++ "Paul \"The Gambler\" L\303\251vy.md" | 261 ++ ...56\347\273\203\344\271\240\357\274\211.md" | 53 + ...13\345\212\277\347\255\226\347\225\245.md" | 40 +- ...> "Python API \346\265\213\350\257\225.md" | 29 +- ...71\345\206\262\347\255\226\347\225\245.md" | 57 +- ...04\346\265\213\344\271\260\345\215\226.md" | 38 +- ...(\346\265\213\350\257\225\347\211\210).md" | 27 +- ...13\350\257\225\347\255\226\347\225\245.md" | 44 +- ...44\346\230\223\347\255\226\347\225\245.md" | 29 +- ...44\346\230\223\347\255\226\347\225\245.md" | 29 +- README.md | 110 +- ...07\347\272\277\347\255\226\347\225\245.md" | 55 +- RSI_now_sb_ok.js => RSI_now_sb_ok.md | 50 +- "RUMI\347\255\226\347\225\245.md" | 66 + Shannon's Demon.js => Shannon's Demon.md | 52 +- ...222\214okcoin\344\270\200\350\207\264).md" | 27 +- TableTemplet.js => TableTemplet.md | 29 +- [VNC] SVM Test.md | 92 + ...01\351\207\221\344\272\244\346\230\223.md" | 27 +- ...60\345\205\245\346\214\201\346\234\211.md" | 29 +- ...26\347\237\277\346\274\224\347\244\272.md" | 40 +- js R-Breaker.js => js R-Breaker.md | 29 +- ...46\346\210\267\345\205\254\345\274\200.md" | 27 +- ...17\344\272\244\346\230\223\351\207\217.md" | 27 +- ...Thrust OKCoin \346\234\237\350\264\247.md" | 54 +- ...\272\223 (\345\205\274\345\256\2712-3).md" | 29 +- ...13\350\257\225\347\211\210\357\274\211.md" | 40 +- ...44\346\230\223\347\261\273\345\272\223.md" | 50 +- ...7\346\240\207\346\241\206\346\236\266).md" | 29 +- ...11\345\217\252\344\271\214\351\270\246.md" | 27 +- ...20\347\240\224\347\251\266\343\200\221.md" | 42 +- ...26\347\225\245\345\217\202\346\225\260.md" | 42 +- ...\265\213\350\257\225 websocket vs rest.md" | 29 +- ...00\347\233\256\345\235\207\350\241\241.md" | 48 +- ...01\347\240\264\347\255\226\347\225\245.md" | 73 + ...50\347\216\207\347\255\226\347\225\245.md" | 89 + ...02\345\260\261\346\230\257\345\271\262.js" | 74 - ...01\347\240\264\345\211\215\351\253\230.md" | 29 +- ...17\345\222\214\347\262\276\345\272\246.md" | 1668 ++++++++++ ...272\277 (0804\346\233\264\346\226\260).md" | 29 +- ...7\350\264\247\347\211\210) Rev. 161216.md" | 29 +- ...07\350\241\241\347\255\226\347\225\245.md" | 38 +- ...4GetMinStock()\345\207\275\346\225\260.md" | 27 +- ....js" => "\344\273\267\345\200\2740.418.md" | 50 +- ...63\345\235\207\345\256\232\346\212\225.md" | 38 +- ...42\345\212\250\346\212\245\350\255\246.md" | 48 +- ...13\345\212\277\347\255\226\347\225\245.md" | 67 + ...44\346\230\223\347\255\226\347\225\245.md" | 73 + ...\273\267\347\233\221\346\216\247 (CTP).md" | 52 +- ...04\345\220\210\347\255\226\347\225\245.md" | 79 + ...60\345\214\226\347\255\226\347\225\245.md" | 29 +- ...76\350\241\250\350\214\203\344\276\213.md" | 67 + ...63\345\217\260\344\275\231\351\242\235.md" | 38 +- ...44\346\230\223\347\263\273\347\273\237.md" | 71 +- ...66\345\267\256\344\273\267\345\233\276.md" | 42 +- ...346\211\230 - \344\271\260\345\205\245.md" | 52 +- ...346\211\230 - \345\215\226\345\207\272.md" | 52 +- ...37\350\264\247\344\270\223\347\224\250.js" | 329 -- ...47\211\210|Simple Iceberg order to buy.md" | 57 + ...7\211\210|Simple Iceberg order to sell.md" | 62 + ...71\351\224\231\346\250\241\346\235\277.md" | 44 +- ...32\204\346\216\222\345\210\227 - btcdw.md" | 27 +- ...16\347\202\271\347\255\226\347\225\245.md" | 79 + ...47\225\245 (\345\260\217\351\253\230).md" | 160 + ...32\345\270\202\347\255\226\347\225\245.md" | 171 + ...6\200\201\345\271\263\350\241\241alpha.md" | 105 + ...50\346\234\237\345\245\227\345\210\251.md" | 431 +++ ...63\350\241\241\347\255\226\347\225\245.md" | 210 ++ ...51\345\231\250\347\255\226\347\225\245.md" | 108 + ...07\350\241\241\347\255\226\347\225\245.js" | 111 - ...07\350\241\241\347\255\226\347\225\245.md" | 111 + ...5\245\227\347\256\227\346\263\225 V1.2.md" | 72 +- ...7\240\201\346\235\245\350\207\252zero).md" | 29 +- ...25\350\276\271\347\275\221\346\240\274.md" | 52 +- ...347\272\277DDI\347\255\226\347\225\245.md" | 96 + ...07\346\240\207\347\273\204\345\220\210.md" | 76 + ...01\346\261\202\346\214\207\347\202\271.md" | 46 +- ...\254(two platforms hedging-JS) (Copy).js" | 225 -- ...\346\234\254(two platforms hedging-JS).md" | 55 +- ...00\346\234\211\350\256\242\345\215\225.md" | 29 +- ...50\347\216\207\347\273\237\350\256\241.md" | 49 +- ...01\346\234\200\344\270\213\351\235\242.md" | 126 + ...13\351\224\244\345\255\220\357\274\211.md" | 88 + ...10\347\272\246\350\277\207\346\273\244.js" | 71 - ...7\345\215\225\345\212\237\350\203\275).md" | 44 +- ...10\346\227\247\347\211\210\357\274\211.md" | 449 +-- ...46\347\273\206\344\277\241\346\201\257.md" | 27 +- ...06\345\217\262\346\237\245\350\257\242.md" | 40 +- ...37\345\215\225\347\263\273\347\273\237.md" | 27 +- ...27\345\210\251\345\220\210\347\272\246.md" | 75 +- ...43\347\240\201\345\256\236\347\216\260.md" | 50 +- ...345\210\260\346\234\254\345\234\260CSV.md" | 27 +- ...17\350\241\250\346\240\274\357\274\211.md" | 368 +++ ...5\347\244\272\345\256\236\344\276\2131.md" | 29 +- ...45\270\201\347\255\226\347\225\245V0.2.md" | 60 +- ...0 \350\241\214\346\220\236\345\256\232.js" | 60 - ...\274\210python\347\211\210\357\274\211.md" | 52 +- ...32\351\201\223\347\255\226\347\225\245.md" | 56 + ...44\346\230\223\347\255\226\347\225\245.md" | 42 +- ...44\346\230\223\347\255\226\347\225\245.md" | 101 + ...6\347\225\245 \350\214\203\344\276\213.md" | 263 ++ ...07\347\272\277\347\255\226\347\225\245.md" | 40 +- ...(\344\271\260\344\270\200\344\273\267).md" | 42 +- ...46\346\210\267\347\273\237\350\256\241.md" | 44 +- ...13\345\212\277\347\255\226\347\225\245.md" | 110 + ...61\345\272\246\344\277\241\346\201\257.md" | 29 +- ...46\346\210\267\344\277\241\346\201\257.md" | 29 +- ...\217\212 Demo \347\250\213\345\272\217.md" | 27 +- ...25\347\256\200\345\215\225\347\211\210.md" | 36 +- ...10\345\210\251\351\252\214\350\257\201.md" | 40 +- ...73\345\234\272\345\215\226\345\215\225.md" | 56 +- ...46\345\217\267\347\273\237\350\256\241.md" | 44 +- ...56\344\273\267\347\233\221\346\216\247.md" | 61 +- ...11\345\261\261\345\257\250\345\270\201.md" | 36 +- ...\357\274\211|Cancel ALL Binance Orders.md" | 48 + ...vs\345\256\236\347\216\260\347\211\210.md" | 44 +- ...346\240\207\347\233\221\346\216\2471.1.md" | 71 +- ...346\240\274\346\257\224\350\276\2031.0.md" | 75 +- ...255\226\347\225\245 (Share 1512580165).js" | 181 -- ...345\267\256ATR\347\255\226\347\225\245.md" | 80 + ...16\347\202\271\347\255\226\347\225\245.md" | 75 + ...347\225\245 - \345\257\271\346\225\262.md" | 48 +- ...21\351\200\274\350\277\221\345\236\213.md" | 50 +- ...347\225\245 (\346\225\231\345\255\246).md" | 102 + ...\255\226\347\225\245|Index Balance Bot.md" | 110 + ...07\346\225\260\351\207\217\345\214\226.md" | 70 +- ...12\347\216\207\347\273\237\350\256\241.md" | 38 +- ...\214\201$.CTA\345\207\275\346\225\260).md" | 62 +- ...47\345\270\201\345\256\232\346\212\225.md" | 44 +- ...44\346\230\223\347\261\273\345\272\223.js" | 397 --- ...Ex\344\272\244\346\230\223 (LTC_USDT).md" | 317 ++ ...60\345\215\225\345\215\226\345\215\225.js" | 20 - ...26\347\211\210\347\255\226\347\225\245.md" | 65 + ...32\351\201\223\347\255\226\347\225\245.md" | 80 + ...57\345\220\246\346\255\243\345\270\270.md" | 36 + ...346\213\237\346\265\213\350\257\225kdj.md" | 442 +++ ...77\347\224\250\344\276\213\345\255\220.js" | 19 - ...77\347\224\250\344\276\213\345\255\220.md" | 39 + ...\345\267\256\344\273\267(by JackConan).md" | 29 +- ...56\344\273\267\345\257\271\345\206\262.md" | 48 +- ...01\347\240\264\347\255\226\347\225\245.md" | 72 + ...60\347\273\204\345\212\237\350\203\275.md" | 44 +- ...6\350\241\250\346\230\276\347\244\272).md" | 38 +- ...45\346\241\206\346\236\266\357\274\211.md" | 51 +- ...76\350\241\250\345\261\225\347\244\272.md" | 29 +- ...\261\225\347\244\272Python\347\211\210.md" | 27 +- "\346\265\267\351\276\237.md" | 408 +++ ...03\347\272\277\347\255\226\347\225\245.md" | 67 + ...\345\206\262(\346\220\254\347\240\226).md" | 405 +++ ...7\347\261\273\345\272\223|Plot library.md" | 29 +- ...14\347\232\204\345\217\230\345\214\226.md" | 40 +- ...07\347\253\240\347\255\226\347\225\245.md" | 40 +- ...45\345\217\243\346\265\213\350\257\225.md" | 40 +- ...32\347\237\245\347\261\273\345\272\223.md" | 52 +- ... "\347\240\264\345\206\260\350\200\205.md" | 72 +- ...\346\234\272 \346\263\250\351\207\212.md" | 331 ++ ...34\346\224\266\345\211\262\346\234\272.md" | 48 +- ...50\346\255\242\346\215\237\347\211\210.md" | 50 +- ...7 \347\210\206\347\240\264\347\211\210.md" | 52 +- ...06\346\236\266\346\250\241\346\235\277.md" | 50 +- ...44\272\272|Stop Loss Below Fixed Price.md" | 82 + ...47\225\245|Moving Average Bot 30 lines.md" | 50 +- ...07\347\272\277\347\255\226\347\225\245.md" | 46 +- ...21\346\240\274\346\265\213\350\257\225.md" | 129 + ...272|Buy then Sell (ping-pong strategy).md" | 63 + ...07\347\272\277\347\255\226\347\225\245.md" | 101 + ...30\345\234\250\350\266\213\345\212\277.md" | 29 +- ...\345\267\256\344\273\267(by JackConan).md" | 29 +- ...6\240\274 (OK\346\234\237\350\264\247).md" | 99 +- ...25\350\276\271\347\275\221\346\240\274.md" | 119 +- ...11\351\246\231\345\206\234\347\211\210.md" | 38 +- ...60\345\215\226\347\244\272\344\276\213.js" | 45 - ...10\346\201\257\346\216\250\351\200\201.md" | 29 +- ...36\346\227\266\351\231\220\344\273\267.md" | 29 +- ...7\345\217\226\345\221\250K\347\272\277.md" | 38 +- ...on\347\211\210\346\234\254\357\274\211.md" | 29 +- ...15\345\270\201\347\273\237\350\256\241.md" | 29 +- ...24\346\211\230\344\271\260\345\205\245.md" | 50 +- ...24\346\211\230\345\215\226\345\207\272.md" | 48 +- ...345\212\250\346\203\205\345\206\2652.0.md" | 56 +- ...1(\346\225\231\345\255\246\357\274\211.md" | 51 + ...52\344\272\244\346\230\223\346\211\200.md" | 58 +- ...07\350\215\241\347\255\226\347\225\245.md" | 62 +- ...60\346\211\213\346\265\213\350\257\225.md" | 79 + ...7K\347\272\277\345\221\250\346\234\237.md" | 38 +- ...7\221\346\233\264\346\226\26020180627).md" | 38 +- ...75\346\266\250\346\235\200\350\267\214.md" | 38 +- ...344\272\272 (\346\225\231\345\255\246).md" | 98 + ...46\345\217\221\344\273\267\346\240\274.md" | 50 +- ...57\345\276\210\346\234\211\346\225\210.js" | 70 - ...14\346\200\247\345\210\206\346\236\220.js" | 78 - ...14\346\200\247\345\210\206\346\236\220.md" | 40 +- ...07\346\240\207\347\255\226\347\225\245.md" | 76 + ...40\346\235\203\347\255\226\347\225\245.md" | 78 + ...44\346\230\223\347\255\226\347\225\245.md" | 89 + ...6\347\225\245\344\271\213 - Penny Jump.md" | 58 +- ...62\346\234\272\344\270\200\345\217\267.md" | 65 +- ...26\347\225\245\344\275\223\351\252\214.md" | 78 + ...26\347\225\245\346\241\206\346\236\266.md" | 51 +- 246 files changed, 20319 insertions(+), 4272 deletions(-) delete mode 100644 "03\345\237\272\344\272\216\345\225\206\345\223\201\346\234\237\350\264\247\347\232\204\345\245\227\345\210\251\347\255\226\347\225\245\346\250\241\345\236\213 (Share 1513096985).js" delete mode 100644 "10\350\241\214\344\272\272\345\223\201\347\255\226\347\225\245.js" rename "2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.js" => "2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.md" (96%) create mode 100644 "30\350\241\214\350\265\214\345\276\222\347\255\226\347\225\245 (\345\201\232\347\251\272).md" create mode 100644 "30\350\241\214\350\265\214\345\276\222\347\255\226\347\225\245.md" create mode 100644 "50\350\241\214\345\244\232\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" create mode 100644 "50\350\241\214\347\275\221\346\240\274\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" rename "796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.js" => "796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.md" (93%) delete mode 100644 "API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.js" create mode 100644 "API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.md" rename "BTC-LTC \345\234\260\345\235\200\347\233\221\350\247\206, \347\237\255\344\277\241\351\200\232\347\237\245.js" => "BTC-LTC \345\234\260\345\235\200\347\233\221\350\247\206, \347\237\255\344\277\241\351\200\232\347\237\245.md" (71%) create mode 100644 "BTC-V\345\217\215\347\255\226\347\225\245.md" create mode 100644 "Binance buy and sell statistics|\345\270\201\345\256\211\344\271\260\345\215\226\347\273\237\350\256\241.md" rename "BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.js" => "BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.md" (73%) create mode 100644 "BitMEX \351\253\230\347\272\247API\345\212\237\350\203\275 (\346\234\237\350\264\247:\346\211\271\351\207\217\344\270\213\345\215\225,\344\270\200\351\224\256\346\222\244\345\215\225) JavaScript.md" create mode 100644 "BitMEX \351\253\230\347\272\247API\345\212\237\350\203\275 V.1.1.0 (\346\234\237\350\264\247:\346\211\271\351\207\217\344\270\213\345\215\225,\347\274\226\350\276\221\350\256\242\345\215\225,\345\206\260\345\261\261\350\256\242\345\215\225,\344\270\200\351\224\256\346\222\244\345\215\225,\345\256\232\346\227\266\346\222\244\345\215\225) Python2-3.md" create mode 100644 "Bitmex\344\273\223\344\275\215\345\217\230\345\214\226\346\216\250\351\200\201\345\276\256\344\277\241\357\274\210wss\345\215\217\350\256\256,\351\234\200\350\246\201bitmex api ID\357\274\211|Bitmex position-change push(websocket).md" rename "BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.js" => "BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.md" (90%) rename "C++ API\350\260\203\347\224\250\344\276\213\345\255\220.cpp" => "C++ API\350\260\203\347\224\250\344\276\213\345\255\220.md" (96%) rename "CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" => "CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.md" (89%) rename "CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.py" => "CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.md" (95%) rename Convert_Record_Cycle.js => Convert_Record_Cycle.md (94%) rename Dual Thrust OKEX Feature.js => Dual Thrust OKEX Feature.md (90%) create mode 100644 "Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210).md" rename "Dual Thrust OKCoin \346\234\237\350\264\247.js" => "Dual Thrust OKCoin \346\234\237\350\264\247.md" (92%) create mode 100644 "Dual Thrust OKEX\346\234\237\350\264\247 (\346\225\231\345\255\246).md" rename "Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.js" => "Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.md" (90%) create mode 100644 Dynamic Balance Strategy.md delete mode 100644 "FCoin\344\272\244\346\230\223\346\211\213\347\273\255\350\264\271\347\273\237\350\256\241(\346\204\237\350\260\242\346\273\241\346\200\273\345\210\206\344\272\253).js" create mode 100644 "Fomo3D \346\231\272\350\203\275\345\220\210\347\272\246\347\233\221\346\216\247 - Fomo3D Smart Contract Monitoring.md" create mode 100644 "Get cryptocurrency current and max supply|\350\216\267\345\217\226\345\270\201\347\247\215\344\276\233\345\272\224\351\207\217.md" create mode 100644 GuoJian_First.md rename Hedge_BTC-ETH Demo.js => Hedge_BTC-ETH Demo.md (93%) rename Iceberg Buy Order.js => Iceberg Buy Order.md (85%) rename "JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.js" => "JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.md" (89%) rename "JS\347\211\210\346\234\254Dual Thrust.js" => "JS\347\211\210\346\234\254Dual Thrust.md" (95%) rename "KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.js" => "KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.md" (95%) create mode 100644 MA5.md create mode 100644 "MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" rename "Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.js" => "Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.md" (94%) rename "My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.js" => "My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.md" (90%) rename "OKCoin\346\234\237\350\264\247\346\235\241\344\273\266\350\247\246\345\217\221\345\247\224\346\211\230\345\270\246\346\255\242\346\215\237.js" => "OKCoin\346\234\237\350\264\247\346\235\241\344\273\266\350\247\246\345\217\221\345\247\224\346\211\230\345\270\246\346\255\242\346\215\237.md" (85%) create mode 100644 "OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245(\346\250\241\346\235\277\346\265\213\350\257\225\344\275\277\347\224\250).md" create mode 100644 "OKEX\344\272\244\346\230\223\345\257\271\344\277\241\346\201\257.md" create mode 100644 "OKEX\346\234\237\347\216\260\345\257\271\345\206\262.md" create mode 100644 OkEX Websocket Realtime.md create mode 100644 "OkEX \351\253\230\347\272\247API\345\212\237\350\203\275 V.1.1.0 (\346\234\237\350\264\247:\346\211\271\351\207\217\344\270\213\345\215\225,\347\216\260\350\264\247;TBD) Python2-3.md" create mode 100644 "Paul \"The Gambler\" L\303\251vy.md" create mode 100644 "Push Binance deal order to WeChat|\345\256\236\346\227\266\346\216\250\351\200\201\345\270\201\345\256\211\346\210\220\344\272\244\345\210\260\345\276\256\344\277\241(wss\345\215\217\350\256\256\347\273\203\344\271\240\357\274\211.md" rename "Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" => "Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.md" (84%) rename "Python API \346\265\213\350\257\225.py" => "Python API \346\265\213\350\257\225.md" (94%) rename "Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.py" => "Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.md" (91%) rename "Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.py" => "Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.md" (92%) rename "Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" => "Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).md" (95%) rename "Python\347\256\200\345\215\225\346\265\213\350\257\225\347\255\226\347\225\245.py" => "Python\347\256\200\345\215\225\346\265\213\350\257\225\347\255\226\347\225\245.md" (83%) rename "R-Breaker \344\272\244\346\230\223\347\255\226\347\225\245.py" => "R-Breaker \344\272\244\346\230\223\347\255\226\347\225\245.md" (97%) rename "R-Breaker11 \344\272\244\346\230\223\347\255\226\347\225\245.py" => "R-Breaker11 \344\272\244\346\230\223\347\255\226\347\225\245.md" (98%) rename "RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.js" => "RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.md" (87%) rename RSI_now_sb_ok.js => RSI_now_sb_ok.md (90%) create mode 100644 "RUMI\347\255\226\347\225\245.md" rename Shannon's Demon.js => Shannon's Demon.md (71%) rename "StochRSI(\345\222\214okcoin\344\270\200\350\207\264).js" => "StochRSI(\345\222\214okcoin\344\270\200\350\207\264).md" (96%) rename TableTemplet.js => TableTemplet.md (93%) create mode 100644 [VNC] SVM Test.md rename "bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.js" => "bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.md" (90%) rename "buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.js" => "buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.md" (89%) rename "fcoin\346\214\226\347\237\277\346\274\224\347\244\272.js" => "fcoin\346\214\226\347\237\277\346\274\224\347\244\272.md" (79%) rename js R-Breaker.js => js R-Breaker.md (96%) rename "okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.js" => "okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.md" (93%) rename "okex\345\270\201\345\270\201\346\234\200\345\260\217\344\272\244\346\230\223\351\207\217.js" => "okex\345\270\201\345\270\201\346\234\200\345\260\217\344\272\244\346\230\223\351\207\217.md" (98%) rename "python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" => "python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.md" (92%) rename "python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" => "python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).md" (96%) rename "python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" => "python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.md" (98%) rename "python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.py" => "python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.md" (93%) rename "stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).js" => "stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).md" (97%) rename "talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" => "talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.md" (76%) rename "\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.js" => "\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.md" (92%) rename "\343\200\220Demo\343\200\221\345\246\202\344\275\225\345\210\251\347\224\250\342\200\234\347\255\226\347\225\245\344\272\244\344\272\222\342\200\234\345\212\250\346\200\201\350\260\203\346\225\264\347\255\226\347\225\245\345\217\202\346\225\260.js" => "\343\200\220Demo\343\200\221\345\246\202\344\275\225\345\210\251\347\224\250\342\200\234\347\255\226\347\225\245\344\272\244\344\272\222\342\200\234\345\212\250\346\200\201\350\260\203\346\225\264\347\255\226\347\225\245\345\217\202\346\225\260.md" (80%) rename "\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest.js" => "\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest.md" (91%) rename "\344\270\200\347\233\256\345\235\207\350\241\241.js" => "\344\270\200\347\233\256\345\235\207\350\241\241.md" (92%) create mode 100644 "\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245.md" create mode 100644 "\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245.md" delete mode 100644 "\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262.js" rename "\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" => "\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.md" (86%) create mode 100644 "\344\272\244\346\230\223\346\211\200\346\234\200\345\260\217\346\225\260\351\207\217\345\222\214\347\262\276\345\272\246.md" rename "\344\273\216\347\254\254\344\270\211\346\226\271\347\275\221\347\253\231\350\216\267\345\217\226K\347\272\277 (0804\346\233\264\346\226\260).js" => "\344\273\216\347\254\254\344\270\211\346\226\271\347\275\221\347\253\231\350\216\267\345\217\226K\347\272\277 (0804\346\233\264\346\226\260).md" (92%) rename "\344\273\216\347\254\254\344\270\211\346\226\271\350\216\267\345\217\226K\347\272\277 (\345\225\206\345\223\201\346\234\237\350\264\247\347\211\210) Rev. 161216.js" => "\344\273\216\347\254\254\344\270\211\346\226\271\350\216\267\345\217\226K\347\272\277 (\345\225\206\345\223\201\346\234\237\350\264\247\347\211\210) Rev. 161216.md" (96%) rename "\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.js" => "\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.md" (74%) rename "\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.js" => "\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.md" (84%) rename "\344\273\267\345\200\2740.418.js" => "\344\273\267\345\200\2740.418.md" (92%) rename "\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225.js" => "\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225.md" (88%) rename "\344\273\267\346\240\274\346\263\242\345\212\250\346\212\245\350\255\246.js" => "\344\273\267\346\240\274\346\263\242\345\212\250\346\212\245\350\255\246.md" (86%) create mode 100644 "\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245.md" create mode 100644 "\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" rename "\344\274\240\347\273\237\346\234\237\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247 (CTP).js" => "\344\274\240\347\273\237\346\234\237\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247 (CTP).md" (85%) create mode 100644 "\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" rename "\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.js" => "\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.md" (94%) create mode 100644 "\344\275\277\347\224\250\347\224\273\347\272\277\347\261\273\345\272\223\347\224\273K\347\272\277\344\273\245\345\217\212\345\235\207\347\272\277\345\233\276\350\241\250\350\214\203\344\276\213.md" rename "\345\205\245\351\227\250\346\250\241\346\235\277\344\271\213\345\220\204\344\270\252\345\271\263\345\217\260\344\275\231\351\242\235.js" => "\345\205\245\351\227\250\346\250\241\346\235\277\344\271\213\345\220\204\344\270\252\345\271\263\345\217\260\344\275\231\351\242\235.md" (75%) rename "\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.js" => "\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.md" (92%) rename "\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.js" => "\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.md" (87%) rename "\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.js" => "\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.md" (85%) rename "\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.js" => "\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.md" (84%) delete mode 100644 "\345\206\260\345\261\261\345\247\224\346\211\230 - \346\224\257\346\214\201\344\273\267\346\240\274\350\247\246\345\217\221 BitVC\346\234\237\350\264\247\344\270\223\347\224\250.js" create mode 100644 "\345\206\260\345\261\261\345\247\224\346\211\230\344\271\260\345\205\245\347\256\200\345\215\225\347\211\210|Simple Iceberg order to buy.md" create mode 100644 "\345\206\260\345\261\261\345\247\224\346\211\230\345\215\226\345\207\272\347\256\200\345\215\225\347\211\210|Simple Iceberg order to sell.md" rename "\345\207\275\346\225\260\350\207\252\345\212\250\345\256\271\351\224\231\346\250\241\346\235\277.js" => "\345\207\275\346\225\260\350\207\252\345\212\250\345\256\271\351\224\231\346\250\241\346\235\277.md" (60%) rename "\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.py" => "\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.md" (80%) create mode 100644 "\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" create mode 100644 "\345\212\250\346\200\201\345\271\263\350\241\241 \345\201\232\345\270\202\347\255\226\347\225\245 (\345\260\217\351\253\230).md" create mode 100644 "\345\212\250\346\200\201\345\271\263\350\241\241 \345\201\232\345\270\202\347\255\226\347\225\245.md" create mode 100644 "\345\212\250\346\200\201\345\271\263\350\241\241alpha.md" create mode 100644 "\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" create mode 100644 "\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" create mode 100644 "\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" delete mode 100644 "\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.js" create mode 100644 "\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.md" rename "\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.js" => "\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.md" (94%) rename "\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).js" => "\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).md" (83%) rename "\345\215\225\350\276\271\347\275\221\346\240\274.js" => "\345\215\225\350\276\271\347\275\221\346\240\274.md" (88%) create mode 100644 "\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245.md" create mode 100644 "\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210.md" rename "\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.py" => "\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.md" (95%) delete mode 100644 "\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS) (Copy).js" rename "\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" => "\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).md" (93%) rename "\345\217\226\346\266\210\346\211\200\346\234\211\350\256\242\345\215\225.js" => "\345\217\226\346\266\210\346\211\200\346\234\211\350\256\242\345\215\225.md" (84%) rename "\345\220\204\345\244\247\345\271\263\345\217\260API\345\217\257\347\224\250\347\216\207\347\273\237\350\256\241.js" => "\345\220\204\345\244\247\345\271\263\345\217\260API\345\217\257\347\224\250\347\216\207\347\273\237\350\256\241.md" (94%) create mode 100644 "\345\220\210\346\210\220\344\273\273\346\204\217\345\221\250\346\234\237K\347\272\277 \344\275\277\347\224\250\350\257\267\347\234\213\346\272\220\347\240\201\346\234\200\344\270\213\351\235\242.md" create mode 100644 "\345\225\206\345\223\201\346\234\237\350\264\247 - \345\275\242\346\200\201\347\255\226\347\225\245\357\274\210\345\242\236\345\274\272\345\236\213\351\224\244\345\255\220\357\274\211.md" delete mode 100644 "\345\225\206\345\223\201\346\234\237\350\264\247\344\270\273\345\212\233\345\220\210\347\272\246\350\277\207\346\273\244.js" rename "\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223(\345\242\236\345\212\240\344\270\213\351\231\220\344\273\267\345\215\225\345\212\237\350\203\275).js" => "\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223(\345\242\236\345\212\240\344\270\213\351\231\220\344\273\267\345\215\225\345\212\237\350\203\275).md" (95%) rename "\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" => "\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\227\247\347\211\210\357\274\211.md" (72%) rename "\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.js" => "\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.md" (93%) rename "\345\225\206\345\223\201\346\234\237\350\264\247\347\273\223\347\256\227\345\215\225\345\271\263\344\273\223\347\233\210\344\272\217\345\216\206\345\217\262\346\237\245\350\257\242.js" => "\345\225\206\345\223\201\346\234\237\350\264\247\347\273\223\347\256\227\345\215\225\345\271\263\344\273\223\347\233\210\344\272\217\345\216\206\345\217\262\346\237\245\350\257\242.md" (84%) rename "\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.js" => "\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" (95%) rename "\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \345\215\225\345\223\201\347\247\215\345\245\227\345\210\251\345\220\210\347\272\246.js" => "\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \345\215\225\345\223\201\347\247\215\345\245\227\345\210\251\345\220\210\347\272\246.md" (80%) rename "\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \347\231\276\350\241\214\344\273\243\347\240\201\345\256\236\347\216\260.js" => "\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \347\231\276\350\241\214\344\273\243\347\240\201\345\256\236\347\216\260.md" (88%) rename "\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.py" => "\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.md" (84%) create mode 100644 "\345\233\276\350\241\250\346\250\241\346\235\277\357\274\210\345\242\236\345\212\240\347\212\266\346\200\201\346\240\217\350\241\250\346\240\274\357\274\211.md" rename "\345\233\276\350\241\250\347\225\214\351\235\242\344\277\241\346\201\257\345\261\225\347\244\272\345\256\236\344\276\2131.js" => "\345\233\276\350\241\250\347\225\214\351\235\242\344\277\241\346\201\257\345\261\225\347\244\272\345\256\236\344\276\2131.md" (93%) rename "\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2.py" => "\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2.md" (82%) delete mode 100644 "\345\235\207\347\272\277\347\255\226\347\225\245 30 \350\241\214\346\220\236\345\256\232.js" rename "\345\235\207\347\272\277\347\255\226\347\225\245\357\274\210python\347\211\210\357\274\211.py" => "\345\235\207\347\272\277\347\255\226\347\225\245\357\274\210python\347\211\210\357\274\211.md" (71%) create mode 100644 "\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245.md" rename "\345\237\272\344\272\216CCI\345\221\250\346\234\237\346\200\247\345\214\272\351\227\264\344\272\244\346\230\223\347\255\226\347\225\245.js" => "\345\237\272\344\272\216CCI\345\221\250\346\234\237\346\200\247\345\214\272\351\227\264\344\272\244\346\230\223\347\255\226\347\225\245.md" (86%) create mode 100644 "\345\237\272\344\272\216\345\233\236\345\275\222\345\271\205\345\272\246\347\232\204\345\217\215\350\275\254\344\272\244\346\230\223\347\255\226\347\225\245.md" create mode 100644 "\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" rename "\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.js" => "\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.md" (92%) rename "\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).js" => "\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).md" (77%) rename "\345\244\232\345\271\263\345\217\260\350\264\246\346\210\267\347\273\237\350\256\241.js" => "\345\244\232\345\271\263\345\217\260\350\264\246\346\210\267\347\273\237\350\256\241.md" (80%) create mode 100644 "\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245.md" rename "\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\346\267\261\345\272\246\344\277\241\346\201\257.js" => "\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\346\267\261\345\272\246\344\277\241\346\201\257.md" (80%) rename "\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\350\264\246\346\210\267\344\277\241\346\201\257.js" => "\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\350\264\246\346\210\267\344\277\241\346\201\257.md" (80%) rename "\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.js" => "\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.md" (90%) rename "\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.js" => "\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.md" (84%) rename "\345\256\232\346\234\237\345\256\232\351\242\235\346\212\225\350\265\204BTC\347\233\210\345\210\251\351\252\214\350\257\201.js" => "\345\256\232\346\234\237\345\256\232\351\242\235\346\212\225\350\265\204BTC\347\233\210\345\210\251\351\252\214\350\257\201.md" (81%) rename "\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.js" => "\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.md" (88%) rename "\345\257\271\345\206\2622.7\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241\347\263\273\347\273\237 \346\224\257\346\214\201\345\244\232\347\273\204\350\264\246\345\217\267\347\273\237\350\256\241.js" => "\345\257\271\345\206\2622.7\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241\347\263\273\347\273\237 \346\224\257\346\214\201\345\244\232\347\273\204\350\264\246\345\217\267\347\273\237\350\256\241.md" (90%) rename "\345\267\256\344\273\267\347\233\221\346\216\247.js" => "\345\267\256\344\273\267\347\233\221\346\216\247.md" (85%) rename "\345\270\201\345\256\211\345\207\272\345\224\256\346\211\200\346\234\211\345\261\261\345\257\250\345\270\201.js" => "\345\270\201\345\256\211\345\207\272\345\224\256\346\211\200\346\234\211\345\261\261\345\257\250\345\270\201.md" (83%) create mode 100644 "\345\270\201\345\256\211\345\217\226\346\266\210\346\211\200\346\234\211\344\272\244\346\230\223\345\257\271\346\234\252\345\256\214\346\210\220\350\256\242\345\215\225\357\274\210IO\346\211\251\345\261\225\347\244\272\350\214\203\357\274\211|Cancel ALL Binance Orders.md" rename "\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.py" => "\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.md" (98%) rename "\345\271\263\345\217\260\344\273\267\346\240\274\346\214\207\346\240\207\347\233\221\346\216\2471.1.js" => "\345\271\263\345\217\260\344\273\267\346\240\274\346\214\207\346\240\207\347\233\221\346\216\2471.1.md" (91%) rename "\345\271\263\345\217\260\344\273\267\346\240\274\346\257\224\350\276\2031.0.js" => "\345\271\263\345\217\260\344\273\267\346\240\274\346\257\224\350\276\2031.0.md" (84%) delete mode 100644 "\345\271\275\347\201\265\344\272\244\346\230\223\350\200\205\347\255\226\347\225\245 (Share 1512580165).js" create mode 100644 "\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245.md" create mode 100644 "\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" rename "\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.js" => "\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.md" (88%) rename "\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \351\253\230\351\242\221\351\200\274\350\277\221\345\236\213.js" => "\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \351\253\230\351\242\221\351\200\274\350\277\221\345\236\213.md" (88%) create mode 100644 "\346\214\207\346\225\260\345\235\207\350\241\241\347\255\226\347\225\245 (\346\225\231\345\255\246).md" create mode 100644 "\346\214\207\346\225\260\345\271\263\350\241\241\347\255\226\347\225\245|Index Balance Bot.md" rename "\346\214\207\346\225\260\351\207\217\345\214\226.js" => "\346\214\207\346\225\260\351\207\217\345\214\226.md" (88%) rename "\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241.js" => "\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241.md" (94%) rename "\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" => "\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).md" (95%) rename "\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.py" => "\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.md" (75%) delete mode 100644 "\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" create mode 100644 "\346\226\260\346\211\213\344\270\212\350\267\257CoinEx\344\272\244\346\230\223 (LTC_USDT).md" delete mode 100644 "\346\226\260\346\211\213\345\205\245\351\227\250\344\271\213 - \344\270\213\344\271\260\345\215\225\345\215\226\345\215\225.js" create mode 100644 "\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245.md" create mode 100644 "\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245.md" create mode 100644 "\346\243\200\346\237\245https:--quant.la-Argus-\346\230\257\345\220\246\346\255\243\345\270\270.md" create mode 100644 "\346\250\241\346\213\237\346\265\213\350\257\225kdj.md" delete mode 100644 "\346\250\241\346\235\277\345\272\223\344\275\277\347\224\250\344\276\213\345\255\220.js" create mode 100644 "\346\250\241\346\235\277\345\272\223\344\275\277\347\224\250\344\276\213\345\255\220.md" rename "\346\257\2171\345\210\206\351\222\237\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\345\267\256\344\273\267(by JackConan).js" => "\346\257\2171\345\210\206\351\222\237\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\345\267\256\344\273\267(by JackConan).md" (85%) rename "\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.js" => "\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.md" (97%) create mode 100644 "\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245.md" rename "\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" => "\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.md" (61%) rename "\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).js" => "\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).md" (93%) rename "\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211.js" => "\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211.md" (95%) rename "\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.js" => "\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.md" (91%) rename "\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.py" => "\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.md" (87%) create mode 100644 "\346\265\267\351\276\237.md" create mode 100644 "\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245.md" create mode 100644 "\347\216\260\347\216\260\345\257\271\345\206\262(\346\220\254\347\240\226).md" rename "\347\224\273\347\272\277\347\261\273\345\272\223.js" => "\347\224\273\347\272\277\347\261\273\345\272\223|Plot library.md" (96%) rename "\347\233\221\350\247\206\345\271\266\346\230\276\347\244\272\345\244\232\344\270\252\345\271\263\345\217\260\347\232\204\345\205\250\351\203\250\350\265\204\344\272\247\346\200\273\345\222\214\347\232\204\345\217\230\345\214\226.js" => "\347\233\221\350\247\206\345\271\266\346\230\276\347\244\272\345\244\232\344\270\252\345\271\263\345\217\260\347\232\204\345\205\250\351\203\250\350\265\204\344\272\247\346\200\273\345\222\214\347\232\204\345\217\230\345\214\226.md" (86%) rename "\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.js" => "\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.md" (96%) rename "\347\237\255\344\277\241\351\200\232\347\237\245\346\216\245\345\217\243\346\265\213\350\257\225.js" => "\347\237\255\344\277\241\351\200\232\347\237\245\346\216\245\345\217\243\346\265\213\350\257\225.md" (62%) rename "\347\237\255\344\277\241\351\200\232\347\237\245\347\261\273\345\272\223.js" => "\347\237\255\344\277\241\351\200\232\347\237\245\347\261\273\345\272\223.md" (71%) rename "\347\240\264\345\206\260\350\200\205.js" => "\347\240\264\345\206\260\350\200\205.md" (94%) create mode 100644 "\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272 \346\263\250\351\207\212.md" rename "\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.js" => "\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.md" (94%) rename "\347\252\234\345\244\251\347\214\264 - \347\247\273\345\212\250\346\255\242\346\215\237\347\211\210.js" => "\347\252\234\345\244\251\347\214\264 - \347\247\273\345\212\250\346\255\242\346\215\237\347\211\210.md" (88%) rename "\347\252\234\345\244\251\347\214\264 \345\244\232\347\251\272\350\276\203\351\207\217 \347\210\206\347\240\264\347\211\210.js" => "\347\252\234\345\244\251\347\214\264 \345\244\232\347\251\272\350\276\203\351\207\217 \347\210\206\347\240\264\347\211\210.md" (86%) rename "\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" => "\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.md" (97%) create mode 100644 "\347\256\200\345\215\225\345\233\272\345\256\232\344\273\267\346\240\274\346\255\242\346\215\237\346\234\272\345\231\250\344\272\272|Stop Loss Below Fixed Price.md" rename Moving Average Strategy in 30 lines.js => "\347\256\200\345\215\225\345\235\207\347\272\277\347\255\226\347\225\245|Moving Average Bot 30 lines.md" (78%) rename "\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.js" => "\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.md" (78%) create mode 100644 "\347\256\200\345\215\225\347\275\221\346\240\274\346\265\213\350\257\225.md" create mode 100644 "\347\256\200\345\215\225\351\242\204\345\256\232\344\271\260\345\205\245\345\220\216\345\215\226\345\207\272\346\234\272\345\231\250\344\272\272|Buy then Sell (ping-pong strategy).md" create mode 100644 "\347\273\217\345\205\270\345\235\207\347\272\277\347\255\226\347\225\245.md" rename "\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.js" => "\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.md" (89%) rename "\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\344\273\267(by JackConan).js" => "\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\344\273\267(by JackConan).md" (84%) rename "\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).js" => "\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).md" (91%) rename "\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" => "\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.md" (91%) rename "\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.js" => "\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.md" (88%) delete mode 100644 "\350\202\241\347\245\250\350\257\201\345\210\270\346\237\245\350\257\242\344\271\260\345\215\226\347\244\272\344\276\213.js" rename "\350\214\203\344\276\213-\345\256\232\346\227\266\346\265\213\350\257\225\345\276\256\344\277\241\346\266\210\346\201\257\346\216\250\351\200\201.js" => "\350\214\203\344\276\213-\345\256\232\346\227\266\346\265\213\350\257\225\345\276\256\344\277\241\346\266\210\346\201\257\346\216\250\351\200\201.md" (74%) rename "\350\216\267\345\217\226OK\346\234\237\350\264\247\345\256\236\346\227\266\351\231\220\344\273\267.js" => "\350\216\267\345\217\226OK\346\234\237\350\264\247\345\256\236\346\227\266\351\231\220\344\273\267.md" (82%) rename "\350\216\267\345\217\226\345\221\250K\347\272\277.js" => "\350\216\267\345\217\226\345\221\250K\347\272\277.md" (83%) rename "\350\216\267\345\217\226\345\222\214\350\256\257\346\234\237\350\264\247\346\225\260\346\215\256\357\274\210Python\347\211\210\346\234\254\357\274\211.py" => "\350\216\267\345\217\226\345\222\214\350\256\257\346\234\237\350\264\247\346\225\260\346\215\256\357\274\210Python\347\211\210\346\234\254\357\274\211.md" (91%) rename "\350\236\215\350\265\204\350\236\215\345\270\201\347\273\237\350\256\241.js" => "\350\236\215\350\265\204\350\236\215\345\270\201\347\273\237\350\256\241.md" (88%) rename "\350\256\241\345\210\222\345\247\224\346\211\230\344\271\260\345\205\245.js" => "\350\256\241\345\210\222\345\247\224\346\211\230\344\271\260\345\205\245.md" (88%) rename "\350\256\241\345\210\222\345\247\224\346\211\230\345\215\226\345\207\272.js" => "\350\256\241\345\210\222\345\247\224\346\211\230\345\215\226\345\207\272.md" (89%) rename "\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.js" => "\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.md" (90%) create mode 100644 "\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211.md" rename "\350\264\246\346\210\267\344\275\231\351\242\235\345\217\230\345\212\250\351\202\256\347\256\261\346\217\220\351\206\222, \346\224\257\346\214\201\346\267\273\345\212\240\345\244\232\344\270\252\344\272\244\346\230\223\346\211\200.js" => "\350\264\246\346\210\267\344\275\231\351\242\235\345\217\230\345\212\250\351\202\256\347\256\261\346\217\220\351\206\222, \346\224\257\346\214\201\346\267\273\345\212\240\345\244\232\344\270\252\344\272\244\346\230\223\346\211\200.md" (77%) rename "\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.js" => "\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.md" (89%) create mode 100644 "\350\267\250\345\271\263\345\217\260\345\245\227\345\210\251\346\226\260\346\211\213\346\265\213\350\257\225.md" rename "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237.js" => "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237.md" (95%) rename "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180627).js" => "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180627).md" (97%) rename "\350\277\275\346\266\250\346\235\200\350\267\214.py" => "\350\277\275\346\266\250\346\235\200\350\267\214.md" (77%) create mode 100644 "\351\227\252\345\264\251\346\234\272\345\231\250\344\272\272 (\346\225\231\345\255\246).md" rename "\351\230\266\346\242\257\344\270\213\345\215\225 - \345\217\257\350\256\276\347\275\256\350\247\246\345\217\221\344\273\267\346\240\274.js" => "\351\230\266\346\242\257\344\270\213\345\215\225 - \345\217\257\350\256\276\347\275\256\350\247\246\345\217\221\344\273\267\346\240\274.md" (80%) delete mode 100644 "\351\235\236\345\270\270\347\256\200\345\215\225\347\232\204\347\255\226\347\225\245\357\274\214\344\275\206\346\230\257\345\276\210\346\234\211\346\225\210.js" delete mode 100644 "\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220.js" rename "02\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220 (Share 1513097042).js" => "\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220.md" (86%) create mode 100644 "\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245.md" create mode 100644 "\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245.md" create mode 100644 "\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245.md" rename "\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213 - Penny Jump.js" => "\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213 - Penny Jump.md" (90%) rename "\351\253\230\351\242\221\346\224\266\345\211\262\346\234\272\344\270\200\345\217\267.js" => "\351\253\230\351\242\221\346\224\266\345\211\262\346\234\272\344\270\200\345\217\267.md" (92%) create mode 100644 "\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214.md" rename "\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.js" => "\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.md" (95%) diff --git "a/03\345\237\272\344\272\216\345\225\206\345\223\201\346\234\237\350\264\247\347\232\204\345\245\227\345\210\251\347\255\226\347\225\245\346\250\241\345\236\213 (Share 1513096985).js" "b/03\345\237\272\344\272\216\345\225\206\345\223\201\346\234\237\350\264\247\347\232\204\345\245\227\345\210\251\347\255\226\347\225\245\346\250\241\345\236\213 (Share 1513096985).js" deleted file mode 100644 index 76e9bd23..00000000 --- "a/03\345\237\272\344\272\216\345\225\206\345\223\201\346\234\237\350\264\247\347\232\204\345\245\227\345\210\251\347\255\226\347\225\245\346\250\241\345\236\213 (Share 1513096985).js" +++ /dev/null @@ -1,234 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/63221 -策略名称: 03基于商品期货的套利策略模型 (Share 1513096985) -策略作者: ellajella-0378 -策略描述: - -商品期货对冲 + 网格 - -传统的跨期对冲一般指统计套利, 用线性回归或者其它办法生成一个套利区间, 这样套利机会比较少, 而且有预测性, 未来价差很可能不是预计的那样回归 - -为了解决这种办法, 进而更频繁的进行套利操作, 我们把两个关联品种或者跨期品种的套利价差定义成一个网格, 每满足一定的价差就开一次仓, 做一次对冲 - -这样价差来回在我们设置的网格里进行波动,我们就能不断的开仓平仓实现盈利. - -不善文案, 不做文字表达了, 具体看策略代码 - - -参数 默认值 描述 ------------ -------------------------------------------------------------------------------------- ----------- -HedgeTable (MA705&MA709)30:15:1;40:25:1;50:35:1;60:45:1(FG705&FG709)10:0:1;15:5:1;20:10:1;25:15:1 开仓表 -CoverAll false 启动时平掉所有仓位 -CalcPeriod 60 账户权益统计周期(分) -AutoRestore false 自动恢复 -*/ - -function Hedge(q, e, positions, symbolA, symbolB, hedgeSpread) { - var self = {} - self.q = q - self.symbolA = symbolA - self.symbolB = symbolB - self.name = symbolA + " & " + symbolB - self.e = e - self.isBusy = false - self.diffA = 0 - self.diffB = 0 - self.update = _D() - var arr = hedgeSpread.split(';') - self.dic = [] - var n = 0 - var coefficient = 1 - for (var i = 0; i < positions.length; i++) { - if (positions[i].ContractType == symbolA) { - n += positions[i].Amount - if (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) { - coefficient = -1 - } - } - } - _.each(arr, function(pair) { - var tmp = pair.split(':'); - if (tmp.length != 3) { - throw "开仓表不正确"; - } - var st = { - open: Number(tmp[0]), - cover: Number(tmp[1]), - amount: Number(tmp[2]), - hold: 0 - } - if (n > 0) { - var m = Math.min(n, st.amount) - n -= m - st.hold = m * coefficient - Log("恢复", self.name, st) - } - self.dic.push(st) - }); - if (n > 0) { - throw "恢复失败, 有多余仓位 " + n; - } - - self.poll = function() { - if (self.isBusy || (!$.IsTrading(self.symbolA))) { - return - } - var insDetailA = exchange.SetContractType(self.symbolA) - if (!insDetailA) { - return - } - var tickerA = exchange.GetTicker() - if (!tickerA) { - return - } - var insDetailB = exchange.SetContractType(self.symbolB) - if (!insDetailB) { - return - } - var tickerB = exchange.GetTicker() - if (!tickerB) { - return - } - - self.update = _D(tickerA.Time) - - var action = null - var diffA = _N(tickerA.Buy - tickerB.Sell) - var diffB = _N(tickerA.Sell - tickerB.Buy) - self.diffA = diffA - self.diffB = diffB - - for (var i = 0; i < self.dic.length && !action; i++) { - if (self.dic[i].hold == 0) { - if (self.dic[i].open <= diffA) { - action = [i, "sell", "buy", self.dic[i].amount] - } else if (self.dic[i].open <= -diffB) { - action = [i, "buy", "sell", -self.dic[i].amount] - } - } else { - if (self.dic[i].hold > 0 && self.dic[i].cover >= diffB) { - action = [i, "closesell", "closebuy", self.dic[i].hold] - } else if (self.dic[i].hold < 0 && self.dic[i].cover >= -diffA) { - action = [i, "closebuy", "closesell", self.dic[i].hold] - } - } - } - - if (!action) { - return - } - - Log("A卖B买: " + _N(diffA) + ", A买B卖: " + _N(diffB), ", Action: " + JSON.stringify(action)) - - self.isBusy = true - - self.q.pushTask(self.e, self.symbolA, action[1], self.dic[action[0]].amount, function(task, ret) { - if (!ret) { - self.isBusy = false - return - } - self.q.pushTask(self.e, self.symbolB, action[2], self.dic[action[0]].amount, function(task, ret) { - if (!ret) { - throw "开仓失败..." - } - self.isBusy = false - if (task.action != "buy" && task.action != "sell") { - self.dic[action[0]].hold = 0; - } else { - self.dic[action[0]].hold = action[3]; - } - }) - }) - } - return self -} - - -function main() { - SetErrorFilter("ready|login|timeout") - Log("正在与交易服务器连接...") - while (!exchange.IO("status")) Sleep(1000); - Log("与交易服务器连接成功") - var mode = exchange.IO("mode", 0); - if (typeof(mode) !== 'number') { - throw "切换模式失败, 请更新到最新托管者!"; - } else { - Log("已切换到适合多品种价格查询的立即模式"); - } - - if (CoverAll) { - Log("开始平掉所有残余仓位..."); - $.NewPositionManager().CoverAll(); - Log("操作完成"); - } - LogStatus("尝试获取持仓状态") - var positions = _C(exchange.GetPosition) - LogStatus("Ready") - - if (positions.length > 0 && !AutoRestore) { - throw "发现持仓, 请勾选自动恢复" - } - - var pairs = [] - var q = $.NewTaskQueue(function(task, ret) { - Log(task.desc, ret ? "成功" : "失败") - }) - var arr = HedgeTable.split('('); - var tbl = { - type: 'table', - title: 'Runtime', - cols: ['Pair', 'Open', 'Cover', 'Hold', 'DiffA', 'DiffB', 'Time'], - rows: [] - }; - _.each(arr, function(item) { - if (item != '') { - var tmp = item.split(')'); - var pair = tmp[0].replace('(', '').split('&'); - var symbolDetail = _C(exchange.SetContractType, pair[0]) - Log("合约", symbolDetail.InstrumentName, "一手", symbolDetail.VolumeMultiple, "份, 最大下单量", symbolDetail.MaxLimitOrderVolume, "保证金率:", _N(symbolDetail.LongMarginRatio), _N(symbolDetail.ShortMarginRatio), "交割日期", symbolDetail.StartDelivDate); - symbolDetail = _C(exchange.SetContractType, pair[1]) - Log("合约", symbolDetail.InstrumentName, "一手", symbolDetail.VolumeMultiple, "份, 最大下单量", symbolDetail.MaxLimitOrderVolume, "保证金率:", _N(symbolDetail.LongMarginRatio), _N(symbolDetail.ShortMarginRatio), "交割日期", symbolDetail.StartDelivDate); - pairs.push(Hedge(q, exchanges[0], positions, pair[0], pair[1], tmp[1])) - } - }); - - var ts = 0 - var lastUpdate = 0 - while (true) { - if (!exchange.IO("status")) { - Sleep(1000) - continue - } - - var now = new Date().getTime() - if (now - ts > (CalcPeriod * 60000)) { - var account = exchange.GetAccount() - if (account) { - var obj = JSON.parse(exchange.GetRawJSON()) - $.PlotLine('账户权益', obj['Balance'] + obj['PositionProfit']); - ts = now - } - } - // IO("wait") 会一直等待收到任何一个品种的行情推送信息, 返回收到行情的真实时间 - var n = exchange.IO("wait") - // 计算行情信息传到策略层花费的时间 - var idle = UnixNano() - n - - if (now - lastUpdate > 5000) { - tbl.rows = [] - _.each(pairs, function(t) { - for (var i = 0; i < t.dic.length; i++) { - tbl.rows.push([t.name, t.dic[i].open, t.dic[i].cover, t.dic[i].hold, t.diffA, t.diffB, t.update]) - } - }); - LogStatus('`' + JSON.stringify(tbl) + '`\nUpdate: ' + _D() + ', Idle: ' + (idle/1000000) + ' ms') - lastUpdate = now - } - - _.each(pairs, function(t) { - t.poll() - }); - - q.poll() - } -} diff --git "a/10\350\241\214\344\272\272\345\223\201\347\255\226\347\225\245.js" "b/10\350\241\214\344\272\272\345\223\201\347\255\226\347\225\245.js" deleted file mode 100644 index 112a2e70..00000000 --- "a/10\350\241\214\344\272\272\345\223\201\347\255\226\347\225\245.js" +++ /dev/null @@ -1,25 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/14436 -策略名称: 10行人品策略 -策略作者: 春哥 -策略描述: - -赚不赚钱看人品 - - -参数 默认值 描述 --------- ----- ------- -Interval 300 轮询周期(秒) -*/ - -function main() { - while (true) { - Sleep(Interval * 1000); - if (Math.random() > 0.5) $.Buy(1000000); else { - $.Sell(1000000); - var a = $.GetAccount(); - if (a) LogProfit( a.Balance , 'CNY:', a.Balance, 'BTC:', a.Stocks); - } - } -} - diff --git "a/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.js" "b/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.md" similarity index 96% rename from "2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.js" rename to "2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.md" index 3899b51a..4d3cfea6 100644 --- "a/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.js" +++ "b/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/1088 -策略名称: 2014年的简易短线机器人 -策略作者: botvsing -策略描述: + +> 策略名称 + +2014年的简易短线机器人 + +> 策略作者 + +botvsing + +> 策略描述 **策略的介绍** @@ -100,15 +105,21 @@ function onTick() { 整个程序也就40多行,看上去十分简单,但当时也花了我一个多星期,这还是在botvs平台上情况下。最大的优势还是起步早,在2014年,市场上以搬砖为主,网格和抢盘口的高频也不多,使得策略如鱼得水,后来竞争不可避免越来越激烈,我的钱也越来越多,面临的挑战很多,每隔一段时间都要进行较大的改动来应对,但总体还算顺利。在交易平台不收取手续费的情况下,是程序化交易的天堂,散户因为不收手续费跟倾向于操作,为高频和套利提供了空间,这一切也基本随着动辄0.1-0.2%的双向手续费终结了,不仅是自己被收费的问题,而是整个市场活跃度下降。 但不需要高频的量化策略任然有很大的空间。 +> 策略参数 + -参数 默认值 描述 ---------------- ------ ---- -sleeptime 3500 休眠时间 -floatamountbuy 8 买单深度 -floatamountsell 8 卖单高度 -diffprice 1.5 套利差价 -*/ +|参数|默认值|描述| +|----|----|----| +|sleeptime|3500|休眠时间| +|floatamountbuy|8|买单深度| +|floatamountsell|8|卖单高度| +|diffprice|1.5|套利差价| + + +> 源码 (javascript) + +``` javascript /* 就是我刚开始编写机器人的源代码,几乎没有改动,参数也是原来的参数。这个版本的程序有许多 需要改进的地方,但即使如此,它也当时表现除了惊人的盈利能力,在我本金不多时,不加杠杆平 @@ -180,3 +191,12 @@ function main() { onTick(); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/1088 + +> 更新时间 + +2018-06-20 17:29:14 diff --git "a/30\350\241\214\350\265\214\345\276\222\347\255\226\347\225\245 (\345\201\232\347\251\272).md" "b/30\350\241\214\350\265\214\345\276\222\347\255\226\347\225\245 (\345\201\232\347\251\272).md" new file mode 100644 index 00000000..de4e9d78 --- /dev/null +++ "b/30\350\241\214\350\265\214\345\276\222\347\255\226\347\225\245 (\345\201\232\347\251\272).md" @@ -0,0 +1,65 @@ + +> 策略名称 + +30行赌徒策略 (做空) + +> 策略作者 + +小小梦 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|_StopWin|500|止盈| +|_StopLoss|500|止损| +|_FirstAmount|0.01|单次下单量| +|_MaxGear|8|加倍赌的次数| + + +> 源码 (javascript) + +``` javascript +var hold = {price : 0, amount : 0} +var _Gear = 0 +function main(){ + var initAccount = _C(exchange.GetAccount) + Log(initAccount, "#FF0000") + while(1){ + var ticker = _C(exchange.GetTicker) + if(hold.amount == 0){ + var firstInfo = $.Sell(_FirstAmount) + hold.amount = firstInfo.amount + hold.price = firstInfo.price + } else { + if(ticker.Buy < hold.price - _StopWin){ + var coverStopWinInfo = $.Buy(hold.amount) + hold.price = 0 + hold.amount = 0 + _Gear = 0 + } else if(ticker.Buy > hold.price + _StopLoss && _Gear < _MaxGear){ + $.Buy(hold.amount) + var amount = hold.amount * 2 + var addInfo = $.Sell(amount) + hold.price = addInfo.price + hold.amount = addInfo.amount + _Gear++ + } + } + LogStatus(_D(), "加倍下注次数:", _Gear, "\n", "当前持仓:", hold) + Sleep(500) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/113986 + +> 更新时间 + +2018-08-29 14:16:21 diff --git "a/30\350\241\214\350\265\214\345\276\222\347\255\226\347\225\245.md" "b/30\350\241\214\350\265\214\345\276\222\347\255\226\347\225\245.md" new file mode 100644 index 00000000..b90b0924 --- /dev/null +++ "b/30\350\241\214\350\265\214\345\276\222\347\255\226\347\225\245.md" @@ -0,0 +1,65 @@ + +> 策略名称 + +30行赌徒策略 + +> 策略作者 + +小小梦 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|_StopWin|500|止盈| +|_StopLoss|500|止损| +|_FirstAmount|0.01|单次下单量| +|_MaxGear|8|加倍赌的次数| + + +> 源码 (javascript) + +``` javascript +var hold = {price : 0, amount : 0} +var _Gear = 0 +function main(){ + var initAccount = _C(exchange.GetAccount) + Log(initAccount, "#FF0000") + while(1){ + var ticker = _C(exchange.GetTicker) + if(hold.amount == 0){ + var firstInfo = $.Buy(_FirstAmount) + hold.amount = firstInfo.amount + hold.price = firstInfo.price + } else { + if(ticker.Sell > hold.price + _StopWin){ + var coverStopWinInfo = $.Sell(hold.amount) + hold.price = 0 + hold.amount = 0 + _Gear = 0 + } else if(ticker.Sell < hold.price - _StopLoss && _Gear < _MaxGear){ + $.Sell(hold.amount) + var amount = hold.amount * 2 + var addInfo = $.Buy(amount) + hold.price = addInfo.price + hold.amount = addInfo.amount + _Gear++ + } + } + LogStatus(_D(), "加倍下注次数:", _Gear, "\n", "当前持仓:", hold) + Sleep(500) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/113796 + +> 更新时间 + +2018-08-31 10:43:45 diff --git "a/50\350\241\214\345\244\232\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" "b/50\350\241\214\345\244\232\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" new file mode 100644 index 00000000..ae455cae --- /dev/null +++ "b/50\350\241\214\345\244\232\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" @@ -0,0 +1,87 @@ + +> 策略名称 + +50行多平台对冲策略(教学) + +> 策略作者 + +小小梦 + +> 策略描述 + +教学策略 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|_HedgePrice|10|对冲差价| +|_HedgeAmount|0.02|对冲量| +|_CurrencyPrecision|2|下单量精度| +|_BaseCurrencyPrecision|2|下单价格精度| + + +> 源码 (javascript) + +``` javascript +var preSumBalance = 0 +var initSumBalance = 0 +function UpdateAccount(isFirst){ + var msg = "" + var sumStocks = 0 + var sumBalance = 0 + for(var i = 0; i < exchanges.length; i++){ + if(exchanges[i].needUpdate == true || isFirst == true){ + exchanges[i].account = _C(exchanges[i].GetAccount) + exchanges[i].needUpdate = false + if(isFirst == true){ + initSumBalance += (exchanges[i].account.Balance + exchanges[i].account.FrozenBalance) + exchanges[i].SetPrecision(_CurrencyPrecision, _BaseCurrencyPrecision) + } + } + sumStocks += (exchanges[i].account.Stocks + exchanges[i].account.FrozenStocks) + sumBalance += (exchanges[i].account.Balance + exchanges[i].account.FrozenBalance) + msg += exchanges[i].GetName() + "币:" + exchanges[i].account.Stocks + "冻币:" + exchanges[i].account.FrozenStocks + "钱:" + exchanges[i].account.Balance + "冻钱:" + exchanges[i].account.FrozenBalance + "\n" + } + LogStatus(_D(), "总币:" + sumStocks, "总钱:" + sumBalance, "\n", msg) + if(preSumBalance != sumBalance){ + LogProfit(sumBalance - initSumBalance, preSumBalance = sumBalance) + } +} +function main(){ + UpdateAccount(true) + while(1){ + for(var i = 0; i < exchanges.length; i++){ + for(var j = 0; j < exchanges.length; j++){ + if(i == 0 && j == 0){ + for(var m = 0; m < exchanges.length; m++){ + exchanges[m].thread = exchanges[m].Go("GetTicker") + } + for(var n = 0; n < exchanges.length; n++){ + exchanges[n].ticker = exchanges[n].thread.wait() + } + } + if(exchanges[i].GetName() != exchanges[j].GetName() && exchanges[i].ticker && exchanges[j].ticker && exchanges[i].ticker.Buy - exchanges[j].ticker.Sell > _HedgePrice){ + if(exchanges[i].account.Stocks > _HedgeAmount && exchanges[j].account.Balance / ((exchanges[i].ticker.Buy + exchanges[j].ticker.Sell) / 2) > _HedgeAmount){ + var sellId_I = exchanges[i].Sell((exchanges[i].ticker.Buy + exchanges[j].ticker.Sell) / 2, _HedgeAmount, exchanges[i].GetName()) + var buyId_J = exchanges[j].Buy((exchanges[i].ticker.Buy + exchanges[j].ticker.Sell) / 2, _HedgeAmount, exchanges[i].GetName()) + exchanges[i].needUpdate = exchanges[j].needUpdate = true + } + } + } + } + UpdateAccount(false) + Sleep(300) // 测试 + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/113278 + +> 更新时间 + +2018-08-25 16:44:16 diff --git "a/50\350\241\214\347\275\221\346\240\274\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" "b/50\350\241\214\347\275\221\346\240\274\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" new file mode 100644 index 00000000..f0ee3f0d --- /dev/null +++ "b/50\350\241\214\347\275\221\346\240\274\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" @@ -0,0 +1,86 @@ + +> 策略名称 + +50行网格策略(教学) + +> 策略作者 + +小小梦 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|direction|true|网格方向| +|_GridNum|10|网格节点数量| +|_GridPointAmount|0.1|网格节点下单量| +|_GridPointDis|20|网格节点间距| +|_GridCovDis|50|网格节点平仓差价| + + +> 源码 (javascript) + +``` javascript +var _StopLoss = 0 +var _StopWin = 0 +var _Grid = [] + +function UpdateGrid(nowBidsPrice, nowAsksPrice, direction){ // up 1, down -1 + if(_Grid.length == 0 || (direction == 1 && nowBidsPrice - _Grid[_Grid.length - 1].price > _GridPointDis) || + (direction == -1 && _Grid[_Grid.length - 1].price - nowAsksPrice > _GridPointDis)){ + + var nowPrice = direction == 1 ? nowBidsPrice : nowAsksPrice + _Grid.push({ + price: _Grid.length == 0 ? nowPrice : _Grid[_Grid.length - 1].price + _GridPointDis * direction, + hold : {price: 0, amount: 0}, + coverPrice : _Grid.length == 0 ? nowPrice - direction * _GridCovDis : _Grid[_Grid.length - 1].price + _GridPointDis * direction - direction * _GridCovDis + }) + + var tradeInfo = direction == 1 ? $.Sell(_GridPointAmount) : $.Buy(_GridPointAmount) + _Grid[_Grid.length - 1].hold.price = tradeInfo.price + _Grid[_Grid.length - 1].hold.amount = tradeInfo.amount + $.PlotFlag(new Date().getTime(), JSON.stringify(tradeInfo), "O") + } + if(_Grid.length > 0 && + ((direction == 1 && nowAsksPrice < _Grid[_Grid.length - 1].coverPrice) || (direction == -1 && nowBidsPrice > _Grid[_Grid.length - 1].coverPrice))){ + + var coverInfo = direction == 1 ? $.Buy(_Grid[_Grid.length - 1].hold.amount) : $.Sell(_Grid[_Grid.length - 1].hold.amount) + _Grid.pop() + $.PlotFlag(new Date().getTime(), JSON.stringify(coverInfo), "C") + _StopWin++ + } else if(_Grid.length > _GridNum){ + var coverfirstInfo = direction == 1 ? $.Buy(_Grid[0].hold.amount) : $.Sell(_Grid[0].hold.amount) + _Grid.shift() + $.PlotFlag(new Date().getTime(), JSON.stringify(coverfirstInfo), "C") + _StopLoss++ + } + +} + +function main(){ + while(1){ + var ticker = _C(exchange.GetTicker) + var records = _C(exchange.GetRecords) + $.PlotRecords(records, "kline") + UpdateGrid(ticker.Buy, ticker.Sell, direction) + var msg = "" + for(var i = 0; i < _Grid.length; i++){ + msg += JSON.stringify(_Grid[i]) + "\n" + } + LogStatus(_D(), "_StopWin:", _StopWin, "_StopLoss:", _StopLoss, _C(exchange.GetAccount), "\n", "_Grid.length:", _Grid.length, "_GridNum:", _GridNum, "\n", msg) + Sleep(500) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/113144 + +> 更新时间 + +2018-08-25 18:19:22 diff --git "a/796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.js" "b/796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.md" similarity index 93% rename from "796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.js" rename to "796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.md" index 3b87d901..66d2a991 100644 --- "a/796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.js" +++ "b/796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.md" @@ -1,30 +1,41 @@ -/* -策略出处: https://www.fmz.com/strategy/3648 -策略名称: 796期货反手加倍算法 -策略作者: Zero -策略描述: + +> 策略名称 + +796期货反手加倍算法 + +> 策略作者 + +Zero + +> 策略描述 796期货反手加倍算法, 先开空或多, 也可以指定失败了继续上次方向, 如果失败了就按指定倍数加仓, 策略有风险, 仅限学习使用. +> 策略参数 + + -参数 默认值 描述 ------------ ----- ----------- -MarginIdx 0 杠杆大小: 10|20 -OpType 0 开仓方向: 做多|做空 -OpAmount 0.1 开仓数量 -OpMode 0 开仓方式: 吃单|挂单 -MaxSpace 0.5 挂单失效距离 -SlidePrice 0.1 下单滑动价(元) -StopProfit 0.2 止赢(百分比) -StopLoss 0.1 止损(百分比) -ReverseRate 2 反手加仓倍数 -MaxLoss 10 最多反手次数 -ReverseMode 0 反手模式: 反仓|顺仓 -SaveLocal false 保存本地日志 -Interval true 轮询间隔(秒) -*/ +|参数|默认值|描述| +|----|----|----| +|MarginIdx|0|杠杆大小: 10|20| +|OpType|0|开仓方向: 做多|做空| +|OpAmount|0.1|开仓数量| +|OpMode|0|开仓方式: 吃单|挂单| +|MaxSpace|0.5|挂单失效距离| +|SlidePrice|0.1|下单滑动价(元)| +|StopProfit|0.2|止赢(百分比)| +|StopLoss|0.1|止损(百分比)| +|ReverseRate|2|反手加仓倍数| +|MaxLoss|10|最多反手次数| +|ReverseMode|0|反手模式: 反仓|顺仓| +|SaveLocal|false|保存本地日志| +|Interval|true|轮询间隔(秒)| +> 源码 (javascript) + +``` javascript + var MarginLevel = [10,20][MarginIdx]; var FirstTradeType = [ORDER_TYPE_BUY, ORDER_TYPE_SELL][OpType]; var OrgAccount = null; @@ -367,3 +378,12 @@ function main() { Sleep(Interval); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/3648 + +> 更新时间 + +2015-02-04 13:49:31 diff --git "a/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.js" "b/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.js" deleted file mode 100644 index 2f29c36a..00000000 --- "a/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.js" +++ /dev/null @@ -1,27 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/4 -策略名称: API 测试新手入门 -策略作者: Zero -策略描述: - -新手入门学习模板 - - -参数 默认值 描述 ---------- ----- ------------- -message Hello 回显的信息 -running true 布尔值 -maxNumber 111 回显数字 -ListIdx 0 下拉框: 第一|第二|第三 -cond 123 条件显示1 -*/ - -function main() { - Log(exchange.GetAccount()); - Log(message, running, maxNumber); - Log('ListIdx :', ListIdx); - LogProfit(100.3); - Log("这是红色字体颜色", "#ff0000"); - Log("我是带背景色的", "#ffffff223344"); - LogProfit(90, "我也带背景色", "#ffffff0000ff"); -} diff --git "a/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.md" "b/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.md" new file mode 100644 index 00000000..5c52f724 --- /dev/null +++ "b/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.md" @@ -0,0 +1,47 @@ + +> 策略名称 + +API 测试新手入门 + +> 策略作者 + +Zero + +> 策略描述 + +新手入门学习模板 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|message|Hello|回显的信息| +|running|true|布尔值| +|maxNumber|111|回显数字| +|ListIdx|0|下拉框: 第一|第二|第三| +|cond|123|条件显示1| + + +> 源码 (javascript) + +``` javascript +function main() { + Log(exchange.GetAccount()); + Log(message, running, maxNumber); + Log('ListIdx :', ListIdx); + LogProfit(100.3); + Log("这是红色字体颜色", "#ff0000"); + Log("我是带背景色的", "#ffffff223344"); + LogProfit(90, "我也带背景色", "#ffffff0000ff"); +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/4 + +> 更新时间 + +2017-02-28 10:14:17 diff --git "a/BTC-LTC \345\234\260\345\235\200\347\233\221\350\247\206, \347\237\255\344\277\241\351\200\232\347\237\245.js" "b/BTC-LTC \345\234\260\345\235\200\347\233\221\350\247\206, \347\237\255\344\277\241\351\200\232\347\237\245.md" similarity index 71% rename from "BTC-LTC \345\234\260\345\235\200\347\233\221\350\247\206, \347\237\255\344\277\241\351\200\232\347\237\245.js" rename to "BTC-LTC \345\234\260\345\235\200\347\233\221\350\247\206, \347\237\255\344\277\241\351\200\232\347\237\245.md" index 2e7366a4..65cab246 100644 --- "a/BTC-LTC \345\234\260\345\235\200\347\233\221\350\247\206, \347\237\255\344\277\241\351\200\232\347\237\245.js" +++ "b/BTC-LTC \345\234\260\345\235\200\347\233\221\350\247\206, \347\237\255\344\277\241\351\200\232\347\237\245.md" @@ -1,23 +1,34 @@ -/* -策略出处: https://www.fmz.com/strategy/1295 -策略名称: BTC-LTC 地址监视, 短信通知 -策略作者: Zero -策略描述: + +> 策略名称 + +BTC-LTC 地址监视, 短信通知 + +> 策略作者 + +Zero + +> 策略描述 有新的交易, 立即提醒 +> 策略参数 + + -参数 默认值 描述 ---------- ---------------------------------- ----------- -Type 0 类型: BTC|LTC -Addr 1LuckyY9fRzcJre7aou7ZhWVXktxjjBb9S 地址 -Interval 3 轮询间隔 -EnableSMS false 启动短信通知 -SMSUser *** 短信宝用户名 -SMSPass *** 短信宝MD5密码 -PhoneNum 1111 接收短信手机号 -*/ +|参数|默认值|描述| +|----|----|----| +|Type|0|类型: BTC|LTC| +|Addr|1LuckyY9fRzcJre7aou7ZhWVXktxjjBb9S|地址| +|Interval|3|轮询间隔| +|EnableSMS|false|启动短信通知| +|SMSUser|***|短信宝用户名| +|SMSPass|***|短信宝MD5密码| +|PhoneNum|1111|接收短信手机号| + +> 源码 (javascript) + +``` javascript var LastMsg = ""; function SMSSend(msg) { if (msg == LastMsg) { @@ -71,3 +82,12 @@ function main() { Sleep(Interval*1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/1295 + +> 更新时间 + +2014-11-07 19:41:42 diff --git "a/BTC-V\345\217\215\347\255\226\347\225\245.md" "b/BTC-V\345\217\215\347\255\226\347\225\245.md" new file mode 100644 index 00000000..eaddfe6f --- /dev/null +++ "b/BTC-V\345\217\215\347\255\226\347\225\245.md" @@ -0,0 +1,179 @@ + +> 策略名称 + +BTC-V反策略 + +> 策略作者 + +ztjeff + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|password|'test888'|口令| + + + + +|按钮|默认值|描述| +|----|----|----| +|recv|true|结束程序| + + +> 源码 (python) + +``` python +# encoding: utf-8 + +import os +from time import time, sleep +from threading import Thread +from socket import socket, AF_INET, SOCK_DGRAM, gethostname, timeout, error + +prct = 0.1 +password = 'test888' +req = {} +pos = {} +recv = True +data = '' +n=60 #减数触发器,减到零触发 + +def trade(req): + """测试交易""" + for symbol, mpos in req.items(): + if symbol not in pos.keys(): + pos[symbol] = 0.0 + targetPos=round(mpos*prct, 4) + Log('targetPos =', targetPos) + if targetPos == pos[symbol]: + #Log("No Trade Operation! client Pos %s is %.3f" % (symbol, pos[symbol])) + continue + tick = exchange.GetTicker(); + if targetPos > pos[symbol]: + vol = round(targetPos-pos[symbol], 4) + type = 'buy-market' + #Log(' Buy btcusdt', vol) + id = exchange.Buy(tick.Sell+10, vol) + #Log(' Buy btcusdt at %s = %s' %(tick.Sell, vol)) + Log("Order id:", id); + elif targetPos < pos[symbol]: + vol = round(pos[symbol]-targetPos, 4) + type = 'sell-market' + #Log(' Sell btcusdt', vol) + id = exchange.Sell(-1, vol) + #Log(' Sell btcusdt at %s = %s' %(tick.Buy, vol)) + Log("Order id:", id); + + account = exchange.GetAccount() + Log("账户信息,Balance:", account.Balance, "FrozenBalance:", account.FrozenBalance, "Stocks:", + account.Stocks, "FrozenStocks:", account.FrozenStocks) + pos[symbol] = round(account.Stocks, 4) + Log('Now Client %s POS = %s' % (symbol, pos[symbol])) + +class recServer(object): + """recServer is receving Signal from SigServer""" + def __init__(self, c): + self.rcv = True + self.t = Thread(target = self.recSig, args = (c,)) + self.t.start() + + def recSig(self, c): + while self.rcv: + try: + data, addr = c.recvfrom(1024) + #Log('n=',n) + except timeout: + continue + except error: + msg = traceback.format_exc() + Log(msg) + continue + if data == 'ok': + #Log('SigServer is alive! Receving "ok" from', addr) + pass + elif 'send password' in data: + Log('The client not login, press any key to exit and restart!') + self.rcv = False + elif not data: + Log("SigServer is stopped, press any Key to exit SigClient!") + self.rcv = False + else: + try: + c.sendto('ack', addr) + Log('send ack to ', addr) + except error: + Log('Send ack error!') + + req = eval(data) + Log(req, 'from', addr) + trade(req) + else: + Log('RecSig Thread is Exiting...') + return None + + def heart(self, c, ADDR): + try: + c.sendto('live', ADDR) + except error: + Log('Send keepAlive error!') + return None + + def close(self): + self.rcv = False + self.t.join() + +def main(): + account = exchange.GetAccount() + Log("账户信息,Balance:", account.Balance, "FrozenBalance:", account.FrozenBalance, "Stocks:", + account.Stocks, "FrozenStocks:", account.FrozenStocks) + pos['btcusdt'] = round(account.Stocks, 4) + Log(pos) + # 启动UDP客户端 + c = socket(AF_INET, SOCK_DGRAM) + host = '47.98.130.139' + port = 1234 + ADDR = (host, port) + c.settimeout(5) + try: + c.sendto(password, ADDR) + data, addr = c.recvfrom(256) + Log(data+' from ', addr) + except timeout, error: + Log('SigServer is not active, client is aborting!') + c.close() + return None + if 'invalid' in data: + Log('\nYou failed to Login! SigClient is Exiting...') + c.close() + return None + + # 如果密码正确,开启接收信号模式 + rc = recServer(c) + sleep(1) + global n + while recv: + n -= 1 + if not n: + rc.heart(c, ADDR) + account = exchange.GetAccount() + pos['btcusdt'] = round(account.Stocks, 4) + #Log(pos) + n = 60 + sleep(1) + else: + rc.close() + Log('Program is End!') +``` + +> 策略出处 + +https://www.fmz.com/strategy/117202 + +> 更新时间 + +2018-09-27 21:45:01 diff --git "a/Binance buy and sell statistics|\345\270\201\345\256\211\344\271\260\345\215\226\347\273\237\350\256\241.md" "b/Binance buy and sell statistics|\345\270\201\345\256\211\344\271\260\345\215\226\347\273\237\350\256\241.md" new file mode 100644 index 00000000..2151fb4d --- /dev/null +++ "b/Binance buy and sell statistics|\345\270\201\345\256\211\344\271\260\345\215\226\347\273\237\350\256\241.md" @@ -0,0 +1,70 @@ + +> 策略名称 + +Binance buy and sell statistics|币安买卖统计 + +> 策略作者 + +botvsing + +> 策略描述 + +记录主动成交数据 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Interval|600|Log interval(second)| +|Pair|btcusdt|trading pair| + + +> 源码 (javascript) + +``` javascript +var tradeHistory = {buyData:{amount:0, money:0}, sellData:{amount:0, money:0}} +if(_G('tradeHistory')){ + tradeHistory = _G('tradeHistory') +} +function onexit(){ + Log('exit,saving data...') + _G('tradeHistory', tradeHistory) +} +function main(){ + var client = Dial("wss://stream.binance.com:9443/ws/" + Pair.toLowerCase() + "@trade", 60) + var updateTime = new Date().getTime() + while(true){ + var trade = JSON.parse(client.read()) + if(trade.m){ + tradeHistory.sellData.amount += parseFloat(trade.q) + tradeHistory.sellData.money += parseFloat(trade.q) * parseFloat(trade.p) + }else{ + tradeHistory.buyData.amount += parseFloat(trade.q) + tradeHistory.buyData.money += parseFloat(trade.q) * parseFloat(trade.p) + } + var buyNet = _N(tradeHistory.buyData.money - tradeHistory.sellData.money, 3) + logSting = 'active buy amount:' + _N(tradeHistory.buyData.amount, 3) + ' total money: ' + _N(tradeHistory.buyData.money, 3) + '\n' + logSting += 'active sell amount:' + _N(tradeHistory.sellData.amount, 3) + ' total money: ' + _N(tradeHistory.sellData.money, 3) + '\n' + logSting += 'Net inflow of funds: ' + _N(tradeHistory.buyData.money - tradeHistory.sellData.money, 3) + LogStatus(logSting) + if(new Date().getTime() - updateTime > Interval*1000){ + updateTime = new Date().getTime() + LogProfit(buyNet) + $.PlotLine('buyNet', buyNet) + $.PlotLine('buy', _N(tradeHistory.buyData.money,3)) + $.PlotLine('sell', _N(tradeHistory.sellData.money,3)) + Log(logSting) + } + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/121917 + +> 更新时间 + +2018-10-27 16:01:47 diff --git "a/BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.js" "b/BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.md" similarity index 73% rename from "BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.js" rename to "BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.md" index 81d98300..4133613d 100644 --- "a/BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.js" +++ "b/BitMEX \347\256\200\345\215\225\346\265\213\350\257\225.md" @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/40289 -策略名称: BitMEX 简单测试 -策略作者: Tony123 -策略描述: + +> 策略名称 + +BitMEX 简单测试 + +> 策略作者 + +发明者量化 + +> 策略描述 现已接入BitMEX, 支持全平台API, 支持IO扩展. -*/ + +> 源码 (javascript) + +``` javascript // 只支持实盘 function main() { exchange.SetContractType("XBTUSD") @@ -27,3 +35,12 @@ function main() { } Log(_C(exchange.GetPosition)) } +``` + +> 策略出处 + +https://www.fmz.com/strategy/40289 + +> 更新时间 + +2017-05-08 17:20:34 diff --git "a/BitMEX \351\253\230\347\272\247API\345\212\237\350\203\275 (\346\234\237\350\264\247:\346\211\271\351\207\217\344\270\213\345\215\225,\344\270\200\351\224\256\346\222\244\345\215\225) JavaScript.md" "b/BitMEX \351\253\230\347\272\247API\345\212\237\350\203\275 (\346\234\237\350\264\247:\346\211\271\351\207\217\344\270\213\345\215\225,\344\270\200\351\224\256\346\222\244\345\215\225) JavaScript.md" new file mode 100644 index 00000000..9c44ec98 --- /dev/null +++ "b/BitMEX \351\253\230\347\272\247API\345\212\237\350\203\275 (\346\234\237\350\264\247:\346\211\271\351\207\217\344\270\213\345\215\225,\344\270\200\351\224\256\346\222\244\345\215\225) JavaScript.md" @@ -0,0 +1,75 @@ + +> 策略名称 + +BitMEX 高级API功能 (期货:批量下单,一键撤单) JavaScript + +> 策略作者 + +FawkesPan + + + + + +> 源码 (javascript) + +``` javascript +/* + + BitMEX Advanced API Interface for FMZ.com. + + Copyright 2018 FawkesPan + Contact : i@fawkex.me / Telegram@FawkesPan + + GNU General Public License v3.0 + +*/ + +function main() { + Log(exchange.GetAccount()); +} +var bulk = [] +// 添加批量买单 +function BulkBuy(symbol,qty,price,type,exec) { + Log("新的Bulk订单 开多 "+ symbol + " " + price + " " + qty) + var order = {}; + order.symbol = symbol; + order.side = "Buy"; + order.orderQty = qty; + order.price = price; + order.ordType = type; + order.execInst = exec; + bulk[Object.keys(bulk).length] = order; +} +// 添加批量卖单 +function BulkSell(symbol,qty,price,type,exec) { + Log("新的Bulk订单 开空 "+ symbol + " " + price + " " + qty) + var order = {}; + order.symbol = symbol; + order.side = "Sell"; + order.orderQty = qty; + order.price = price; + order.ordType = type; + order.execInst = exec; + bulk[Object.keys(bulk).length] = order; +} +//执行批量订单 +function BulkPost() { + Log("正在执行Bulk订单 共计 " + Object.keys(bulk).length + " 个订单"); + var param = "orders=" + JSON.stringify(bulk); + bulk = []; + exchange.IO("api", "POST", "/api/v1/order/bulk", param); +} +//取消所有订单 +function CancelPendingOrders() { + exchange.IO("api","DELETE","/api/v1/order/all","symbol="+exchange.GetCurrency()); +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/105056 + +> 更新时间 + +2018-08-30 03:01:43 diff --git "a/BitMEX \351\253\230\347\272\247API\345\212\237\350\203\275 V.1.1.0 (\346\234\237\350\264\247:\346\211\271\351\207\217\344\270\213\345\215\225,\347\274\226\350\276\221\350\256\242\345\215\225,\345\206\260\345\261\261\350\256\242\345\215\225,\344\270\200\351\224\256\346\222\244\345\215\225,\345\256\232\346\227\266\346\222\244\345\215\225) Python2-3.md" "b/BitMEX \351\253\230\347\272\247API\345\212\237\350\203\275 V.1.1.0 (\346\234\237\350\264\247:\346\211\271\351\207\217\344\270\213\345\215\225,\347\274\226\350\276\221\350\256\242\345\215\225,\345\206\260\345\261\261\350\256\242\345\215\225,\344\270\200\351\224\256\346\222\244\345\215\225,\345\256\232\346\227\266\346\222\244\345\215\225) Python2-3.md" new file mode 100644 index 00000000..ec83672a --- /dev/null +++ "b/BitMEX \351\253\230\347\272\247API\345\212\237\350\203\275 V.1.1.0 (\346\234\237\350\264\247:\346\211\271\351\207\217\344\270\213\345\215\225,\347\274\226\350\276\221\350\256\242\345\215\225,\345\206\260\345\261\261\350\256\242\345\215\225,\344\270\200\351\224\256\346\222\244\345\215\225,\345\256\232\346\227\266\346\222\244\345\215\225) Python2-3.md" @@ -0,0 +1,443 @@ + +> 策略名称 + +BitMEX 高级API功能 V.1.1.0 (期货:批量下单,编辑订单,冰山订单,一键撤单,定时撤单) Python2-3 + +> 策略作者 + +FawkesPan + +> 策略描述 + +# BitMEX 高级API功能 (FMZ.com) + +### 初始化 +这个库整合了一些高级的 BitMEX API 功能,使用前需要进行初始化。 +``` +# 单个交易所 +BitMEX = ext.BitMEXPlus(exchange) # 创建一个新的接口对象 +# 多个交易所 +BitMEX = ext.BitMEXPlus(exchanges[0]) # exchanges[这里取决于你的交易所添加在第几个] +``` + +### 订单操作 +#### 批量订单 +##### BulkAdd() 添加新订单到本地订单列表 +``` +side price amount 为必填参数 +symbol 不填则使用默认交易对设置 +displayQty 用于冰山订单功能 设置订单显示部分大小 设置为0则完全隐藏 +orderType execInst 可选参数请看源码内备注 +BitMEX.BulkAdd(side=string, price=float, amount=integer, symbol=string, displayQty=integer, ordType='Limit', clOrdID='', execInst='') +``` +##### BulkClear() 清除本地未提交订单 +``` +symbol 指定后可清除指定交易对订单 如不指定则清除所有订单 +notify 是否显示日志 默认为显示 +BitMEX.BulkClear(symbol=string, notify=True) +``` +##### BulkPost() 提交本地未提交订单 +``` +symbol 指定后只提交指定交易对订单 不指定则提交所有订单 +BitMEX.BulkPost(symbol=string) +``` +##### BulkOrders() 查看本地所有未提交订单 +``` +BitMEX.BulkOrders() +``` +#### 取消订单 +##### CancelAllOrders() 取消当前的未完成订单 +``` +symbol 指定后只取消指定交易对订单 不指定则取消所有订单 +filter 自定义订单过滤 只取消符合条件的订单 如 filter={'side': 'Buy'} 取消所有买单 +BitMEX.CancelAllOrders(symbol=string, filter=dict) +``` +##### CancelAllAfter() 在一定时间后取消所有未完成订单 +再次请求可以重置计数器 +``` +timeout 指定在多少毫秒后取消订单 填0可以删除计数器 +BitMEX.CancelAllAfter(timeout=integer) +``` +#### 编辑订单 +##### Amend() 修改一个订单 +``` +symbol 指定交易对 不指定交易对则使用默认交易对 +orderID clOrdID 订单ID和用户自定义订单ID 至少指定其中一项 两项都填则只使用orderID +price amount 订单的新价格和订单的新数量 至少修改其中一项 可以同时修改两项 +BitMEX.Amend(symbol=string, orderID=string, clOrdID=string, price=float, amount=integer) +``` +#### 批量编辑订单 +##### AmendAdd() 添加一个需要修改的订单到本地待修改订单列表 +``` +symbol 指定交易对 不指定交易对则使用默认交易对 +orderID clOrdID 订单ID和用户自定义订单ID 至少指定其中一项 两项都填则只使用orderID +price amount 订单的新价格和订单的新数量 至少修改其中一项 可以同时修改两项 +BitMEX.AmendAdd(symbol=string, orderID=string, clOrdID=string, price=float, amount=integer) +``` +##### AmendClear() 清除本地未提交的待修改订单 +``` +symbol 指定后可清除指定交易对订单 如不指定则清除所有订单 +notify 是否显示日志 默认为显示 +BitMEX.AmendClear(symbol=string, notify=True) +``` +##### AmendPost() 提交本地未提交的待修改订单 +``` +symbol 指定后提交指定交易对订单修改请求 不指定则提交默认交易对订单的修改请求 +BitMEX.AmendPost(symbol=string) +``` +##### AmendOrders() 查看本地所有未提交订单 +``` +BitMEX.AmendOrders() +``` + +### 与我联系 +邮箱 i@fawkex.me +电报 [FawkesPan](https://telegram.me/FawkesPan) + +接受策略定制 + +### 关于这个库 +[BitMEX API文档](https://www.bitmex.com/app/apiOverview) + +[使用 GNU General Public License v3](https://www.gnu.org/licenses/gpl-3.0.en.html) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|LANG|ZH|语言 / Language| + + +> 源码 (python) + +``` python + + +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# encoding: utf-8 +# +# BitMEX Advanced API Interface for FMZ.com. +# +# Copyright 2018 FawkesPan +# Contact : i@fawkex.me / Telegram@FawkesPan +# +# GNU General Public License v3.0 +# + +import json +import math +import decimal + +def toNearest(num, tickSize): + tickDec = decimal.Decimal(str(tickSize)) + return float((decimal.Decimal(round(num / tickSize, 0)) * tickDec)) + +QUOTES = {} +QUOTES['ZH'] = { + 'GREET' : '[BitMEX 接口已初始化] 合约: %s. %s', + 'INITF' : '使用的交易所不正确,当前交易所: %s', + 'PARAMERR' : '***传的参数不对 检查你的代码*** %s', + 'NEWORDER' : '[添加订单] 合约: %s 方向: %s 价格: %.8f 数量: %d 张. %s', + 'MODORDER' : '[修改订单] orderID/clOrdID: %s 新价格: %.8f 新数量: %d. %s', + 'MODORDERP' : '[修改订单] orderID/clOrdID: %s 新价格: %.8f. %s', + 'MODORDERA' : '[修改订单] orderID/clOrdID: %s 新数量: %d. %s', + 'ORDCOUNT' : '[本次批量发送订单] 总计: %d 条. %s', + 'THISBATCH' : '[信息] 正在处理 合约: %s 条数: %d. %s', + 'CLEARALL' : '[信息] 已清除所有本地订单. %s', + 'CLEAR' : '[信息] 已清除所有 %s 本地订单. %s', + 'CA' : '[订单计划取消] 所有订单都将在 %d 毫秒 后取消. %s' +} + +COLORS = { + 'DEEPBLUE' : '#1F618D', + 'BLUE' : '#0000FF', + 'LIGHTBLUE' : '#5DADE2', + 'DEEPGREEN' : '#27AE60', + 'GREEN' : '#00FF00', + 'LIGHTGREEN' : '#58D68D', + 'LAPIS' : '#26619C', + 'DEEPRED' : '#CB4335', + 'RED' : '#FF0000', + 'LIGHTRED' : '#EC7063' +} + + +class BitMEX: + + def __init__(self, exchange): + self.QUOTES = {} + exchange.GetCurrency() + if isinstance(exchange.GetCurrency(), bytes): + self.symbol = str(exchange.GetCurrency(), "utf-8").lower() + name = str(exchange.GetName(), "utf-8") + else: + self.symbol = exchange.GetCurrency() + name = exchange.GetName() + self.IO = exchange.IO + self.bulks = [] + self.amends = [] + if 'BitMEX' in str(name): + Log(QUOTES[LANG]['GREET'] % (self.symbol.upper(),COLORS['LAPIS'])) + else: + Log(QUOTES[LANG]['INITF'] % (name)) + + def BulkAdd(self, side=None, price=None, amount=None, symbol=None, ordType='Limit', displayQty=None, clOrdID=None, execInst=None): + if type is None or price is None or amount is None: + Log(QUOTES[LANG]['PARAMERR'] % (COLORS['RED'])) + return False + side = side.lower() + if 'sell' in side: + side = 'Sell' + cl = COLORS['DEEPRED'] + else: + side = 'Buy' + cl = COLORS['DEEPGREEN'] + if symbol is None: + symbol = self.symbol + + # Order structure + order = {} + order['symbol'] = symbol.upper() # Symbol + order['price'] = price # Price + order['side'] = side # Buy/Sell + order['orderQty'] = int(amount) # Amount + + # Valid order types + # Market, Limit, Stop, StopLimit, MarketIfTouched, LimitIfTouched, MarketWithLeftOverAsLimit, Pegged + # Limit: The default order type. Specify an orderQty and price. + # Market: A traditional Market order. A Market order will execute until filled or your bankruptcy price is reached, at which point it will cancel. + # MarketWithLeftOverAsLimit: A market order that, after eating through the order book as far as permitted by available margin, will become a limit order. The difference between this type and Market only affects the behavior in thin books. Upon reaching the deepest possible price, if there is quantity left over, a Market order will cancel the remaining quantity. MarketWithLeftOverAsLimit will keep the remaining quantity in the books as a Limit. + # Stop: A Stop Market order. Specify an orderQty and stopPx. When the stopPx is reached, the order will be entered into the book. + ## On sell orders, the order will trigger if the triggering price is lower than the stopPx. On buys, higher. + ## Note: Stop orders do not consume margin until triggered. Be sure that the required margin is available in your account so that it may trigger fully. + ## Close Stops don't require an orderQty. See Execution Instructions below. + # StopLimit: Like a Stop Market, but enters a Limit order instead of a Market order. Specify an orderQty, stopPx, and price. + # MarketIfTouched: Similar to a Stop, but triggers are done in the opposite direction. Useful for Take Profit orders. + # LimitIfTouched: As above; use for Take Profit Limit orders. + order['ordType'] = ordType + # If you want to keep track of order IDs yourself, set a unique clOrdID per order. This clOrdID will come back as a property on the order and any related executions (including on the WebSocket), and can be used to get or cancel the order. Max length is 36 characters. + if clOrdID is not None: + order['clOrdID'] = clOrdID + # The following execInsts are supported. If using multiple, separate with a comma (e.g. LastPrice,Close). + # ParticipateDoNotInitiate, MarkPrice, LastPrice, IndexPrice, ReduceOnly, Close + # ParticipateDoNotInitiate: Also known as a Post-Only order. If this order would have executed on placement, it will cancel instead. + # MarkPrice, LastPrice, IndexPrice: Used by stop and if-touched orders to determine the triggering price. Use only one. By default, 'MarkPrice' is used. Also used for Pegged orders to define the value of 'LastPeg'. + # ReduceOnly: A 'ReduceOnly' order can only reduce your position, not increase it. If you have a 'ReduceOnly' limit order that rests in the order book while the position is reduced by other orders, then its order quantity will be amended down or canceled. If there are multiple 'ReduceOnly' orders the least aggressive will be amended first. + # Close: 'Close' implies 'ReduceOnly'. A 'Close' order will cancel other active limit orders with the same side and symbol if the open quantity exceeds the current position. This is useful for stops: by canceling these orders, a 'Close' Stop is ensured to have the margin required to execute, and can only execute up to the full size of your position. If orderQty is not specified, a 'Close' order has an orderQty equal to your current position's size. + ## Note that a Close order without an orderQty requires a side, so that BitMEX knows if it should trigger above or below the stopPx. + if execInst is not None: + order['execInst'] = execInst + if 'Close' in execInst: + del order['orderQty'] + # Optional quantity to display in the book. Use 0 for a fully hidden order. (Iceberg Order) + if displayQty is not None: + order['displayQty'] = displayQty + + self.bulks.append(order) + + Log(QUOTES[LANG]['NEWORDER'] % (symbol.upper(),side.upper(),price,amount,cl)) + + return True + + def BulkClear(self, symbol=None, notify=True): + ret = [] + if symbol is None: + ret = self.bulks + self.bulks = [] + if notify: + Log(QUOTES[LANG]['CLEARALL'] % (COLORS['RED'])) + else: + new = [] + for i in self.bulks: + if i['symbol'] != symbol: + new.append(i) + else: + ret.append(i) + self.bulks = new + Log(QUOTES[LANG]['CLEAR'] % (symbol.encode().upper(), COLORS['RED'])) + + return ret + + def BulkPost(self, symbol=None): + orders = [] + if symbol is None: + orders = self.BulkClear(notify=False) + else: + orders = self.BulkClear(symbol=symbol, notify=False) + + ret = self.IO("api", "POST", "/api/v1/order/bulk", 'orders=%s' % json.dumps(orders)) + + Log(QUOTES[LANG]['ORDCOUNT'] % (len(orders),COLORS['LAPIS'])) + return ret + + def BulkOrders(self): + return self.bulks + + def Amend(self, symbol=None, orderID=None, clOrdID=None, price=None, amount=None): + if symbol is None: + symbol = self.symbol + + order = {} + order['symbol'] = symbol + if orderID is None: + if clOrdID is None: + Log(QUOTES[LANG]['PARAMERR'] % (COLORS['RED'])) + return False + else: + order['clOrdID'] = clOrdID + else: + order['orderID'] = orderID + + if price is not None: + order['price'] = price + if amount is not None: + order['orderQty'] = amount + + if price is None and amount is None: + Log(QUOTES[LANG]['PARAMERR'] % (COLORS['RED'])) + return False + + ret = self.IO("api", "PUT", "/api/v1/order/bulk", 'orders=%s' % json.dumps([order])) + if ret == False: + return False + + try: + id = order['orderID'] + except: + id = order['clOrdID'] + + if price is None: + Log(QUOTES[LANG]['MODORDERA'] % (id, amount, COLORS['LAPIS'])) + return ret + elif amount is None: + Log(QUOTES[LANG]['MODORDERP'] % (id, price, COLORS['LAPIS'])) + return ret + else: + Log(QUOTES[LANG]['MODORDER'] % (id, price, amount, COLORS['LAPIS'])) + return ret + + def AmendAdd(self, symbol=None, orderID=None, clOrdID=None, price=None, amount=None): + if symbol is None: + symbol = self.symbol + + order = {} + order['symbol'] = symbol + if orderID is None: + if clOrdID is None: + Log(QUOTES[LANG]['PARAMERR'] % (COLORS['RED'])) + return False + else: + order['clOrdID'] = clOrdID + else: + order['orderID'] = orderID + + if price is not None: + order['price'] = price + if amount is not None: + order['orderQty'] = amount + + if price is None and amount is None: + Log(QUOTES[LANG]['PARAMERR'] % (COLORS['RED'])) + return False + + self.amends.append(order) + + try: + id = order['orderID'] + except: + id = order['clOrdID'] + + if price is None: + Log(QUOTES[LANG]['MODORDERA'] % (id, amount, COLORS['LAPIS'])) + return True + elif amount is None: + Log(QUOTES[LANG]['MODORDERP'] % (id, price, COLORS['LAPIS'])) + return True + else: + Log(QUOTES[LANG]['MODORDER'] % (id, price, amount, COLORS['LAPIS'])) + return True + + def AmendClear(self, symbol=None, notify=True): + ret = [] + if symbol is None: + ret = self.amends + self.amends = [] + if notify: + Log(QUOTES[LANG]['CLEARALL'] % (COLORS['RED'])) + else: + new = [] + for i in self.amends: + if i['symbol'] != symbol: + new.append(i) + else: + ret.append(i) + self.self.amends = new + Log(QUOTES[LANG]['CLEAR'] % (symbol.encode().upper(), COLORS['RED'])) + + return ret + + def AmendPost(self, symbol=None): + if symbol is None: + symbol = self.symbol + orders = self.AmendClear(symbol=symbol, notify=False) + param = "orders=" + json.dumps(orders) + Log(QUOTES[LANG]['ORDCOUNT'] % (len(orders),COLORS['LAPIS'])) + return self.IO("api", "PUT", "/api/v1/order/bulk", param) + + def AmendOrders(self): + return self.amends + + def CancelAllOrders(self, symbol=None, filters=None): + param = '' + if symbol is not None: + param = param + 'symbol=' + symbol + if filters is not None: + param = param + 'filters=' + json.dumps(filters) + return self.IO("api","DELETE","/api/v1/order/all", param) + + def CancelAllAfter(self, timeout=0): + param = 'timeout=' + str(timeout) + Log(QUOTES[LANG]['CA'] % (timeout,COLORS['LAPIS'])) + return self.IO("api","POST","/api/v1/order/cancelAllAfter", param) + + def GetInstrument(self, symbol='XBTUSD'): + try: + import requests + except ModuleNotFoundError: + Log('pip安装requests以使用GetInstrument()函数.') + return {} + return requests.get('https://www.bitmex.com/api/v1/instrument?symbol=%s&count=1&reverse=false' % symbol).json()[0] + +ext.BitMEXPlus = BitMEX # 导出BitMEX Class, 主策略可以通过BitMEXPlus = ext.BitMEXPlus(exchange)调用 +ext.toNearest = toNearest + +# 模块功能测试 +def main(): + LogReset() + Log(exchange.GetAccount()) + BitMEXPlus = ext.BitMEXPlus(exchange) + exchange.SetContractType(exchange.GetCurrency()) + base_price = exchange.GetTicker()['Last'] + _toNearest = ext.toNearest + BitMEXPlus.BulkAdd('sell', _toNearest(base_price*1.4, 0.5), 30) + BitMEXPlus.BulkAdd('buy', _toNearest(base_price*0.7, 0.5), 30) + Log(BitMEXPlus.BulkOrders()) + Log(BitMEXPlus.BulkPost()) + Log(exchange.GetOrders()) + Log(BitMEXPlus.CancelAllAfter(5000)) + Sleep(8000) + Log(exchange.GetOrders()) + Log(BitMEXPlus.BulkOrders()) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/114148 + +> 更新时间 + +2018-11-13 18:07:03 diff --git "a/Bitmex\344\273\223\344\275\215\345\217\230\345\214\226\346\216\250\351\200\201\345\276\256\344\277\241\357\274\210wss\345\215\217\350\256\256,\351\234\200\350\246\201bitmex api ID\357\274\211|Bitmex position-change push(websocket).md" "b/Bitmex\344\273\223\344\275\215\345\217\230\345\214\226\346\216\250\351\200\201\345\276\256\344\277\241\357\274\210wss\345\215\217\350\256\256,\351\234\200\350\246\201bitmex api ID\357\274\211|Bitmex position-change push(websocket).md" new file mode 100644 index 00000000..08845206 --- /dev/null +++ "b/Bitmex\344\273\223\344\275\215\345\217\230\345\214\226\346\216\250\351\200\201\345\276\256\344\277\241\357\274\210wss\345\215\217\350\256\256,\351\234\200\350\246\201bitmex api ID\357\274\211|Bitmex position-change push(websocket).md" @@ -0,0 +1,44 @@ + +> 策略名称 + +Bitmex仓位变化推送微信(wss协议,需要bitmex api ID)|Bitmex position-change push(websocket) + +> 策略作者 + +botvsing + +> 策略描述 + +使用websocket协议和平台最新的HMAC获取签名的方法,仓位有变化推送到微信 + + + +> 源码 (javascript) + +``` javascript +function main() { + var APIKEY = "your Access Key(Bitmex API ID)" + var expires = parseInt(Date.now() / 1000) + 10 + var signature = exchange.HMAC("sha256", "hex", "GET/realtime" + expires, "{{secretkey}}") + var client = Dial("wss://www.bitmex.com/realtime", 60) + var auth = JSON.stringify({args: [APIKEY, expires, signature], op: "authKeyExpires"}) + var pos = 0 + client.write(auth) + client.write('{"op": "subscribe", "args": "position"}') + while (true) { + bitmexData = client.read() + if(bitmexData.table == 'position' && pos != parseInt(bitmexData.data[0].currentQty)){ + Log('position change', pos, parseInt(bitmexData.data[0].currentQty), '@') + pos = parseInt(bitmexData.data[0].currentQty) + } + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/128624 + +> 更新时间 + +2018-12-04 18:04:36 diff --git "a/BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.js" "b/BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.md" similarity index 90% rename from "BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.js" rename to "BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.md" index 2d989f74..54e7114b 100644 --- "a/BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.js" +++ "b/BotVS \345\225\206\345\223\201\346\234\237\350\264\247 \351\207\217\345\214\226 \346\265\213\350\257\225\345\205\245\351\227\250 \347\255\226\347\225\245.md" @@ -1,32 +1,46 @@ -/* -策略出处: https://www.fmz.com/strategy/59120 -策略名称: BotVS 商品期货 量化 测试入门 策略 -策略作者: 小小梦 -策略描述: + +> 策略名称 + +BotVS 商品期货 量化 测试入门 策略 + +> 策略作者 + +小小梦 + +> 策略描述 知乎专栏 文章: via. https://zhuanlan.zhihu.com/p/30880706 +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|_Interval|500|轮询间隔| +|_StrContractType|rb1801|测试合约代码| -参数 默认值 描述 ----------------- ------ ------ -_Interval 500 轮询间隔 -_StrContractType rb1801 测试合约代码 - -按钮 默认值 描述 ----------------- ------------------- -------------- -changeSymbol MA801 更改商品期货合约代码 -OPEN_LONG true 开多 -OPEN_SHORT true 开空 -COVER true 按数量平仓 -GET_PNEDING __button__ 获取当前合约未完成的订单 -GET_ORDER 空 获取当前合约指定id 的订单 -GET_POSITION 空 获取当前合约持仓信息 -GET_ALL_POSITION __button__ 获取所有合约持仓信息 -CANCEL_ORDER 空 取消订单 -JS_CODE Log("call js code") 调用 JS 代码 -*/ + + +|按钮|默认值|描述| +|----|----|----| +|changeSymbol|MA801|更改商品期货合约代码| +|OPEN_LONG|true|开多| +|OPEN_SHORT|true|开空| +|COVER|true|按数量平仓| +|GET_PNEDING|__button__|获取当前合约未完成的订单| +|GET_ORDER|空|获取当前合约指定id 的订单| +|GET_POSITION|空|获取当前合约持仓信息| +|GET_ALL_POSITION|__button__|获取所有合约持仓信息| +|CANCEL_ORDER|空|取消订单| +|JS_CODE|Log("call js code")|调用 JS 代码| + + +> 源码 (javascript) + +``` javascript // 商品期货 测试 程序 /* 1、 行情部分测试 @@ -351,3 +365,12 @@ function main(){ Sleep(_Interval) } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/59120 + +> 更新时间 + +2017-11-09 13:41:44 diff --git "a/C++ API\350\260\203\347\224\250\344\276\213\345\255\220.cpp" "b/C++ API\350\260\203\347\224\250\344\276\213\345\255\220.md" similarity index 96% rename from "C++ API\350\260\203\347\224\250\344\276\213\345\255\220.cpp" rename to "C++ API\350\260\203\347\224\250\344\276\213\345\255\220.md" index 1b742b1d..32d20d93 100644 --- "a/C++ API\350\260\203\347\224\250\344\276\213\345\255\220.cpp" +++ "b/C++ API\350\260\203\347\224\250\344\276\213\345\255\220.md" @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/61533 -策略名称: C++ API调用例子 -策略作者: Zero -策略描述: + +> 策略名称 + +C++ API调用例子 + +> 策略作者 + +Zero + +> 策略描述 支持C++ 11, 兼容各种平台(Windows/Linux/Mac). 云端编译. -*/ + +> 源码 (cpp) + +``` cpp void main() { if (!Test("c++")) { Panic("请下载最新版本托管者"); @@ -134,3 +142,12 @@ void main() { } } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/61533 + +> 更新时间 + +2018-02-14 11:35:11 diff --git "a/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" "b/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.md" similarity index 89% rename from "CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" rename to "CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.md" index bc167d36..d80dd24f 100644 --- "a/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.js" +++ "b/CTP\345\225\206\345\223\201\346\234\237\350\264\247\345\244\232\345\223\201\347\247\215\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/17289 -策略名称: CTP商品期货多品种海龟交易策略 -策略作者: Zero -策略描述: + +> 策略名称 + +CTP商品期货多品种海龟交易策略 + +> 策略作者 + +Zero + +> 策略描述 - 只支持操作CTP商品期货 - 支持自动或手动恢复进度 @@ -18,32 +23,41 @@ BotVS docker 3.0 compiled at 2016-07-05T09:56:18+0800 https://dn-filebox.qbox.me/d33687abb648c489b6883296685e8717ea3f44ca.png +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Instruments|MA701,CF701,zn1701,SR701,pp1701,l1701,hc1610,ni1701,i1701,v1701,rb1610,jm1701,ag1612,al1701,jd1701,cs1701,p1701|合约列表| +|LoopInterval|3|轮询周期(秒)| +|RiskRatio|true|% Risk Per N ( 0 - 100)| +|ATRLength|20|ATR计算周期| +|EnterPeriodA|20|系统一入市周期| +|LeavePeriodA|10|系统一离市周期| +|EnterPeriodB|55|系统二入市周期| +|LeavePeriodB|20|系统二离市周期| +|UseEnterFilter|true|使用入市过滤| +|IncSpace|0.5|加仓间隔(N的倍数)| +|StopLossRatio|2|止损系数(N的倍数)| +|MaxLots|4|单品种加仓次数| +|RMode|0|进度恢复模式: 自动|手动| +|VMStatus|{}|手动恢复字符串| +|WXPush|true|推送交易信息| +|MaxTaskRetry|5|开仓最多重试次数| +|KeepRatio|10|预留保证金比例| -参数 默认值 描述 --------------- --------------------------------------------------------------------------------------------------------------- ----------------------- -Instruments MA701,CF701,zn1701,SR701,pp1701,l1701,hc1610,ni1701,i1701,v1701,rb1610,jm1701,ag1612,al1701,jd1701,cs1701,p1701 合约列表 -LoopInterval 3 轮询周期(秒) -RiskRatio true % Risk Per N ( 0 - 100) -ATRLength 20 ATR计算周期 -EnterPeriodA 20 系统一入市周期 -LeavePeriodA 10 系统一离市周期 -EnterPeriodB 55 系统二入市周期 -LeavePeriodB 20 系统二离市周期 -UseEnterFilter true 使用入市过滤 -IncSpace 0.5 加仓间隔(N的倍数) -StopLossRatio 2 止损系数(N的倍数) -MaxLots 4 单品种加仓次数 -RMode 0 进度恢复模式: 自动|手动 -VMStatus {} 手动恢复字符串 -WXPush true 推送交易信息 -MaxTaskRetry 5 开仓最多重试次数 -KeepRatio 10 预留保证金比例 - -按钮 默认值 描述 ------ ---------- ----- -暂停/继续 __button__ 暂停/继续 -*/ + + +|按钮|默认值|描述| +|----|----|----| +|暂停/继续|__button__|暂停/继续| + + +> 源码 (javascript) + +``` javascript /*backtest start: 2016-03-01 00:00:00 end: 2016-12-30 00:00:00 @@ -624,3 +638,12 @@ function main() { Sleep(LoopInterval * 1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/17289 + +> 更新时间 + +2018-03-23 22:33:42 diff --git "a/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.py" "b/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.md" similarity index 95% rename from "CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.py" rename to "CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.md" index bffeae2b..47dabfac 100644 --- "a/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.py" +++ "b/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.md" @@ -1,30 +1,42 @@ -''' -策略出处: https://www.fmz.com/strategy/101399 -策略名称: CoinPark交易所通用协议 6.27 16:00 更新 关闭了SSL验证 -策略作者: botvsing -策略描述: + +> 策略名称 + +CoinPark交易所通用协议 6.27 16:00 更新 关闭了SSL验证 + +> 策略作者 + +botvsing + +> 策略描述 ## CoinPark通用协议Python2版本 用途:可以使BotVs支持coinpark.cc交易所 -不知道什么是通用协议?https://www.botvs.com/bbs-topic/1052 -可以把通用协议当成普通机器人,运行在BotVs模拟盘即可,不收取费用 -也可以把代码保存起来,在服务器上用python运行 +代码公开地址:https://www.botvs.com/strategy/101399 运行地址 http://127.0.0.1:6667 -也可以在运行时指定端口 +### 1.在托管者所在服务器运行插件 - python coinpark.py 8866 -在托管者所在服务器后台运行即可: +在保存成文件上传的托管者所在服务器,后台运行即可: nohup python coinpark.py & +也可以在运行时指定端口: + + python coinpark.py 8866 +也可以当成一个普通机器人运行在模拟盘上,不收取费用。 + +### 2.在FMZ网站配置交易所 + 交易所配置如下: ![iamge](https://dn-filebox.qbox.me/c1456599386e597f2966f67b49c7102bab857fef.png) -已经经过部分人的测试,欢迎反馈 -2018.6.26 18:46 更新,修改了Bug +由于账户没资产,未作详细测试,欢迎反馈Bug +2018.6.26 15:57 更新,修改了Bug + -''' +> 源码 (python) + +``` python #!/usr/bin/env python # -*- coding: utf-8 -*- ''' @@ -326,3 +338,12 @@ def run(server_class=HTTPServer, handler_class=Server, port=6667): run(port=int(argv[1])) else: run() +``` + +> 策略出处 + +https://www.fmz.com/strategy/101399 + +> 更新时间 + +2018-09-01 14:55:09 diff --git a/Convert_Record_Cycle.js b/Convert_Record_Cycle.md similarity index 94% rename from Convert_Record_Cycle.js rename to Convert_Record_Cycle.md index 201c3e45..b30f7d40 100644 --- a/Convert_Record_Cycle.js +++ b/Convert_Record_Cycle.md @@ -1,19 +1,30 @@ -/* -策略出处: https://www.fmz.com/strategy/37678 -策略名称: Convert_Record_Cycle -策略作者: jxc6698 -策略描述: + +> 策略名称 + +Convert_Record_Cycle + +> 策略作者 + +jxc6698 + +> 策略描述 # 得到指定周期的蜡烛图 线数据 如有BUG ,问题 欢迎留言 +> 策略参数 + -参数 默认值 描述 ----------------- ------------ ------- -UI_NewCycleForMS 1000*60*60*2 合成周期毫秒数 -*/ +|参数|默认值|描述| +|----|----|----| +|UI_NewCycleForMS|1000*60*60*2|合成周期毫秒数| + + +> 源码 (javascript) + +``` javascript /** * author: jcx * date: 3/10/2017 @@ -190,3 +201,12 @@ function main() { Sleep(1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/37678 + +> 更新时间 + +2017-03-13 16:41:10 diff --git a/Dual Thrust OKEX Feature.js b/Dual Thrust OKEX Feature.md similarity index 90% rename from Dual Thrust OKEX Feature.js rename to Dual Thrust OKEX Feature.md index 83574e98..b4fcc4fd 100644 --- a/Dual Thrust OKEX Feature.js +++ b/Dual Thrust OKEX Feature.md @@ -1,27 +1,38 @@ -/* -策略出处: https://www.fmz.com/strategy/103247 -策略名称: Dual Thrust OKEX Feature -策略作者: botvsing -策略描述: + +> 策略名称 + +Dual Thrust OKEX Feature + +> 策略作者 + +botvsing + +> 策略描述 Check the url below to learn abount Dual Thrust Strategy. https://www.quantconnect.com/tutorials/strategy-library/dual-thrust-trading-algorithm +> 策略参数 + + -参数 默认值 描述 ---------------- ----- ------------------------------------------ -ContractTypeIdx 0 Contract Name: this_week|next_week|quarter -MarginLevelIdx 0 Margin Level: 10|20 -NPeriod 4 Period included -Ks 0.5 Up-track ratio -Kx 0.5 Down-track ratio -AmountOP true Open positon amount -Interval 2000 retry interval -LoopInterval 3 loop time(second) -PeriodShow 500 total K-line number to show for chart -*/ +|参数|默认值|描述| +|----|----|----| +|ContractTypeIdx|0|Contract Name: this_week|next_week|quarter| +|MarginLevelIdx|0|Margin Level: 10|20| +|NPeriod|4|Period included| +|Ks|0.5|Up-track ratio| +|Kx|0.5|Down-track ratio| +|AmountOP|true|Open positon amount| +|Interval|2000|retry interval| +|LoopInterval|3|loop time(second)| +|PeriodShow|500|total K-line number to show for chart| + +> 源码 (javascript) + +``` javascript var ChartCfg = { __isStock: true, title: { @@ -237,3 +248,12 @@ function main() { Sleep(LoopInterval * 1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/103247 + +> 更新时间 + +2018-07-04 14:41:06 diff --git "a/Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210).md" "b/Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210).md" new file mode 100644 index 00000000..47a57e99 --- /dev/null +++ "b/Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210).md" @@ -0,0 +1,77 @@ + +> 策略名称 + +Dual Thrust (麦语言版) + +> 策略作者 + +littleDreamXX + +> 策略描述 + +> 基本原理 + +- 在当天收盘,计算两个值: 最高价-收盘价,和收盘价-最低价。然后取这两个值较大的那个,乘以k值,结果称为触发值。 +- 在第二天开盘,记录开盘价,然后在价格超过(开盘+触发值)时马上买入,或者价格低于(开盘-触发值)时马上卖空。 +- 这个系统是反转系统,没有单独止损。也就是说,反向信号也同时就是平仓信号。 + +> 图解 + + https://dn-filebox.qbox.me/ab06814528c0ae8c54c6bebaea4438325968fbe5.jpg + +`Dual Thrust 策略包含完整的图表显示, 图表动态更新,模板引用等功能, 可做学习模板使用.` + +策略的详细介绍 : http://xueqiu.com/5256769224/32429363 + + +- 主图 + 上轨:公式:UPTRACK^^O+KS*RG; + 下轨:公式:DOWNTRACK^^O-KX*RG; + +- 副图: + 无 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N|4|计算周期| +|KS|0.5|上轨系数| +|KX|0.5|下轨系数| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-01-01 00:00:00 +end: 2018-02-28 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}] +args: [["ContractType","this_week",126961]] +*) + +HH:=HV(H,N); +HC:=HV(C,N); +LL:=LV(L,N); +LC:=LV(C,N); + +RG:=MAX(HH-LC,HC-LL); +UPTRACK^^O+KS*RG; +DOWNTRACK^^O-KX*RG; + +// 交易信号 +C>UPTRACK,BPK; +C 策略出处 + +https://www.fmz.com/strategy/128884 + +> 更新时间 + +2018-12-06 12:09:22 diff --git "a/Dual Thrust OKCoin \346\234\237\350\264\247.js" "b/Dual Thrust OKCoin \346\234\237\350\264\247.md" similarity index 92% rename from "Dual Thrust OKCoin \346\234\237\350\264\247.js" rename to "Dual Thrust OKCoin \346\234\237\350\264\247.md" index 630f932c..2ecfc89f 100644 --- "a/Dual Thrust OKCoin \346\234\237\350\264\247.js" +++ "b/Dual Thrust OKCoin \346\234\237\350\264\247.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/12101 -策略名称: Dual Thrust OKCoin 期货 -策略作者: Zero -策略描述: + +> 策略名称 + +Dual Thrust OKCoin 期货 + +> 策略作者 + +Zero + +> 策略描述 > 基本原理 @@ -18,20 +23,26 @@ 策略的详细介绍 : http://xueqiu.com/5256769224/32429363 +> 策略参数 + + -参数 默认值 描述 ---------------- ----- -------------- -ContractTypeIdx 0 合约品种: 当周|次周|季度 -MarginLevelIdx 0 杠杆大小: 10|20 -NPeriod 4 计算周期 -Ks 0.5 上轨系数 -Kx 0.5 下轨系数 -AmountOP true 开仓合约张数 -Interval 2000 重试间隔(毫秒) -LoopInterval 3 轮询间隔(秒) -PeriodShow 500 图表最大显示K线柱数 -*/ +|参数|默认值|描述| +|----|----|----| +|ContractTypeIdx|0|合约品种: 当周|次周|季度| +|MarginLevelIdx|0|杠杆大小: 10|20| +|NPeriod|4|计算周期| +|Ks|0.5|上轨系数| +|Kx|0.5|下轨系数| +|AmountOP|true|开仓合约张数| +|Interval|2000|重试间隔(毫秒)| +|LoopInterval|3|轮询间隔(秒)| +|PeriodShow|500|图表最大显示K线柱数| + +> 源码 (javascript) + +``` javascript var ChartCfg = { __isStock: true, title: { @@ -248,3 +259,12 @@ function main() { Sleep(LoopInterval * 1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/12101 + +> 更新时间 + +2018-06-05 16:33:49 diff --git "a/Dual Thrust OKEX\346\234\237\350\264\247 (\346\225\231\345\255\246).md" "b/Dual Thrust OKEX\346\234\237\350\264\247 (\346\225\231\345\255\246).md" new file mode 100644 index 00000000..4f5bde42 --- /dev/null +++ "b/Dual Thrust OKEX\346\234\237\350\264\247 (\346\225\231\345\255\246).md" @@ -0,0 +1,166 @@ + +> 策略名称 + +Dual Thrust OKEX期货 (教学) + +> 策略作者 + +小小梦 + +> 策略描述 + +> 基本原理 + +- 在当天收盘,计算两个值: 最高价-收盘价,和收盘价-最低价。然后取这两个值较大的那个,乘以k值,结果称为触发值。 +- 在第二天开盘,记录开盘价,然后在价格超过(开盘+触发值)时马上买入,或者价格低于(开盘-触发值)时马上卖空。 +- 这个系统是反转系统,没有单独止损。也就是说,反向信号也同时就是平仓信号。 + +> 图解 + + https://dn-filebox.qbox.me/ab06814528c0ae8c54c6bebaea4438325968fbe5.jpg + +`Dual Thrust 策略包含完整的图表显示, 图表动态更新,模板引用等功能, 可做学习模板使用.` + +策略的详细介绍 : http://xueqiu.com/5256769224/32429363 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|NPeriod|4|计算周期| +|Ks|0.5|上轨系数| +|Kx|0.5|下轨系数| +|AmountOP|true|开仓合约张数| + + +> 源码 (javascript) + +``` javascript +var STATE_IDLE = 0 +var STATE_LONG = 1 +var STATE_SHORT = 2 +var State = STATE_IDLE +var LastBarTime = 0 +var UpTrack = 0 +var DownTrack = 0 +var InitAccount = null + +function GetPosition(posType) { + var positions = exchange.GetPosition() + for (var i = 0; i < positions.length; i++) { + if (positions[i].Type === posType) { + return [positions[i].Price, positions[i].Amount]; + } + } + return [0, 0] +} + +function CancelPendingOrders() { + while (true) { + var orders = exchange.GetOrders() + for (var i = 0; i < orders.length; i++) { + exchange.CancelOrder(orders[i].Id) + Sleep(500) + } + if (orders.length === 0) { + break + } + } +} + +function Trade(currentState, nextState) { + var pfn = nextState === STATE_LONG ? exchange.Buy : exchange.Sell + if (currentState !== STATE_IDLE) { + exchange.SetDirection(currentState === STATE_LONG ? "closebuy" : "closesell") + while (true) { + var amount = GetPosition(currentState === STATE_LONG ? PD_LONG : PD_SHORT)[1] + if (amount === 0) { + break + } + pfn(nextState === STATE_LONG ? _C(exchange.GetTicker).Sell * 1.001 : _C(exchange.GetTicker).Buy * 0.999, amount) + Sleep(500) + CancelPendingOrders() + } + var account = exchange.GetAccount() + LogProfit(_N(account.Stocks - InitAccount.Stocks, 3), "收益率:", _N((account.Stocks - InitAccount.Stocks) * 100 / InitAccount.Stocks, 3) + '%') + } + exchange.SetDirection(nextState === STATE_LONG ? "buy" : "sell") + while (true) { + var pos = GetPosition(nextState === STATE_LONG ? PD_LONG : PD_SHORT) + if (pos[1] >= AmountOP) { + Log("持仓均价", pos[0], "数量:", pos[1]) + break + } + pfn(nextState === STATE_LONG ? _C(exchange.GetTicker).Sell * 1.001 : _C(exchange.GetTicker).Buy * 0.999, AmountOP-pos[1]) + Sleep(500) + CancelPendingOrders() + } +} + +function onTick() { + var records = exchange.GetRecords() + if (!records || records.length <= NPeriod) { + return + } + var Bar = records[records.length - 1] + $.PlotRecords(records, 'K线') + if (LastBarTime !== Bar.Time) { + var HH = TA.Highest(records, NPeriod, 'High') + var HC = TA.Highest(records, NPeriod, 'Close') + var LL = TA.Lowest(records, NPeriod, 'Low') + var LC = TA.Lowest(records, NPeriod, 'Close') + var Range = Math.max(HH - LC, HC - LL) + UpTrack = _N(Bar.Open + (Ks * Range), 3) + DownTrack = _N(Bar.Open - (Kx * Range), 3) + $.PlotHLine(UpTrack, 'UpTrack') + $.PlotHLine(DownTrack, 'DownTrack') + LastBarTime = Bar.Time + } + + LogStatus("Price:", Bar.Close, "Up:", UpTrack, "Down:", DownTrack, "Date:", new Date()) + var msg + if (State === STATE_IDLE || State === STATE_SHORT) { + if (Bar.Close >= UpTrack) { + msg = '做多 触发价: ' + Bar.Close + ' 上轨:' + UpTrack + Log(msg) + Trade(State, STATE_LONG) + State = STATE_LONG + $.PlotFlag(Bar.Time, msg, '多', 'flag', 'red') + } + } + + if (State === STATE_IDLE || State === STATE_LONG) { + if (Bar.Close <= DownTrack) { + msg = '做空 触发价: ' + Bar.Close + ' 下轨:' + DownTrack + Log(msg) + Trade(State, STATE_SHORT) + $.PlotFlag(Bar.Time, msg, '空', 'circlepin', 'green') + State = STATE_SHORT + } + } +} + +function main() { + exchange.SetContractType("quarter") + exchange.SetMarginLevel(10) + if (exchange.GetPosition().length > 0) { + throw "策略启动前不能有持仓." + } + CancelPendingOrders() + InitAccount = exchange.GetAccount() + while (true) { + onTick() + Sleep(500) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/112425 + +> 更新时间 + +2018-08-25 16:39:50 diff --git "a/Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.js" "b/Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.md" similarity index 90% rename from "Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.js" rename to "Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.md" index 4601ce97..f4222ef6 100644 --- "a/Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.js" +++ "b/Dual Thrust \345\225\206\345\223\201\346\234\237\350\264\247.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/13011 -策略名称: Dual Thrust 商品期货 -策略作者: Zero -策略描述: + +> 策略名称 + +Dual Thrust 商品期货 + +> 策略作者 + +Zero + +> 策略描述 > 基本原理 @@ -18,21 +23,27 @@ 策略的详细介绍 : http://xueqiu.com/5256769224/32429363 +> 策略参数 + -参数 默认值 描述 ----------------- ----- ----------- -ContractTypeName MA701 合约品种 -NPeriod 4 计算周期 -Ks 0.5 上轨系数 -Kx 0.5 下轨系数 -AmountOP true 开仓合约张数 -Interval 2000 重试间隔(毫秒) -LoopInterval 3 轮询间隔(秒) -PeriodShow 500 图表最大显示K线柱数 -NotifyWX true 下单微信通知 -CoverAll false 启动策略时清空合约仓位 -*/ +|参数|默认值|描述| +|----|----|----| +|ContractTypeName|MA701|合约品种| +|NPeriod|4|计算周期| +|Ks|0.5|上轨系数| +|Kx|0.5|下轨系数| +|AmountOP|true|开仓合约张数| +|Interval|2000|重试间隔(毫秒)| +|LoopInterval|3|轮询间隔(秒)| +|PeriodShow|500|图表最大显示K线柱数| +|NotifyWX|true|下单微信通知| +|CoverAll|false|启动策略时清空合约仓位| + + +> 源码 (javascript) + +``` javascript /*backtest start: 2016-01-15 09:00:00 end: 2017-01-01 15:00:00 @@ -210,3 +221,12 @@ function main() { Sleep(LoopInterval * 1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/13011 + +> 更新时间 + +2017-11-10 21:54:38 diff --git a/Dynamic Balance Strategy.md b/Dynamic Balance Strategy.md new file mode 100644 index 00000000..77b35080 --- /dev/null +++ b/Dynamic Balance Strategy.md @@ -0,0 +1,106 @@ + +> 策略名称 + +Dynamic Balance Strategy + +> 策略作者 + +ruby + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|threshold|0.05|threshold| +|ZPrecision|8|Price Precision| +|XPrecision|4|Amount Precision| +|MinStock|0.001|minimum buying amount| +|Interval|2000|error retry interval| +|LoopInterval|60|Polling Interval| + + +> 源码 (javascript) + +``` javascript +var InitAccount = null; + +function onTick(){ + var acc = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + var spread = ticker.Sell - ticker.Buy; + var diffAsset = (acc.Balance - (acc.Stocks * ticker.Sell))/2; + var ratio = diffAsset / acc.Balance; + LogStatus('ratio:', ratio, _D()); + if(Math.abs(ratio) < threshold){ + return false; + } + if(ratio > 0){ + var buyPrice = _N(ticker.Sell + spread, ZPrecision); + var buyAmount = _N(diffAsset / buyPrice, XPrecision); + if(buyAmount < MinStock){ + return false; + } + exchange.Buy(buyPrice, buyAmount); + } else { + var sellPrice = _N(ticker.Buy - spread, ZPrecision); + var sellAmount = _N(-diffAsset / sellPrice, XPrecision); + if (sellAmount < MinStock) { + return false; + } + exchange.Sell(sellPrice, sellAmount, diffAsset, ratio); + } + return true; +} + +function CancelPendingOrders(){ + var ret = false; + while(true){ + var orders = null; + while(!(orders = exchange.GetOrders())){ + Sleep(Interval); + } + if(orders.length == 0){ + return ret; + } + for(var j = 0; j < orders.length; j++){ + exchange.CancelOrder(orders[j],Id); + ret = true; + if(j < (orders.length - 1)){ + Sleep(Interval); + + } + + } + + } + + } + + +function main() { + InitAccount = _C(exchange.GetAccount); + while(true){ + if(onTick()){ + Sleep(1000); + CancelPendingOrders(); + Log(_C(exchange.GetAccount)); + + } + Sleep(LoopInterval * 1000); + } + + +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/110900 + +> 更新时间 + +2018-08-13 12:35:18 diff --git "a/FCoin\344\272\244\346\230\223\346\211\213\347\273\255\350\264\271\347\273\237\350\256\241(\346\204\237\350\260\242\346\273\241\346\200\273\345\210\206\344\272\253).js" "b/FCoin\344\272\244\346\230\223\346\211\213\347\273\255\350\264\271\347\273\237\350\256\241(\346\204\237\350\260\242\346\273\241\346\200\273\345\210\206\344\272\253).js" deleted file mode 100644 index 37956533..00000000 --- "a/FCoin\344\272\244\346\230\223\346\211\213\347\273\255\350\264\271\347\273\237\350\256\241(\346\204\237\350\260\242\346\273\241\346\200\273\345\210\206\344\272\253).js" +++ /dev/null @@ -1,146 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/98405 -策略名称: FCoin交易手续费统计(感谢满总分享) -策略作者: 每日一嫩模 -策略描述: - - - -*/ - -//2018-6-13 22:19 -var Trades = []; -var fees = {"usdt": 0, "btc": 0, "eth": 0, "etc": 0, "ft": 0}; -var num = 0; -var table = { - type: "table", - title: "标题", - cols: ["ts", "时间", "买卖", "委托数", "委托价", "成交额", "成交数", "成交均价", "手续费", "来源", "状态", "交易对", "委托类型", "手续费币"], - rows: [] -}; -var FC_pairs = FC_pairs(); - -function main() { - - /* - symbol 交易对 - states 订单状态 - - submitted 已提交 - partial_filled 部分成交 - partial_canceled 部分成交已撤销 - filled 完全成交 - canceled 已撤销 - pending_cancel 撤销已提交 - - before 查询某个页码之前的订单 - after 查询某个页码之后的订单 - limit 每页的订单数量,默认为 20 条 - - */ - - var Pairs = Object.keys(FC_pairs);//["btcusdt","ltcusdt","ethusdt","ftusdt","ftbtc","etcusdt","bchusdt"]; - var States = ["partial_canceled", "filled", "partial_filled"]; - - var after = new Date().setHours(0, 0, 0, 0); - var end = after + 24 * 3600 * 1000; - - var ts0 = new Date().getTime(); - Pairs.forEach(function (Symbol) { - var ts = after; - - States.forEach(function (State) { - while (true) { - Sleep(1000); -//Log(56,new Date().getTime()-ts0); - ts0 = new Date().getTime(); - var ordersHistory = FC_ordersHistory(Symbol, State, "after", ts); - calcFees(ordersHistory, end); - if (ordersHistory.length < 100) { - break; - } - ts = ordersHistory[0].created_at + 1; - } - }); - - }); - - Log(fees, after, new Date(after));//new Date().format("M-d h:m:s") - - table.title = JSON.stringify(fees); - table.rows = Trades; - // LogStatus("`" + JSON.stringify([table]) + "`" + "\n"); -} - -function calcFees(ordersHistory, end) { - ordersHistory.forEach(function (v) { - if (v.created_at < end) { - var quote = FC_pairs[v.symbol][v.side === "buy" ? 0 : 1]; - if (!fees.hasOwnProperty(quote)) { - fees[quote] = 0; - } - fees[quote] += Number(v.fill_fees); - Trades.push(FC_ordersformat(v).concat([quote])); - } - }); -} - -function FC_pairs() { - var info; - var sleep = 1000; - try { - info = exchange.IO("api", "GET", "/v2/public/symbols");// - } catch (e) { - Log("FC_pairs()出错重试"); - Sleep(sleep); - sleep += sleep; - FC_pairs(); - } - - if (info.hasOwnProperty("status") && info.status === 429) { - Log("429错误"); - Sleep(10000); - FC_pairs(); - } else { - info = info.data; - } - var ret = {}; - info.forEach(function (v) { - if (!ret.hasOwnProperty(v)) { - ret[v.name] = {}; - } - ret[v.name] = [v.base_currency, v.quote_currency]; - }); - - return ret; -} - -function FC_ordersHistory(symbol, states, after_before, ts) { - Log(ts, new Date(ts)); - var args = "symbol=" + symbol + "&limit=100&states=" + states + "&" + after_before + "=" + ts; - var info; - var sleep = 3000; - try { - info = exchange.IO("api", "GET", "/v2/orders", args); - Log(args); - Log(info.data.length); - } catch (e) { - Log("FC_ordersHistory 出错重试"); - Sleep(sleep); - sleep += sleep; - return FC_ordersHistory(symbol, states, after_before, ts); - } - - if (info.hasOwnProperty("status") && info.status === 429) { - Log("429错误"); - Sleep(10000); - return FC_ordersHistory(symbol, states, after_before, ts); - } - return info.data; -} - -function FC_ordersformat(v) { - var ret = [v.created_at, new Date(v.created_at), v.side, Number(v.amount), Number(v.price), Number(v.executed_value), Number(v.filled_amount), _N(Number(v.executed_value) / Number(v.filled_amount), 8), Number(v.fill_fees), v.source, v.state, v.symbol, v.type]; - return ret; -} - diff --git "a/Fomo3D \346\231\272\350\203\275\345\220\210\347\272\246\347\233\221\346\216\247 - Fomo3D Smart Contract Monitoring.md" "b/Fomo3D \346\231\272\350\203\275\345\220\210\347\272\246\347\233\221\346\216\247 - Fomo3D Smart Contract Monitoring.md" new file mode 100644 index 00000000..4e3f006a --- /dev/null +++ "b/Fomo3D \346\231\272\350\203\275\345\220\210\347\272\246\347\233\221\346\216\247 - Fomo3D Smart Contract Monitoring.md" @@ -0,0 +1,126 @@ + +> 策略名称 + +Fomo3D 智能合约监控 - Fomo3D Smart Contract Monitoring + +> 策略作者 + +FawkesPan + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|TG|0|是否启用 Telegram 机器人: 0|1| +|TGKEY||Telegram 机器人KEY| +|TGID|false|Telegram 会话ID| +|THRESHOLD|300|触发通知阈值| +|REFRESH_DELAY|10|刷新数据间隔| +|INFURAKEY|需要到infura.io申请密钥并且添加合约地址白名单|数据接口密钥| +|CONTRACT|0xa62142888aba8370742be823c1782d17a0389da1|智能合约地址| +|WECHAT|0|启用微信通知: 0|1| + + +> 源码 (python) + +``` python +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# encoding: utf-8 +# +# Fomo3D Smart Contract Monitoring +# +# Copyright 2018 FawkesPan +# Contact : i@fawkex.me / Telegram@FawkesPan +# +# Do What the Fuck You Want To Public License +# + +import requests +import re +import json +import time +import datetime + +LogReset() + +if TG == 1: + TG_ENABLE = True +else: + TG_ENABLE = False +if WECHAT == 1: + WC_ENABLE = True +else: + WC_ENABLE = False + +TG_BOT_KEY = TGKEY + +TGURL = 'https://api.telegram.org/bot%s/sendMessage' % TG_BOT_KEY +TGPARAM = {} +TGPARAM['chat_id'] = TGID + +def Send(message): + if TG_ENABLE == False: + return + try: + TGPARAM['text'] = message + res = requests.post(TGURL, data = TGPARAM) + return + except IOError as e: + print(e) + return + + +def Refresh(): + URL = 'https://mainnet.infura.io/%s' % INFURAKEY + HEADER = {'Content-Type': 'application/json'} + PARAM = '{"jsonrpc": "2.0", "id": 1, "method": "eth_call", "params": [{"data":"0x747dff42","to":"%s"},"latest"]}' % CONTRACT + data = requests.post(URL,data=PARAM,headers=HEADER).json() + HEX = re.sub('(0{2,})','X',data['result']).split('X')[3] + print(HEX) + INT = int(HEX, 16) + NOW = int(time.time()) + LEFT = INT - NOW + return LEFT + +def main(): + Log('Started!') + Log('ContractAddress: ' + CONTRACT) + Log('Telegram Enabled: ' + str(TG_ENABLE)) + Log('WeChat Enabled: ' + str(WC_ENABLE)) + while True: + try: + DATE = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + TIMELEFT = Refresh() + message = 'Time before FOMO ENDING : %d' % TIMELEFT + if TIMELEFT < 0: + TIMELEFT = THRESHOLD + 10 + if TIMELEFT <= THRESHOLD: + Send(message) + if WC_ENABLE == True: + message = message + ' !@' + + Log(message) + else: + Log(message) + + except IOError as e: + print(e) + time.sleep(REFRESH_DELAY) + pass + + time.sleep(REFRESH_DELAY) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/107916 + +> 更新时间 + +2018-09-12 02:35:10 diff --git "a/Get cryptocurrency current and max supply|\350\216\267\345\217\226\345\270\201\347\247\215\344\276\233\345\272\224\351\207\217.md" "b/Get cryptocurrency current and max supply|\350\216\267\345\217\226\345\270\201\347\247\215\344\276\233\345\272\224\351\207\217.md" new file mode 100644 index 00000000..710434b7 --- /dev/null +++ "b/Get cryptocurrency current and max supply|\350\216\267\345\217\226\345\270\201\347\247\215\344\276\233\345\272\224\351\207\217.md" @@ -0,0 +1,51 @@ + +> 策略名称 + +Get cryptocurrency current and max supply|获取币种供应量 + +> 策略作者 + +botvsing + + + + + +> 源码 (javascript) + +``` javascript +function GetSupply(symbol, max){ + var ids = null + if(_G('ids')){ + ids = _G('ids') + }else{ + ids = JSON.parse(HttpQuery('https://api.coinmarketcap.com/v2/listings/')).data + _G('ids', ids) + } + var coinId = null + for (var i=0; i 策略出处 + +https://www.fmz.com/strategy/122370 + +> 更新时间 + +2018-10-18 20:55:41 diff --git a/GuoJian_First.md b/GuoJian_First.md new file mode 100644 index 00000000..818f5f90 --- /dev/null +++ b/GuoJian_First.md @@ -0,0 +1,85 @@ + +> 策略名称 + +GuoJian_First + +> 策略作者 + +liuguojian + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|min|0.0085|买入最小值| +|max|0.008534|卖出最大值| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2018-08-27 00:00:00 +end: 2018-08-28 20:00:00 +period: 1m +exchanges: [{"eid":"Huobi","currency":"LTC_BTC"}] +*/ + +function main() { + Log(max); + Log(min); + var a = 1; + while(true){ + Log(exchange.GetAccount()); + var ticker = exchange.GetTicker(); + Log(ticker); + if(ticker.High >= max){ + //Log("当前最高价"+ticker.High); + //Log("将所有USDT换成BTC"); + Log("卖出1"); + exchange.Sell(-1, 1); + Log(exchange.GetAccount()); + + } + if(ticker.Low <= min){ + Log("买入1"); + exchange.Buy(-1, 1); + Log(exchange.GetAccount()); + break; + } + a++; + Sleep(60000); // 一分钟 + } + +} + +function onexit(){ + Log("onexit"); +} + +function onerror(){ + Log("onerror"); +} + +function init(){ + Log("init"); +} + + + + + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/113871 + +> 更新时间 + +2018-08-28 21:43:15 diff --git a/Hedge_BTC-ETH Demo.js b/Hedge_BTC-ETH Demo.md similarity index 93% rename from Hedge_BTC-ETH Demo.js rename to Hedge_BTC-ETH Demo.md index 8ab6eaf5..d890fc38 100644 --- a/Hedge_BTC-ETH Demo.js +++ b/Hedge_BTC-ETH Demo.md @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/48536 -策略名称: Hedge_BTC-ETH Demo -策略作者: 小小梦 -策略描述: + +> 策略名称 + +Hedge_BTC-ETH Demo + +> 策略作者 + +小小梦 + +> 策略描述 BTC 和 ETH 的 跨品种对冲 思路测试 DEMO 根据价格比 画出 图表,分析 价格比 变化,寻找套利空间。 @@ -10,12 +15,18 @@ BTC 和 ETH 的 跨品种对冲 思路测试 DEMO by littleDream +> 策略参数 + -参数 默认值 描述 ----- ----- ------------ -Mode 0 模式: BOLL|SMA -*/ +|参数|默认值|描述| +|----|----|----| +|Mode|0|模式: BOLL|SMA| + + +> 源码 (javascript) + +``` javascript /*exchanges A : BTC B : ETH @@ -155,3 +166,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/48536 + +> 更新时间 + +2017-07-25 13:19:52 diff --git a/Iceberg Buy Order.js b/Iceberg Buy Order.md similarity index 85% rename from Iceberg Buy Order.js rename to Iceberg Buy Order.md index 79e81d09..8843b611 100644 --- a/Iceberg Buy Order.js +++ b/Iceberg Buy Order.md @@ -1,27 +1,38 @@ -/* -策略出处: https://www.fmz.com/strategy/103319 -策略名称: Iceberg Buy Order -策略作者: botvsing -策略描述: + +> 策略名称 + +Iceberg Buy Order + +> 策略作者 + +botvsing + +> 策略描述 冰山委托指的是投资者在进行大额交易时,为避免对市场造成过大冲击,将大单委托自动拆为多笔委托,根据当前的最新买一/卖一价格和客户设定的价格策略自动进行小单委托,在上一笔委托被全部成交或最新价格明显偏离当前委托价时,自动重新进行委托。 例子: 如果单次均值浮动点数设置为10那么: 每一笔委托的数量为其单次委托平均值的90%~110%,委托价格为最新买1价*(1-委托深度),在上一笔委托全部成交后再进行新的一笔委托,在最新成交价格距离该笔委托超过委托深度*2时自动撤单并重新进行委托。在策略总成交量等于其总委托数量时停止委托。当市场的最新成交价格高于其最高买入价格时停止委托,在最新成交价格重新低于最高买入价后恢复委托。 +> 策略参数 + + -参数 默认值 描述 ------------- ------ ----------------------- -TotalBuyNet 10000 total buy value -AvgBuyOnce 100 avg buy value -FloatPoint 10 avg price float percent -EntrustDepth 0.1 buy depth percent -MaxBuyPrice 20000 Highest price to buy -Interval 1000 retry time(ms) -MinStock 0.0001 Min Stock -LoopInterval true loop time(second) -*/ +|参数|默认值|描述| +|----|----|----| +|TotalBuyNet|10000|total buy value| +|AvgBuyOnce|100|avg buy value| +|FloatPoint|10|avg price float percent| +|EntrustDepth|0.1|buy depth percent| +|MaxBuyPrice|20000|Highest price to buy| +|Interval|1000|retry time(ms)| +|MinStock|0.0001|Min Stock| +|LoopInterval|true|loop time(second)| + +> 源码 (javascript) + +``` javascript function CancelPendingOrders() { while (true) { var orders = _C(exchange.GetOrders); @@ -99,3 +110,12 @@ function main() { Log("All Done", _C(exchange.GetAccount)); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/103319 + +> 更新时间 + +2018-07-05 11:10:09 diff --git "a/JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.js" "b/JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.md" similarity index 89% rename from "JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.js" rename to "JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.md" index 2be4ba5c..69ae372c 100644 --- "a/JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.js" +++ "b/JS\347\211\210 \345\225\206\345\223\201\346\234\237\350\264\247 \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245\346\241\206\346\236\266.md" @@ -1,13 +1,19 @@ -/* -策略出处: https://www.fmz.com/strategy/44593 -策略名称: JS版 商品期货 精简多品种 MACD 趋势策略框架 -策略作者: 小小梦 -策略描述: + +> 策略名称 + +JS版 商品期货 精简多品种 MACD 趋势策略框架 + +> 策略作者 + +小小梦 + -*/ +> 源码 (javascript) + +``` javascript /*backtest start: 2016-01-30 end: 2016-12-30 @@ -87,3 +93,12 @@ function main(){ } +``` + +> 策略出处 + +https://www.fmz.com/strategy/44593 + +> 更新时间 + +2017-06-24 10:32:57 diff --git "a/JS\347\211\210\346\234\254Dual Thrust.js" "b/JS\347\211\210\346\234\254Dual Thrust.md" similarity index 95% rename from "JS\347\211\210\346\234\254Dual Thrust.js" rename to "JS\347\211\210\346\234\254Dual Thrust.md" index 42369197..b9bbef55 100644 --- "a/JS\347\211\210\346\234\254Dual Thrust.js" +++ "b/JS\347\211\210\346\234\254Dual Thrust.md" @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/36100 -策略名称: JS版本Dual Thrust -策略作者: BotVs@太极 -策略描述: + +> 策略名称 JS版本Dual Thrust -*/ +> 策略作者 + +BotVs@太极 + +> 策略描述 + +JS版本Dual Thrust + + +> 源码 (javascript) + +``` javascript // botvs@505d17ec1da140d9467374ae4c1ad024 //========================================== //API: Chart 函数使用的简单例子(画图功能) @@ -118,3 +126,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/36100 + +> 更新时间 + +2017-02-18 17:25:01 diff --git "a/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.js" "b/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.md" similarity index 95% rename from "KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.js" rename to "KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.md" index 3e68a35f..f360f556 100644 --- "a/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.js" +++ "b/KingKeltner\350\266\213\345\212\277\347\255\226\347\225\245_\344\275\216\351\242\221.md" @@ -1,13 +1,19 @@ -/* -策略出处: https://www.fmz.com/strategy/42283 -策略名称: KingKeltner趋势策略_低频 -策略作者: ipqhjjybj -策略描述: +> 策略名称 + +KingKeltner趋势策略_低频 + +> 策略作者 + +ipqhjjybj -*/ + + +> 源码 (javascript) + +``` javascript /* 策略出处: vnpy 策略名称: KingKeltner趋势策略 @@ -137,3 +143,12 @@ function main() { Sleep(LoopInterval*1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/42283 + +> 更新时间 + +2017-06-02 23:06:08 diff --git a/MA5.md b/MA5.md new file mode 100644 index 00000000..13033f20 --- /dev/null +++ b/MA5.md @@ -0,0 +1,81 @@ + +> 策略名称 + +MA5 + +> 策略作者 + +yy1987316 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|RETRY_INTERVAL|true|重试间隔(秒)| + + +> 源码 (python) + +``` python +''' +MA5策略 +站上买,跌破卖 +''' +import datetime + +def onTick(): + '''轮训函数''' + account = _C(exchange.GetAccount) + Log(account) + kline_data = _C(exchange.GetRecords, PERIOD_D1) + # 前一个周期的MA5值,排除当前周期 + ma5_list = TA.MA(kline_data, 5) + if len(ma5_list) >= 2: + ma5 = ma5_list[-2] + + if ma5: + # 如果有值,回测时间段内开始的几个周期,没有ma5 + + # 取上个周期的开盘价、收盘价 + open_price = kline_data[-2].Open + close_price = kline_data[-2].Close + Log('当前:open_price=', open_price, ',close_price=', close_price, ',ma5=', ma5) + + if open_price < ma5 < close_price and account.Balance > 10: + Log('买') + exchange.Buy(-1, account.Balance) + elif close_price < ma5 < open_price and account.Stocks > 0.1: + Log('卖') + exchange.Sell(-1, account.Stocks) + else: + Log('无行情') + else: + Log('当前时间无MA5供参考') + +def wait_to_tomorrow(): + '''等待到第二天0点''' + s = _N(UnixNano() / 1000000000) + s = 86400 - (s - 16*60*60) % 86400 + 1 + # Log(s) + Sleep(s * 1000) + +def main(): + # 设置重试延迟 + _CDelay(RETRY_INTERVAL * 1000) + while True: + onTick() + wait_to_tomorrow() + # Sleep(LOOP_INTERVAL * 1000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/125474 + +> 更新时间 + +2018-11-09 18:13:18 diff --git "a/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" "b/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" new file mode 100644 index 00000000..8d8e5b87 --- /dev/null +++ "b/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" @@ -0,0 +1,99 @@ + +> 策略名称 + +MACD+MA指标组合策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 公式名称:MACD+MA指标组合策略 +- 数据周期:日K +- 数据合约:指数合约 +- 交易合约:主力合约 +- 适合品种:商品期货 +- 官方网站:WWW.QUANT.LA + +- 副图 + 副图显示:MACDDIFF,公式 MACDDIFF:MACDVALUE-AVGMACD; + +- 主图 + 主图显示:DMA1,公式 DMA1^^MA(C,L1); + DMA2,公式 DMA2^^MA(C,L2); + +/upload/asset/6d7b1a3241d607bbc4f4f853687fcf54.png + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|FASTLENGTH|12|MACD指标参数1| +|SLOWLENGTH|26|MACD指标参数2| +|MACDLENGTH|9|MACD指标参数3| +|L1|50|均线1指标| +|L2|120|均线2指标| +|STOPLOSS|5|止损百分比| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2016-06-01 00:00:00 +end: 2016-07-19 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +*) + +// MACD计算参数 已经添加到,策略参数 +// FASTLENGTH:=12; +// SLOWLENGTH:=26; +// MACDLENGTH:=9; + +// 均线长度 已经添加到,策略参数 +// L1:=50; +// L2:=120; + +// 止损5% 已经添加到,策略参数 +// STOPLOSS:=5; + +//MACD +MACDVALUE:=EMA(CLOSE,FASTLENGTH)-EMA(CLOSE,SLOWLENGTH); +AVGMACD:=EMA(MACDVALUE,MACDLENGTH); +MACDDIFF:MACDVALUE-AVGMACD; + +//MA1、MA2 +DMA1^^MA(C,L1); +DMA2^^MA(C,L2); +买入开仓价:=VALUEWHEN(BARSBK=1,O); +卖出开仓价:=VALUEWHEN(BARSSK=1,O); +BUYCONDITION:=MACDVALUE>0 && DMA1>DMA2 && MACDDIFF>0 && C>DMA1 && REF(C,1)>REF(DMA1,1); +SELLCONDITION:=MACDVALUE<0 && DMA10 AND (REF(MACDVALUE,1)<0 OR REF(DMA1,1)0 AND (REF(MACDVALUE,1)>0 OR REF(DMA1,1)>REF(DMA2,1)),BP; + +// 启动止损 +SKVOL>0 AND HIGH>=卖出开仓价*(1+STOPLOSS*0.01),BP; +SETSIGPRICETYPE(BP,MAX(O,卖出开仓价*(1+STOPLOSS*0.01))); +BKVOL>0 AND LOW<=买入开仓价*(1-STOPLOSS*0.01),SP; +SETSIGPRICETYPE(SP,MIN(O,买入开仓价*(1-STOPLOSS*0.01))); +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/128134 + +> 更新时间 + +2018-12-05 11:48:12 diff --git "a/Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.js" "b/Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.md" similarity index 94% rename from "Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.js" rename to "Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.md" index 763b50e9..b6796fd8 100644 --- "a/Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.js" +++ "b/Ma\345\215\225\345\235\207\347\272\277\350\266\213\345\212\277\344\272\244\346\230\223.md" @@ -1,13 +1,19 @@ -/* -策略出处: https://www.fmz.com/strategy/42451 -策略名称: Ma单均线趋势交易 -策略作者: ipqhjjybj -策略描述: + +> 策略名称 + +Ma单均线趋势交易 + +> 策略作者 + +ipqhjjybj -*/ + +> 源码 (javascript) + +``` javascript /* 策略出处: internet 策略名称: MA 单均线趋势策略 @@ -139,3 +145,12 @@ function main() { } +``` + +> 策略出处 + +https://www.fmz.com/strategy/42451 + +> 更新时间 + +2017-06-04 21:55:07 diff --git "a/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.js" "b/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.md" similarity index 90% rename from "My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.js" rename to "My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.md" index f44452e4..fc6d48bc 100644 --- "a/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.js" +++ "b/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/8602 -策略名称: My-1-价值平均定投策略 -策略作者: Lizza -策略描述: + +> 策略名称 + +My-1-价值平均定投策略 + +> 策略作者 + +Lizza + +> 策略描述 实盘:https://www.botvs.com/m/robot/26018 这个策略适合长期看好比特币的脑残粉,使用价值平均策略来进行定投,可以有效的抵抗市场波动。(关于价值平均定投请度娘。) @@ -22,22 +27,31 @@ 说明:程序会每次检查账户内的资金和比特币与启动时的差额,以此计算每次需要购买的数量,因此不要用其他机器人公用一个帐户,也不要手工进行买入卖出的操作。如果在交易所有充值和体现,应该在程序互动部分填入,否则程序计算会错误。 +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|ErrorInterval|2000|出错重试(毫秒)| +|InvestInternal|15|投资间隔(按照分钟计算)| +|MoneyEveryMonth|5000|每月要投资的资金量| +|SlidePrice|0.05|购买时滑点| -参数 默认值 描述 ---------------- ------- ------------ -ErrorInterval 2000 出错重试(毫秒) -InvestInternal 15 投资间隔(按照分钟计算) -MoneyEveryMonth 5000 每月要投资的资金量 -SlidePrice 0.05 购买时滑点 -按钮 默认值 描述 ------------ ---------- ----------- -Pause __button__ 暂停交易 -Continue __button__ 继续交易 -MoneyChange false 纪录资金充值或提现 -StockChange false 纪录数字货币充值或提现 -*/ + +|按钮|默认值|描述| +|----|----|----| +|Pause|__button__|暂停交易| +|Continue|__button__|继续交易| +|MoneyChange|false|纪录资金充值或提现| +|StockChange|false|纪录数字货币充值或提现| + + +> 源码 (javascript) + +``` javascript var initAccount; var startTime; //unix timestamp var pause = false; //pause execution of strategy or continue @@ -267,3 +281,12 @@ function onexit(){ Log('Robot Stopped!#ff0000@'); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/8602 + +> 更新时间 + +2016-06-14 10:42:59 diff --git "a/OKCoin\346\234\237\350\264\247\346\235\241\344\273\266\350\247\246\345\217\221\345\247\224\346\211\230\345\270\246\346\255\242\346\215\237.js" "b/OKCoin\346\234\237\350\264\247\346\235\241\344\273\266\350\247\246\345\217\221\345\247\224\346\211\230\345\270\246\346\255\242\346\215\237.md" similarity index 85% rename from "OKCoin\346\234\237\350\264\247\346\235\241\344\273\266\350\247\246\345\217\221\345\247\224\346\211\230\345\270\246\346\255\242\346\215\237.js" rename to "OKCoin\346\234\237\350\264\247\346\235\241\344\273\266\350\247\246\345\217\221\345\247\224\346\211\230\345\270\246\346\255\242\346\215\237.md" index 0b0cc32c..9e377225 100644 --- "a/OKCoin\346\234\237\350\264\247\346\235\241\344\273\266\350\247\246\345\217\221\345\247\224\346\211\230\345\270\246\346\255\242\346\215\237.js" +++ "b/OKCoin\346\234\237\350\264\247\346\235\241\344\273\266\350\247\246\345\217\221\345\247\224\346\211\230\345\270\246\346\255\242\346\215\237.md" @@ -1,27 +1,38 @@ -/* -策略出处: https://www.fmz.com/strategy/2169 -策略名称: OKCoin期货条件触发委托带止损 -策略作者: Zero -策略描述: + +> 策略名称 + +OKCoin期货条件触发委托带止损 + +> 策略作者 + +Zero + +> 策略描述 OKCoin期货条件触发下单, 成交后可条件触发自动止损 +> 策略参数 + + -参数 默认值 描述 ---------------- ----- ----------------- -CType 0 货币类型: 人民币|美元 -ContractType 0 合约类型: 当周|下周|当月|季度 -OpType 0 操作类型: 开多|开空 -MLevel 0 杠杆大小: 10倍|20倍 -TriggerType 0 触发方式: 涨超|跌落 -TriggerPrice 2000 开仓触发价格(元) -OrderPrice 2005 开仓委托价(元) -OrderAmount true 开仓委托量 -StopLossTrigger 1800 止损触发价(元) -StopOrderPrice 1790 止损委托价(元) -LoopInterval 300 轮询间隔(毫秒) -*/ +|参数|默认值|描述| +|----|----|----| +|CType|0|货币类型: 人民币|美元| +|ContractType|0|合约类型: 当周|下周|当月|季度| +|OpType|0|操作类型: 开多|开空| +|MLevel|0|杠杆大小: 10倍|20倍| +|TriggerType|0|触发方式: 涨超|跌落| +|TriggerPrice|2000|开仓触发价格(元)| +|OrderPrice|2005|开仓委托价(元)| +|OrderAmount|true|开仓委托量| +|StopLossTrigger|1800|止损触发价(元)| +|StopOrderPrice|1790|止损委托价(元)| +|LoopInterval|300|轮询间隔(毫秒)| + +> 源码 (javascript) + +``` javascript var _ContractType = ["this_week", "next_week", "month", "quarter"][ContractType]; var _TradeType = ["buy", "sell"][OpType]; var _MarginLevel = [10, 20][MLevel]; @@ -178,3 +189,12 @@ function main() { } Log("完成所有操作, 策略退出."); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/2169 + +> 更新时间 + +2014-12-10 15:33:25 diff --git "a/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245(\346\250\241\346\235\277\346\265\213\350\257\225\344\275\277\347\224\250).md" "b/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245(\346\250\241\346\235\277\346\265\213\350\257\225\344\275\277\347\224\250).md" new file mode 100644 index 00000000..292d613d --- /dev/null +++ "b/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245(\346\250\241\346\235\277\346\265\213\350\257\225\344\275\277\347\224\250).md" @@ -0,0 +1,564 @@ + +> 策略名称 + +OKCoin期货跨期对冲策略(模板测试使用) + +> 策略作者 + +小小梦 + +> 策略描述 + +OKCoin期货跨期对冲策略(模板) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|OpMode|0|现货-下单方式: 吃单|挂单| +|MaxSpace|0.5|现货-挂单失效距离| +|SlidePrice|0.1|现货-下单滑动价(元)| +|MaxAmount|0.8|现货-开仓最大单次下单量| +|RetryDelay|500|现货-失败重试(毫秒)| +|MAType|0|现货-均线算法: EMA|MA|AMA(自适应均线)| +|Interval|300|期货—失败重试间隔(毫秒)| +|F_SlidePrice|2|期货—下单滑价(元)| +|lv|0.5|期货—滑价增长率| +|max_open_lv|true|期货—开仓滑价最大增长率| +|max_cover_lv|true|期货—平仓滑价最大增长率| + + +> 源码 (javascript) + +``` javascript +// 现货部分 +function CancelPendingOrders(e, orderType) { + while (true) { + var orders = e.GetOrders(); + if (!orders) { + Sleep(RetryDelay); + continue; + } + var processed = 0; + for (var j = 0; j < orders.length; j++) { + if (typeof(orderType) === 'number' && orders[j].Type !== orderType) { + continue; + } + e.CancelOrder(orders[j].Id, orders[j]); + processed++; + if (j < (orders.length - 1)) { + Sleep(RetryDelay); + } + } + if (processed === 0) { + break; + } + } +} + +function GetAccount(e, waitFrozen) { + if (typeof(waitFrozen) == 'undefined') { + waitFrozen = false; + } + var account = null; + var alreadyAlert = false; + while (true) { + account = _C(e.GetAccount); + if (!waitFrozen || (account.FrozenStocks < e.GetMinStock() && account.FrozenBalance < 0.01)) { + break; + } + if (!alreadyAlert) { + alreadyAlert = true; + Log("发现账户有冻结的钱或币", account); + } + Sleep(RetryDelay); + } + return account; +} + + +function StripOrders(e, orderId) { + var order = null; + if (typeof(orderId) == 'undefined') { + orderId = null; + } + while (true) { + var dropped = 0; + var orders = _C(e.GetOrders); + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == orderId) { + order = orders[i]; + } else { + var extra = ""; + if (orders[i].DealAmount > 0) { + extra = "成交: " + orders[i].DealAmount; + } else { + extra = "未成交"; + } + e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); + dropped++; + } + } + if (dropped === 0) { + break; + } + Sleep(RetryDelay); + } + return order; +} + +// mode = 0 : direct buy, 1 : buy as buy1 +function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, retryDelay) { + var initAccount = GetAccount(e, true); + var nowAccount = initAccount; + var orderId = null; + var prePrice = 0; + var dealAmount = 0; + var diffMoney = 0; + var isFirst = true; + var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell; + var isBuy = tradeType == ORDER_TYPE_BUY; + while (true) { + var ticker = _C(e.GetTicker); + var tradePrice = 0; + if (isBuy) { + tradePrice = _N((mode === 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4); + } else { + tradePrice = _N((mode === 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4); + } + if (!orderId) { + if (isFirst) { + isFirst = false; + } else { + nowAccount = GetAccount(e, true); + } + var doAmount = 0; + if (isBuy) { + diffMoney = _N(initAccount.Balance - nowAccount.Balance, 4); + dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 4); + doAmount = Math.min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance - 10) / tradePrice, 4)); + } else { + diffMoney = _N(nowAccount.Balance - initAccount.Balance, 4); + dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); + doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); + } + if (doAmount < e.GetMinStock()) { + break; + } + prePrice = tradePrice; + orderId = tradeFunc(tradePrice, doAmount, ticker); + if (!orderId) { + CancelPendingOrders(e, tradeType); + } + } else { + if (mode === 0 || (Math.abs(tradePrice - prePrice) > maxSpace)) { + orderId = null; + } + var order = StripOrders(e, orderId); + if (!order) { + orderId = null; + } + } + Sleep(retryDelay); + } + + if (dealAmount <= 0) { + return null; + } + + return { + price: _N(diffMoney / dealAmount, 4), + amount: dealAmount + }; +} + +$.Buy = function(e, amount) { + if (typeof(e) === 'number') { + amount = e; + e = exchange; + } + return Trade(e, ORDER_TYPE_BUY, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); +}; + +$.Sell = function(e, amount) { + if (typeof(e) === 'number') { + amount = e; + e = exchange; + } + return Trade(e, ORDER_TYPE_SELL, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); +}; + +$.CancelPendingOrders = function(e, orderType) { + if (typeof(orderType) === 'undefined') { + if (typeof(e) === 'number') { + orderType = e; + e = exchange; + } else if (typeof(e) === 'undefined') { + e = exchange; + } + } + return CancelPendingOrders(e, orderType); +}; + +$.GetAccount = function(e) { + if (typeof(e) === 'undefined') { + e = exchange; + } + return _C(e.GetAccount); +}; + +var _MACalcMethod = [TA.EMA, TA.MA, talib.KAMA][MAType]; + +// 返回上穿的周期数. 正数为上穿周数, 负数表示下穿的周数, 0指当前价格一样 +$.Cross = function(a, b) { + var crossNum = 0; + var arr1 = []; + var arr2 = []; + if (Array.isArray(a)) { + arr1 = a; + arr2 = b; + } else { + var records = null; + while (true) { + records = exchange.GetRecords(); + if (records && records.length > a && records.length > b) { + break; + } + Sleep(RetryDelay); + } + arr1 = _MACalcMethod(records, a); + arr2 = _MACalcMethod(records, b); + } + if (arr1.length !== arr2.length) { + throw "array length not equal"; + } + for (var i = arr1.length-1; i >= 0; i--) { + if (typeof(arr1[i]) !== 'number' || typeof(arr2[i]) !== 'number') { + break; + } + if (arr1[i] < arr2[i]) { + if (crossNum > 0) { + break; + } + crossNum--; + } else if (arr1[i] > arr2[i]) { + if (crossNum < 0) { + break; + } + crossNum++; + } else { + break; + } + } + return crossNum; +}; + +// 期货部分 +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) && direction == PD_LONG) || ((positions[i].Type == PD_SHORT) && 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; + var step = 0; + while (true) { + var needOpen = opAmount; + if (isFirst) { + isFirst = false; + } else { + positionNow = GetPosition(e, contractType, direction); + if (positionNow) { + needOpen = opAmount - (positionNow.Amount - initAmount); + } + } + if (needOpen < e.GetMinStock()) { + break; + } + if (step > max_open_lv) { + break; + } + var amount = needOpen; + e.SetDirection(direction == PD_LONG ? "buy" : "sell"); + var orderId; + if (direction == PD_LONG) { + orderId = e.Buy(price + F_SlidePrice * (1 + step), amount, "开多仓", contractType, price); + } else { + orderId = e.Sell(price - F_SlidePrice * (1 + step), amount, "开空仓", contractType, price); + } + + Sleep(Interval) // 增加延迟 避免 调用间隔过小导致 API 反应不过来,调换一下位置,写在合适的位置上, GetOrders 之前,避免刚下单就获取 未完成订单 导致问题。 + + while (true) { + var orders = _C(e.GetOrders); + if (orders.length === 0) { + break; + } + Sleep(Interval); + for (var j = 0; j < orders.length; j++) { + e.CancelOrder(orders[j].Id); + if (j < (orders.length - 1)) { + Sleep(Interval); + } + } + } + step += lv; + // Sleep(Interval) // 增加延迟 避免 调用间隔过小导致 API 反应不过来,调换一下位置,写在合适的位置上, GetOrders 之前,避免刚下单就获取 未完成订单 导致问题。 + } + 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, OP_amount, direction) { + var initP = null; + var positions = null; + var isFirst = true; + var ID = null; + var step = 0; + var index = 0; + var initP_contractTypeAmount = 0 + while (true) { + var n = 0; + positions = _C(e.GetPosition); + if (isFirst === true) { + if (typeof(direction) === 'undefined' && positions.length > 1 || (direction !== PD_LONG && direction !== PD_SHORT && typeof(direction) !== 'undefined')) { + throw "有多,空双向持仓,并且参数direction未明确方向!或 direction 参数异常:" + direction; + } + initP = positions; + isFirst = false; + // 修改BUG + for(var m = 0 ; m < initP.length; m++){ + if(initP[m].ContractType == contractType){ + initP_contractTypeAmount = initP[m].Amount + } + } + } + for (var i = 0; i < positions.length; i++) { + if (positions[i].ContractType != contractType || (positions[i].Type !== direction && typeof(direction) !== 'undefined')) { + continue; + } + var amount = 0; + if (typeof(OP_amount) === 'undefined') { + amount = positions[i].Amount; + } else { + amount = OP_amount - (/*initP[i].Amount*/ initP_contractTypeAmount - positions[i].Amount); + } + + if (amount <= 0) { // 修改为 小于 等于 0 + continue; + } + if (positions[i].Type == PD_LONG) { + e.SetDirection("closebuy"); + ID = e.Sell(price - F_SlidePrice * (1 + step), amount, "平多仓", contractType, price); + n++; + } else if (positions[i].Type == PD_SHORT) { + e.SetDirection("closesell"); + ID = e.Buy(price + F_SlidePrice * (1 + step), amount, "平空仓", contractType, price); + n++; + } + index = i; + } + if (n === 0) { + break; + } + Sleep(Interval); + if (typeof(ID) !== 'number') { + CancelPendingOrders(e); // 测试 + Log("ID:", ID); + continue; + } + + //_C(e.CancelOrder, ID); // 测试修改 e.CancelOrder(ID); + CancelPendingOrders(e); // 测试 + step += lv; + if (step > max_cover_lv) { + break; + } + } + + var nowP = _C(e.GetPosition); + if (!nowP[index] || nowP[index].Type !== initP[index].Type) { + return initP.length === 0 ? 0 : initP[index].Amount; + } else { + var diff = initP[index].Amount - nowP[index].Amount; + return diff; + } +} + +var PositionManager = (function() { + function PositionManager(e) { + if (typeof(e) === 'undefined') { + e = exchange; + } + if (e.GetName() !== 'Futures_OKCoin' && e.GetName() !== 'Futures_BitVC') { + throw 'Only support Futures_OKCoin & Futures_BitVC'; + } + 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); + }; + + 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, OP_amount, direction) { + if (!this.account) { + this.account = _C(exchange.GetAccount); + } + return Cover(this.e, contractType, price, OP_amount, direction); + }; + + PositionManager.prototype.Profit = function(contractType) { + var accountNow = _C(this.e.GetAccount); + Log("NOW:", accountNow, "--account:", this.account); + return _N(accountNow.Balance - this.account.Balance); + }; + + return PositionManager; +})(); + +$.NewPositionManager = function(e) { + return new PositionManager(e); +}; + + +// 测试代码 +function main() { + if (exchange.GetName() === 'Futures_OKCoin') { + var info = exchange.SetContractType("this_week"); + Log("info 返回值:", info); + Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); + var depth = exchange.GetDepth(); + var p = $.NewPositionManager(); + p.OpenShort("this_week", 10, depth.Bids[0].Price - 2); + Log(exchange.GetPosition()); + Sleep(500 * 1000); + depth = exchange.GetDepth(); + var ret = p.Cover("this_week", depth.Bids[0].Price + 2, 5); + Log("cover ret:", ret); + //LogProfit(p.Profit()); + Log(exchange.GetPosition()); + Log("-----------------------------测试分割线----------------------------------------"); + var depth = exchange.GetDepth(); + p.OpenLong("this_week", 20, depth.Bids[0].Price + 2); + Log(exchange.GetPosition()); + Sleep(500 * 1000); + depth = exchange.GetDepth(); + var ret = p.Cover("this_week", depth.Bids[0].Price - 2, 10, PD_LONG); + Log("cover ret:", ret); + Log(exchange.GetPosition()); + Log("-----------------------------测试分割线----------------------------------------"); + var ret = p.Cover("this_week", depth.Bids[0].Price - 3, 10, PD_LONG); + Log("cover ret:", ret); + var ret = p.Cover("this_week", depth.Bids[0].Price + 3, 5, PD_SHORT); + Log("cover ret:", ret); + Log(exchange.GetPosition()); + } else if (exchange.GetName() === 'Futures_BitVC') { + var info = exchange.SetContractType("week"); + Log("info 返回值:", info); + Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); + var depth = exchange.GetDepth(); + var p = $.NewPositionManager(); + p.OpenLong("week", 500, depth.Bids[0].Price + 2); + Log(exchange.GetPosition()); + Sleep(500 * 1000); + depth = exchange.GetDepth(); + var ret = p.Cover("week", depth.Bids[0].Price - 2, 500); + Log("cover ret:", ret); + Log(exchange.GetPosition()); + Log("-----------------------------测试分割线----------------------------------------"); + var info = exchange.SetContractType("week"); + Log("info 返回值:", info); + Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); + var depth = exchange.GetDepth(); + p.OpenShort("week", 600, depth.Bids[0].Price - 2); + Log(exchange.GetPosition()); + Sleep(500 * 1000); + depth = exchange.GetDepth(); + var ret = p.Cover("week", depth.Bids[0].Price + 2, 500, PD_SHORT); + Log("cover ret:", ret); + Log(exchange.GetPosition()); + Log("-----------------------------测试分割线----------------------------------------"); + var ret = p.Cover("week", depth.Bids[0].Price + 3, 100, PD_SHORT); + Log("cover ret:", ret); + //p.Cover("week", depth.Asks[0].Price - 3, 300, PD_LONG); + Log(exchange.GetPosition()); + } else if(exchange.GetName() === 'huobi' || exchange.GetName() === 'OKCoin'){ + Log($.GetAccount()); + Log($.Buy(0.5)); + Log($.Sell(0.5)); + exchange.Buy(1000, 3); + $.CancelPendingOrders(exchanges[0]); + Log($.Cross(30, 7)); + Log($.Cross([1,2,3,2.8,3.5], [3,1.9,2,5,0.6])); + } +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/36762 + +> 更新时间 + +2017-10-22 23:14:09 diff --git "a/OKEX\344\272\244\346\230\223\345\257\271\344\277\241\346\201\257.md" "b/OKEX\344\272\244\346\230\223\345\257\271\344\277\241\346\201\257.md" new file mode 100644 index 00000000..ad80fbf7 --- /dev/null +++ "b/OKEX\344\272\244\346\230\223\345\257\271\344\277\241\346\201\257.md" @@ -0,0 +1,2884 @@ + +> 策略名称 + +OKEX交易对信息 + +> 策略作者 + +leviyuan + + + + + +> 源码 (javascript) + +``` javascript +// https://github.com/okcoin-okex/API-docs-OKEx.com/blob/master/%E5%B8%81%E5%AF%B9%E7%B2%BE%E5%BA%A6(pairs_increment).csv +var data = {} + +$.GetTradeInfo = function(tradeName) { + return data[tradeName] +} + +$.GetAllTradeNames = function() { + var list = [] + for (var n in data) + list[list.length] = n + return list +} + +data.bch_btc = { + base_min_size: 0.001, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.ltc_btc = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.00000001 +} +data.eth_btc = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.00000001 +} +data.etc_btc = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.eth_usdt = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.btc_usdt = { + base_min_size: 0.001, + base_increment: 0.00000001, + quote_increment: 0.0001 +} +data.bt2_btc = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.etc_eth = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.btg_btc = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.ltc_usdt = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.etc_usdt = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.0001 +} +data.bch_usdt = { + base_min_size: 0.001, + base_increment: 0.00000001, + quote_increment: 0.0001 +} +data.qtum_btc = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.qtum_usdt = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.0001 +} +data.qtum_eth = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.neo_btc = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.gas_btc = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.hsr_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.neo_eth = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.gas_eth = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.hsr_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.neo_usdt = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.0001 +} +data.gas_usdt = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.0001 +} +data.hsr_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.dash_btc = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.00000001 +} +data.xrp_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.zec_btc = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.00000001 +} +data.dash_eth = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.00000001 +} +data.xrp_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.zec_eth = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.00000001 +} +data.dash_usdt = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.xrp_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.zec_usdt = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.iota_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.xuc_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.iota_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.xuc_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.iota_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.xuc_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.eos_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.omg_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.eos_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.omg_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.eos_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.omg_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.act_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.btm_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.act_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.btm_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.act_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.btm_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.bcd_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.bcd_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.storj_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.snt_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.storj_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.snt_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.storj_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.snt_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.pay_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.dgd_btc = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.00000001 +} +data.gnt_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.pay_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.dgd_eth = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.00000001 +} +data.gnt_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.pay_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.dgd_usdt = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.gnt_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.lrc_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.nuls_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.mco_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.lrc_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.nuls_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.mco_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.lrc_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.nuls_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.mco_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.btg_usdt = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.0001 +} +data.cmt_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.itc_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.cmt_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.itc_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.cmt_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.itc_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.sbtc_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.pra_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.san_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.edo_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.avt_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.pra_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.san_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.edo_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.avt_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.pra_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.san_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.edo_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.avt_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.ltc_eth = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.00000001 +} +data.link_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.salt_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data["1st_btc"] = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.wtc_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.sngls_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.snm_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.zrx_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.bnt_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.cvc_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.link_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.salt_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data["1st_eth"] = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.wtc_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.sngls_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.snm_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.zrx_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.bnt_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.cvc_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.link_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.salt_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data["1st_usdt"] = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.wtc_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.sngls_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.snm_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.zrx_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.bnt_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.cvc_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.bcx_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.mana_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.rcn_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.mana_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.mana_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.vee_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.vee_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.vee_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.tnb_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.tnb_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.tnb_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.amm_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.amm_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.amm_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.knc_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.knc_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.knc_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.dat_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.dat_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.dat_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.gnx_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.gnx_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.gnx_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.icx_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.icx_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.icx_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.ark_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.ark_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.ark_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.yoyo_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.yoyo_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.yoyo_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.qvt_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.qvt_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.qvt_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.elf_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.elf_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.elf_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.ast_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ast_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ast_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.sub_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.sub_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.sub_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.dnt_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.dnt_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.dnt_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.fun_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.fun_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.fun_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.ace_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.ace_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.ace_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.trx_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.trx_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.trx_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.evx_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.evx_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.evx_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.mda_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.mda_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.mda_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.mth_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.mth_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.mth_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.mtl_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.mtl_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.mtl_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.xem_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.xem_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.xem_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.icn_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.icn_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.icn_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.eng_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.req_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.oax_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.dgb_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.ppt_btc = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.dgb_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.dgb_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.ppt_eth = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.ppt_usdt = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.0001 +} +data.oax_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.oax_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.req_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.req_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.eng_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.eng_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.rcn_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.rcn_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.swftc_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.swftc_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.swftc_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.rdn_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.rdn_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.rdn_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.xmr_btc = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.00000001 +} +data.xmr_eth = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.00000001 +} +data.xmr_usdt = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.xlm_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.xlm_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.xlm_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.kcash_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.kcash_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.kcash_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.mdt_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.mdt_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.mdt_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.nas_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.nas_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.nas_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.rnt_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.rnt_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.rnt_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.wrc_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.wrc_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.wrc_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.ukg_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ukg_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ukg_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.ugc_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.ugc_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.ugc_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.dpy_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.dpy_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.dpy_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.read_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.read_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.read_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.ssc_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.ssc_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.ssc_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.aac_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.fair_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.aac_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.aac_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.fair_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.fair_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.ubtc_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.ubtc_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.ubtc_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.cag_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.cag_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.cag_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.dna_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.lend_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.lend_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.dna_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.lend_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.dna_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.rct_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.rct_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.rct_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.bch_eth = { + base_min_size: 0.001, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.show_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.show_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.show_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.vib_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.vib_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.vib_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.mot_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.mot_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.mot_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.utk_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.utk_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.utk_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.mag_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.mag_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.mag_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.topc_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.topc_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.brd_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.topc_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.qun_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.brd_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.qun_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.qun_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.brd_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.viu_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.viu_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.ost_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.viu_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.ost_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ost_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.aidoc_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.aidoc_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.aidoc_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.int_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.la_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.la_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.la_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.int_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.int_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.ipc_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ipc_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ipc_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.ngc_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ngc_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ngc_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.tio_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.tio_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.tio_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.iost_btc = { + base_min_size: 0.1, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.iost_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.iost_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.poe_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.poe_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.poe_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.mof_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.yee_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.mof_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.yee_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.yee_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.mof_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.ins_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ins_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ins_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.tct_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.tct_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.tct_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.atl_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.atl_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.atl_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.theta_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.theta_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.lev_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.theta_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.lev_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.lev_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.stc_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.spf_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.stc_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.spf_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.spf_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.stc_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.ref_btc = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.ref_eth = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.ref_usdt = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.0001 +} +data.snc_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.snc_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.snc_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.pst_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.pst_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.pst_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.can_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.can_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.can_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.hot_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.mkr_btc = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.00000001 +} +data.mkr_eth = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.00000001 +} +data.mkr_usdt = { + base_min_size: 0.001, + base_increment: 0.00000001, + quote_increment: 0.0001 +} +data.hot_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.key_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.hot_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.key_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.key_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.light_btc = { + base_min_size: 10, + base_increment: 1, + quote_increment: 1E-10 +} +data.light_eth = { + base_min_size: 10, + base_increment: 1, + quote_increment: 0.000000001 +} +data.light_usdt = { + base_min_size: 10, + base_increment: 1, + quote_increment: 0.000001 +} +data.true_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.true_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.true_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.of_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 1E-10 +} +data.of_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 1E-10 +} +data.of_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.000001 +} +data.soc_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.soc_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.soc_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.wbtc_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.dent_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.dent_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.dent_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.zen_btc = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.zen_eth = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.00000001 +} +data.zen_usdt = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.0001 +} +data.hmc_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.hmc_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.hmc_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.zip_btc = { + base_min_size: 10, + base_increment: 1, + quote_increment: 0.000000001 +} +data.zip_eth = { + base_min_size: 10, + base_increment: 1, + quote_increment: 0.00000001 +} +data.zip_usdt = { + base_min_size: 10, + base_increment: 1, + quote_increment: 0.000001 +} +data.nano_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.nano_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.nano_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.cic_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.cic_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.cic_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.gto_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.gto_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.gto_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.chat_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.chat_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.chat_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.insur_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.insur_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.insur_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.cbt_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.cbt_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.cbt_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.r_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.r_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.r_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.uct_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.uct_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.uct_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.bec_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.bec_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.bec_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.mith_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.mith_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.mith_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.abt_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.abt_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.abt_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.bkx_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.bkx_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.bkx_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.gtc_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.gtc_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.gtc_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.auto_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.auto_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.auto_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.gsc_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.gsc_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.gsc_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.rfr_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.rfr_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.rfr_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.trio_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.trio_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.trio_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.tra_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.tra_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.tra_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.ren_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.ren_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.ren_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.wfee_btc = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.wfee_eth = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.00000001 +} +data.wfee_usdt = { + base_min_size: 10, + base_increment: 0.1, + quote_increment: 0.0001 +} +data.dadi_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.dadi_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.dadi_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.enj_btc = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.enj_eth = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.00000001 +} +data.enj_usdt = { + base_min_size: 10, + base_increment: 0.01, + quote_increment: 0.0001 +} +data.ont_btc = { + base_min_size: 0.1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ont_eth = { + base_min_size: 0.1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ont_usdt = { + base_min_size: 0.1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.okb_usdt = { + base_min_size: 1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.okb_btc = { + base_min_size: 1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.okb_eth = { + base_min_size: 1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.ltc_okb = { + base_min_size: 0.01, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.etc_okb = { + base_min_size: 0.01, + base_increment: 0.00001, + quote_increment: 0.0001 +} +data.bch_okb = { + base_min_size: 0.001, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.xrp_okb = { + base_min_size: 0.01, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.eos_okb = { + base_min_size: 0.01, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.qtum_okb = { + base_min_size: 0.01, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.dash_okb = { + base_min_size: 0.01, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.neo_okb = { + base_min_size: 0.01, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.iota_okb = { + base_min_size: 0.01, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.zec_okb = { + base_min_size: 0.01, + base_increment: 0.000001, + quote_increment: 0.0001 +} +data.ctxc_btc = { + base_min_size: 0.01, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ctxc_eth = { + base_min_size: 0.01, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.ctxc_usdt = { + base_min_size: 0.01, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.zil_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.zil_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.zil_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.you_okb = { + base_min_size: 10, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.you_btc = { + base_min_size: 0.1, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.you_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.you_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00001 +} +data.lba_okb = { + base_min_size: 0.1, + base_increment: 0.001, + quote_increment: 0.0001 +} +data.lba_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.lba_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.lba_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.ok06ett_usdt = { + base_min_size: 0.01, + base_increment: 0.00000001, + quote_increment: 0.0001 +} +data.cai_okb = { + base_min_size: 10, + base_increment: 0.001, + quote_increment: 0.000001 +} +data.lsk_btc = { + base_min_size: 0.01, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.lsk_eth = { + base_min_size: 0.01, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.lsk_usdt = { + base_min_size: 0.01, + base_increment: 0.00000001, + quote_increment: 0.0001 +} +data.cai_btc = { + base_min_size: 10, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.cai_eth = { + base_min_size: 10, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.cai_usdt = { + base_min_size: 10, + base_increment: 0.0001, + quote_increment: 0.000001 +} +data.ae_btc = { + base_min_size: 0.01, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.ae_okb = { + base_min_size: 0.01, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.sc_okb = { + base_min_size: 10, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.kan_okb = { + base_min_size: 10, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.win_okb = { + base_min_size: 10, + base_increment: 0.001, + quote_increment: 0.000001 +} +data.sc_eth = { + base_min_size: 10, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.sc_btc = { + base_min_size: 10, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.sc_usdt = { + base_min_size: 10, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.ae_eth = { + base_min_size: 0.01, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.ae_usdt = { + base_min_size: 0.01, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.kan_btc = { + base_min_size: 10, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.kan_eth = { + base_min_size: 10, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.kan_usdt = { + base_min_size: 10, + base_increment: 0.0001, + quote_increment: 0.00001 +} +data.win_btc = { + base_min_size: 10, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.win_eth = { + base_min_size: 10, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.win_usdt = { + base_min_size: 10, + base_increment: 0.001, + quote_increment: 0.000001 +} +data.ors_okb = { + base_min_size: 1, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.mvp_okb = { + base_min_size: 10, + base_increment: 0.0001, + quote_increment: 0.00001 +} +data.dcr_okb = { + base_min_size: 0.01, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.dcr_btc = { + base_min_size: 0.01, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.dcr_eth = { + base_min_size: 0.01, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.dcr_usdt = { + base_min_size: 0.01, + base_increment: 0.00000001, + quote_increment: 0.0001 +} +data.waves_okb = { + base_min_size: 0.01, + base_increment: 0.0001, + quote_increment: 0.0001 +} +data.waves_btc = { + base_min_size: 0.01, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.waves_eth = { + base_min_size: 0.01, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.waves_usdt = { + base_min_size: 0.01, + base_increment: 0.00000001, + quote_increment: 0.0001 +} +data.ors_btc = { + base_min_size: 1, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.ors_eth = { + base_min_size: 1, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.ors_usdt = { + base_min_size: 1, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.mvp_btc = { + base_min_size: 10, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.mvp_eth = { + base_min_size: 10, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.mvp_usdt = { + base_min_size: 10, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.nas_okb = { + base_min_size: 0.1, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.xas_okb = { + base_min_size: 0.1, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.cvt_okb = { + base_min_size: 1, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.nxt_btc = { + base_min_size: 1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.zco_okb = { + base_min_size: 1, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.ardr_btc = { + base_min_size: 1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.egt_okb = { + base_min_size: 1, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.xas_btc = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.xas_eth = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.xas_usdt = { + base_min_size: 0.1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.cvt_btc = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.cvt_eth = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00000001 +} +data.cvt_usdt = { + base_min_size: 1, + base_increment: 0.001, + quote_increment: 0.00001 +} +data.egt_btc = { + base_min_size: 1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.egt_eth = { + base_min_size: 1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.egt_usdt = { + base_min_size: 1, + base_increment: 0.0001, + quote_increment: 0.00001 +} +data.zco_btc = { + base_min_size: 1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.zco_eth = { + base_min_size: 1, + base_increment: 0.0001, + quote_increment: 0.00000001 +} +data.bcn_okb = { + base_min_size: 10, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.bcn_btc = { + base_min_size: 10, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.bcn_usdt = { + base_min_size: 10, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.let_okb = { + base_min_size: 1, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.let_btc = { + base_min_size: 1, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.let_eth = { + base_min_size: 1, + base_increment: 0.00000001, + quote_increment: 0.00000001 +} +data.let_usdt = { + base_min_size: 1, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +data.cit_okb = { + base_min_size: 1, + base_increment: 0.00000001, + quote_increment: 0.00001 +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/117000 + +> 更新时间 + +2018-09-17 00:22:01 diff --git "a/OKEX\346\234\237\347\216\260\345\257\271\345\206\262.md" "b/OKEX\346\234\237\347\216\260\345\257\271\345\206\262.md" new file mode 100644 index 00000000..04891a8c --- /dev/null +++ "b/OKEX\346\234\237\347\216\260\345\257\271\345\206\262.md" @@ -0,0 +1,621 @@ + +> 策略名称 + +OKEX期现对冲 + +> 策略作者 + +alinwo + +> 策略描述 + +策略逻辑 + +此策略会自动检测OKEX上现货和期货的差价,当差价达到期望盈利阀值时,通过等量对冲来获取盈利。 + +策略特色 + +支持OKEX上的所有期货品种(BTC, EOS, BCH, ETH等等) +支持自定义杠杆倍数和合约类型(当周,次周等) +支持自定义盈利期望值(比如年化40%的利润) +详尽的报表(包括详尽的策略状态,交易历史,利润跟踪等) +全自动对冲,不需要人工操作 + +详细说明见我的博客: +http://www.pcclean.io/okex%E6%9C%9F%E7%8E%B0%E5%AF%B9%E5%86%B2js%E6%BA%90%E4%BB%A3%E7%A0%81%E5%88%86%E4%BA%AB%E5%9F%BA%E4%BA%8Efmz-botvs%E5%AE%9E%E7%8E%B0/ + + + +> 源码 (javascript) + +``` javascript +//【OKEX期现对冲】说明 +//============================================================================================================================== +/* + +注意: + 确定操作的ok期货为“全仓模式” + 确定操作的合约类型为“当周” + 严格按照2个一组的顺序添加交易所 BCH/USDC, BCH/USD A:现货 B:期货 + 策略会用USDT/USD汇率修正现货价格! + +版本历史: + 9:51 2018/1/9 first release + 14:57 2018/1/13 正式开始运行 + 15:12 2018/11/15 自动处理强平,提高盈利目标,报表支持显示期货仓位,取消显示交易历史,图标只显示stocks + 23:12 2018/11/15 支持按钮清空所有收益日志 + 16:09 2018/11/16 支持按钮更新收益图表, 用USDT/USD汇率修正现货价格 + +*/ + + + + +var ExchangProcessor={ + + createNew: function(exA,exB){ + //策略参数 + //============================================================================================================================== + var contract_type ="this_week"; //合约类型 + var margin_level =10; //杠杆倍数 + var want_profit =0.01; //想要的额外收入(+汇率损失) + var ignore_range =0.001; //例如USDT对USD, 对冲期的安全波动范围,策略会忽略这个范围的波动 + var max_wait_order =10000; //订单等待 + var wait_ms =3000; //默认等待毫秒 + var traders_recorder =false; //记录所有交易 + + var handfee= {OKEX:0.001, Futures_OKCoin:0.001}; //手续费 + var trade_amount={ETH_USD:0.5, BCH_USD:0.5, BTC_USD:0.05}; //每次交易数量 例如0.5个bch + var contract_min={ETH_USD:10, BCH_USD:10, BTC_USD:100}; //一合约价值多少美金 USD,用这个计算买入张数 + + var price_n ={ETH_USDT:4, ETH_USD:3, BCH_USDT:4, BCH_USD:3, BTC_USDT:4, BTC_USD:2}; //价格精度 + var num_n ={ETH_USDT:3, ETH_USD:0, BCH_USDT:3, BCH_USD:0, BTC_USDT:3, BTC_USD:0}; //数量精度 + var minestbuy ={ETH_USDT:0.001, ETH_USD:1, BCH_USDT:0.001, BCH_USD:1, BTC_USDT:0.001, BTC_USD:1}; //最小买入量 + var price_step ={ETH_USDT:0.03, ETH_USD:0.03, BCH_USDT:0.05, BCH_USD:0.05, BTC_USDT:0.65, BTC_USD:0.65}; //定价单调整价格的单位(每次调整万1, 大致等于25分钟调整%1) + + + + + + //全局状态变量 + //============================================================================================================================== + var pre_time=null; //记录轮询间隔时间 + var limit_orders=[]; //限价单 + var trades=[]; //所有交易 + var pending_pos=[]; //未完成对冲仓位 + var hedging_op=0; //对冲机会 + var hedging_real=0; //真实对冲次数 + var hedging_complete=0; //对冲完成次数 + + + + + + + //构建处理器 + var processor={}; + + //工具函数 + //============================================================================================================================== + //重试购买,直到成功返回 + processor.retryBuy=function(ex,price,num,mode) + { + var currency=ex.GetCurrency(); + var r=ex.Buy(_N(price,price_n[currency]), _N(num,num_n[currency])); + var tempnum=num; + while (!r){ + Log("Buy失败,正在重试。"); + Sleep(wait_ms); + if (mode==="spot"){ + var account=_C(ex.GetAccount); + var ticker=_C(ex.GetTicker); + var last=ticker.Last; + var fixedAmount=Math.min(account.Balance*0.95/last,num); + r=ex.Buy(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); + }else if(mode==="futures"){ + //tempnum=tempnum-1; + if (tempnum===0){ + break; + } + r=ex.Buy(_N(price,price_n[currency]), _N(tempnum,num_n[currency])); + } + } + return r; + } + //重试卖出,直到成功返回 + processor.retrySell=function(ex,price,num,mode){ + var currency=ex.GetCurrency(); + var r=ex.Sell(_N(price,price_n[currency]), _N(num,num_n[currency])); + var tempnum=num; + while (!r){ + Log("Sell失败,正在重试。"); + Sleep(wait_ms); + if (mode==="spot"){ + var account=_C(ex.GetAccount); + var fixedAmount=Math.min(account.Stocks,num); + r=ex.Sell(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); + }else if(mode==="futures"){ + //tempnum=tempnum-1; + var position=_C(ex.GetPosition); + if (tempnum===0 || position.length===0){ + break; + } + r=ex.Sell(_N(price,price_n[currency]), _N(tempnum,num_n[currency])); + + } + } + return r; + } + //获得美元汇率 + processor.getUSDTratio=function(){ + var r = _C(HttpQuery,"https://api.coinmarketcap.com/v2/ticker/825/"); + var o = JSON.parse(r); + return o.data.quotes.USD.price; + } + //获得中国时间 + processor.get_ChinaTimeString=function(){ + var date = new Date(); + var now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); + var cdate=new Date(now_utc); + cdate.setHours(cdate.getHours()+8); + var localstring=cdate.getFullYear()+'/'+(cdate.getMonth()+1)+'/'+cdate.getDate()+' '+cdate.getHours()+':'+cdate.getMinutes()+':'+cdate.getSeconds(); + return localstring; + } + //处理定价单 + processor.process_limiteorders=function(){ + var cur_time=new Date(); + var limit_orders_new=[]; + for (var i=0; imax_wait_order){ + var exchange_c=limit_orders[i].exchange; + var order_ID=limit_orders[i].ID; + var ordermode=limit_orders[i].mode; + var exname=exchange_c.GetName(); + var account=_C(exchange_c.GetAccount); + var ticker=_C(exchange_c.GetTicker); + var last=ticker.Last; + var orderdata=_C(exchange_c.GetOrder,order_ID); + var type=orderdata.Type; + var currency=exchange_c.GetCurrency(); + + if (orderdata.Status!=ORDER_STATE_CLOSED){ + var notcompleted=orderdata.Amount-orderdata.DealAmount; + exchange_c.CancelOrder(order_ID); + if (type===ORDER_TYPE_BUY){ + var allowbuy=notcompleted; + if (allowbuy>=minestbuy[currency]){ + var limited_order_ID=processor.retryBuy(exchange_c,orderdata.Price+price_step[currency],allowbuy,ordermode); + Log("加价买入。"+orderdata.Price+"|"+(orderdata.Price+price_step[currency])); + var limited_order_data={ + exchange:exchange_c, + ID:limited_order_ID, + create_time:new Date(), + utcdate:processor.get_ChinaTimeString(), + mode:ordermode + }; + limit_orders_new.push(limited_order_data); + } + }else if (type===ORDER_TYPE_SELL){ + var allowsell=notcompleted; + if (allowsell>=minestbuy[currency]){ + var limited_order_ID=processor.retrySell(exchange_c,orderdata.Price-price_step[currency],allowsell,ordermode); + Log("降价卖出。"+orderdata.Price+"|"+(orderdata.Price-price_step[currency])); + var limited_order_data={ + exchange:exchange_c, + ID:limited_order_ID, + create_time:new Date(), + utcdate:processor.get_ChinaTimeString(), + mode:ordermode + }; + limit_orders_new.push(limited_order_data); + } + } + + //保存交易信息 + if (type===ORDER_TYPE_BUY){ + var details={ + type:"限价买", + time:limit_orders[i].utcdate, + RealAmount:orderdata.DealAmount, + WantAmount:orderdata.Amount, + RealPrice:orderdata.Price, + WantPrice:orderdata.Price, + Memo:"部分完成", + exname:exname + }; + if (traders_recorder){ + trades.push(details); + } + }else if (type===ORDER_TYPE_SELL){ + var details={ + type:"限价卖", + time:limit_orders[i].utcdate, + RealAmount:orderdata.DealAmount, + WantAmount:orderdata.Amount, + RealPrice:orderdata.Price, + WantPrice:orderdata.Price, + Memo:"部分完成", + exname:exname + }; + if (traders_recorder){ + trades.push(details); + } + } + }else{ + //保存交易信息 + if (type===ORDER_TYPE_BUY){ + var details={ + type:"限价买", + time:limit_orders[i].utcdate, + RealAmount:orderdata.DealAmount, + WantAmount:orderdata.Amount, + RealPrice:orderdata.Price, + WantPrice:orderdata.Price, + Memo:"已完成", + exname:exname + }; + if (traders_recorder){ + trades.push(details); + } + }else if (type===ORDER_TYPE_SELL){ + var details={ + type:"限价卖", + time:limit_orders[i].utcdate, + RealAmount:orderdata.DealAmount, + WantAmount:orderdata.Amount, + RealPrice:orderdata.Price, + WantPrice:orderdata.Price, + Memo:"已完成", + exname:exname + }; + if (traders_recorder){ + trades.push(details); + } + } + } + }else{ + limit_orders_new.push(limit_orders[i]); + } + } + limit_orders=limit_orders_new; + } + //强制执行限价单 + processor.force_limited_order=function(type,ex,price,num,mode){ + if (type==="buy"){ + var buyID=processor.retryBuy(ex,price,num,mode); + var order1={ + exchange:ex, + ID:buyID, + create_time:new Date(), + utcdate:processor.get_ChinaTimeString(), + mode:mode + }; + limit_orders.push(order1); + } + if (type==="sell"){ + var sellID=processor.retrySell(ex,price,num,mode); + var order1={ + exchange:ex, + ID:sellID, + create_time:new Date(), + utcdate:processor.get_ChinaTimeString(), + mode:mode + }; + limit_orders.push(order1); + } + + while(limit_orders.length!==0){ + //process limited orders + processor.process_limiteorders(); + Sleep(wait_ms); + } + } + + + + + + + + + //初始化 + //============================================================================================================================== + processor.init_obj=function(){ + _CDelay(wait_ms); + pre_time = new Date(); + } + + + + + + + + + //处理交易 + //============================================================================================================================== + processor.work=function(){ + var cur_time = new Date(); + var passedtime=cur_time-pre_time; + pre_time=cur_time; + + var USDT_r=processor.getUSDTratio(); + + //get information + var A_account=_C(exA.GetAccount); + var A_exname=exA.GetName(); + var A_currency=exA.GetCurrency(); + var A_quotecurrency=exA.GetQuoteCurrency(); + var A_ticker=_C(exA.GetTicker); + var A_last=A_ticker.Last; + var A_last_fixed=A_last*USDT_r; //Fixed price: ETH/USD + var A_depth=_C(exA.GetDepth); + var A_orders=_C(exA.GetOrders); + var A_buy1=A_depth.Bids[0].Price; + var A_sell1=A_depth.Asks[0].Price; + + exB.SetContractType(contract_type); + exB.SetMarginLevel(margin_level); + var B_account=_C(exB.GetAccount); + var B_exname=exB.GetName(); + var B_currency=exB.GetCurrency(); + var B_quotecurrency=exB.GetQuoteCurrency(); + var B_ticker=_C(exB.GetTicker); + var B_last=B_ticker.Last; + var B_depth=_C(exB.GetDepth); + var B_orders=_C(exB.GetOrders); + var B_buy1=B_depth.Bids[0].Price; + var B_sell1=B_depth.Asks[0].Price; + + var cdiff=Math.abs(B_last-A_last_fixed)/A_last_fixed; + var cdiff2=(B_last-A_last_fixed)/A_last_fixed; + var target_bofu=want_profit+handfee[A_exname]*2+handfee[B_exname]*2+ignore_range; + + + //开始对冲 + if (limit_orders.length===0 && A_last_fixed>B_last && cdiff>target_bofu){ + + hedging_op++; + + var heyuefenshu_B=_N(trade_amount[B_currency]*B_last/contract_min[B_currency],0); + var exact_amount=heyuefenshu_B*contract_min[B_currency]/B_last; + + if (A_account.Stocks*0.9>exact_amount && B_account.Stocks*0.9>exact_amount){ + + hedging_real++; + + //sell 1 bch from A + processor.force_limited_order("sell",exA,A_buy1,exact_amount,"spot"); + //buy 1 bch from B + exB.SetDirection("buy"); + processor.force_limited_order("buy",exB,B_sell1,heyuefenshu_B,"futures"); + + var posA={ + type:'spot-sell', + exchange:exA, + price:A_buy1, + amount:exact_amount, + starttime:processor.get_ChinaTimeString() + }; + pending_pos.push(posA); + var posB={ + type:'futures-buyup', + exchange:exB, + price:B_sell1, + amount:heyuefenshu_B, + starttime:processor.get_ChinaTimeString() + }; + pending_pos.push(posB); + + } + + } + if (limit_orders.length===0 && A_last_fixedtarget_bofu){ + + hedging_op++; + + var heyuefenshu_B=_N(trade_amount[B_currency]*B_last/contract_min[B_currency],0); + var exact_amount=heyuefenshu_B*contract_min[B_currency]/B_last; + + if (A_account.Balance*0.9>exact_amount*A_last && B_account.Stocks*0.9>exact_amount){ + + hedging_real++; + + //buy 1 bch from A + processor.force_limited_order("buy",exA,A_sell1,exact_amount,"spot"); + //sell 1 bch from B + exB.SetDirection("sell"); + processor.force_limited_order("buy",exB,B_sell1,heyuefenshu_B,"futures"); + + var posA={ + type:'spot-buy', + exchange:exA, + price:A_sell1, + amount:exact_amount, + starttime:processor.get_ChinaTimeString() + }; + pending_pos.push(posA); + var posB={ + type:'futures-buydown', + exchange:exB, + price:B_sell1, + amount:heyuefenshu_B, + starttime:processor.get_ChinaTimeString() + }; + pending_pos.push(posB); + + } + } + + //结束对冲 + if (limit_orders.length===0 && cdiff<=ignore_range && A_orders.length===0 && B_orders.length===0 && pending_pos.length>0){ + + hedging_complete++; + + for (var thidx=0; thidx0 && limit_orders.length===0 && A_orders.length===0 && B_orders.length===0){ + Log('检测到Okex的仓位已被强平,执行自动释放对冲仓位。'); + + hedging_complete++; + + for (var thidx=0; thidx 策略出处 + +https://www.fmz.com/strategy/127939 + +> 更新时间 + +2018-11-29 11:23:51 diff --git a/OkEX Websocket Realtime.md b/OkEX Websocket Realtime.md new file mode 100644 index 00000000..834720c6 --- /dev/null +++ b/OkEX Websocket Realtime.md @@ -0,0 +1,140 @@ + +> 策略名称 + +OkEX Websocket Realtime + +> 策略作者 + +FawkesPan + +> 策略描述 + +# OkEX WebSocket API Connecter (compress supported) + + + +> 源码 (python) + +``` python +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# encoding: utf-8 +# +# Market Real-time Subscription +# +# Copyright 2018 FawkesPan +# +# Do What the Fuck You Want To Public License +# + + +import time +import ssl +import sys +import code +import json +import hashlib +import hmac +import urllib +import threading +import websocket +import zlib +import string + +try: + import readline +except ImportError: + pass + +pong = time.time() + +class WSSubscription: + + def __init__(self,symbol='btc',contract_type='this_week',on_message=None): + self.__symbol = symbol.lower() + self.__contract_type = contract_type + self.__Depth = {} + self.__Position = {} + + if on_message is not None: + self.__callbackEnabled = True + self.__callback = on_message + else: + self.__callbackEnabled = False + + thread = threading.Thread(target=self.sub, args=()) + thread.daemon = True + thread.start() + + def GetDepth(self): + return self.__Depth + + def subscribe(self,ws): + + def run(*args): + ws.send("{'event':'addChannel','channel':'ok_sub_futureusd_%s_depth_%s_5'}" % (self.__symbol,self.__contract_type)) + ws.send("{'event':'addChannel','channel':'ok_sub_futureusd_%s_trade_%s'}" % (self.__symbol,self.__contract_type)) + + while True: + ws.send("{'event':'ping'}") + time.sleep(30) + + threading.Thread(target=run).start() + + def sub(self): + + websocket.enableTrace(False) + URL = "wss://real.okex.com:10441/websocket?compress=true" + ws = websocket.WebSocketApp(URL, + on_message=self.incoming, + on_error=self.error_handling, + on_close=self.closing) + + ws.on_open = self.subscribe + + while True: + try: + ws.run_forever() + except: + pass + + pass + + def incoming(self,ws,message): + message = zlib.decompress(message, -zlib.MAX_WBITS) + message = message.decode('utf-8') + global pong + if 'pong' in message: + pong = time.time() + if 'asks' in message and 'bids' in message: + d = json.loads(message) + self.__Depth = d[0]['data'] + self.__Depth['asks'].reverse() + + if self.__callbackEnabled: + self.__callback(message) + + + def error_handling(self,ws,error): + print(str(error)) + + def closing(self,ws): + print("WebSocket Closing...") + +ext.OkEXWS = WSSubscription + +# 模块测试 +def main(): + OkEX = ext.OkEXWS(symbol='btc',contract_type='this_week') + while (True): + Log(OkEX.GetDepth()) + time.sleep(1) +``` + +> 策略出处 + +https://www.fmz.com/strategy/91176 + +> 更新时间 + +2018-11-06 00:13:58 diff --git "a/OkEX \351\253\230\347\272\247API\345\212\237\350\203\275 V.1.1.0 (\346\234\237\350\264\247:\346\211\271\351\207\217\344\270\213\345\215\225,\347\216\260\350\264\247;TBD) Python2-3.md" "b/OkEX \351\253\230\347\272\247API\345\212\237\350\203\275 V.1.1.0 (\346\234\237\350\264\247:\346\211\271\351\207\217\344\270\213\345\215\225,\347\216\260\350\264\247;TBD) Python2-3.md" new file mode 100644 index 00000000..33ad5792 --- /dev/null +++ "b/OkEX \351\253\230\347\272\247API\345\212\237\350\203\275 V.1.1.0 (\346\234\237\350\264\247:\346\211\271\351\207\217\344\270\213\345\215\225,\347\216\260\350\264\247;TBD) Python2-3.md" @@ -0,0 +1,344 @@ + +> 策略名称 + +OkEX 高级API功能 V.1.1.0 (期货:批量下单,现货;TBD) Python2-3 + +> 策略作者 + +FawkesPan + +> 策略描述 + +# OkEX 高级API功能 (FMZ.com) + +### 初始化 +这个库整合了一些 OkEX 高级API 功能,使用前需要进行初始化。 +#### OkEX期货 +``` +# OkEX 期货 +# future 可选参数 this_week next_week quarter , 不填默认 this_week +OkEXFuture = ext.OkEXFuturePlus(exchange, future=string) # 创建一个新的接口对象 +# 多个交易所 +OkEXFuture = ext.OkEXFuturePlus(exchanges[0], future=string) # exchanges[这里取决于你的交易所添加在第几个] +``` +#### OkEX现货 +#还在写 + +### 订单操作-期货 +#### 批量订单 +##### BulkAdd() 添加新订单到本地订单列表 +``` +side price amount 为必填参数 +symbol future 不填则使用默认交易对设置 +matchPrice 默认为False , 设置为True 使用对手价交易 +OkEXFuture.BulkAdd(side=string, price=float, amount=integer, matchPrice=False, symbol=string, future=string) +``` +##### BulkClear() 清除本地未提交订单 +``` +symbol 指定后可清除指定交易对订单 如不指定则清除所有订单 +notify 是否显示日志 默认为显示 +OkEXFuture.BulkClear(symbol=string, notify=True) +``` +##### BulkPost() 提交本地未提交订单 +``` +symbol 指定后只提交指定交易对订单 不指定则提交所有订单 +future 必须同时指定symbol才能使用 指定后只提交特定交易对的特定合约的订单 +OkEXFuture.BulkPost(symbol=string, future=string) +``` +##### BulkOrders() 查看本地未提交订单 +``` +symbol 指定后只查看指定交易对订单 不指定则查看所有订单 +future 必须同时指定symbol才能使用 指定后只查看特定交易对的特定合约的订单 +OkEXFuture.BulkOrders(symbol=string, future=string) +``` + +### 与我联系 +邮箱 i@fawkex.me +电报 [FawkesPan](https://telegram.me/FawkesPan) + +接受策略定制 + +### 关于这个库 +[OkEX API文档](https://github.com/okcoin-okex/API-docs-OKEx.com/) + +[使用 GNU General Public License v3](https://www.gnu.org/licenses/gpl-3.0.en.html) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|LANG|ZH|语言 / Language| + + +> 源码 (python) + +``` python + +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# encoding: utf-8 +# +# OkEX Advanced API Interface for FMZ.com. +# +# Copyright 2018 FawkesPan +# Contact : i@fawkex.me / Telegram@FawkesPan +# +# GNU General Public License v3.0 +# + +import json +import time + +QUOTES = {} +QUOTES['ZH'] = { + 'GREET' : '[OkEX 接口已初始化] 币种: %s 合约: %s. %s', + 'INITF' : '使用的交易所不正确,当前交易所: %s', + 'PARAMERR' : '***传的参数不对 检查你的代码*** %s', + 'NEWORDER' : '[添加订单] 币种: %s 合约: %s 方向: %s 价格: %.4f 数量: %d 张. %s', + 'ORDCOUNT' : '[本次批量发送订单] 总计: %d 条. %s', + 'THISBATCH' : '[信息] 正在处理 币种: %s 合约: %s 条数: %d. %s', + 'ORDSENT' : '[已发送订单] 币种: %s 合约: %s 条数: %d. %s', + 'NEEDSPLIT' : '[信息] 由于单合约单量大于5条 需要进行分片处理. %s', + 'CLEARALL' : '[信息] 已清除所有本地订单. %s', + 'CLEARS' : '[信息] 已清除所有 %s 本地订单. %s', + 'CLEAR' : '[信息] 已清除所有 %s %s 本地订单. %s' +} + +COLORS = { + 'DEEPBLUE' : '#1F618D', + 'BLUE' : '#0000FF', + 'LIGHTBLUE' : '#5DADE2', + 'DEEPGREEN' : '#27AE60', + 'GREEN' : '#00FF00', + 'LIGHTGREEN' : '#58D68D', + 'LAPIS' : '#26619C', + 'DEEPRED' : '#CB4335', + 'RED' : '#FF0000', + 'LIGHTRED' : '#EC7063' +} + + +class OkEXFuture: + + def __init__(self, exchange, future='this_week'): + self.QUOTES = {} + exchange.GetCurrency() + if isinstance(exchange.GetCurrency(), bytes): + self.symbol = str(exchange.GetCurrency(), "utf-8").lower() + name = str(exchange.GetName(), "utf-8") + else: + self.symbol = exchange.GetCurrency() + name = exchange.GetName() + self.IO = exchange.IO + self.future = future + self.bulks = {} + self.bulks[self.symbol] = {} + self.bulks[self.symbol][self.future] = [] + if 'OKCoin' in str(name): + Log(QUOTES[LANG]['GREET'] % (self.symbol.upper(),self.future.upper(),COLORS['LAPIS'])) + else: + Log(QUOTES[LANG]['INITF'] % (name)) + + def BulkAdd(self, side=None, price=None, amount=None, matchPrice=False, symbol=None, future=None): + if type is None or price is None or amount is None: + Log(QUOTES[LANG]['PARAMERR'] % (COLORS['RED'])) + return False + side = side.lower() + if side == 'buy': + tp = 1 + cl = COLORS['DEEPGREEN'] + if side == 'sell': + tp = 2 + cl = COLORS['DEEPRED'] + if side == 'closebuy': + tp = 3 + cl = COLORS['LIGHTRED'] + if side == 'closesell': + tp = 4 + cl = COLORS['LIGHTGREEN'] + if symbol is None: + symbol = self.symbol + if future is None: + future = self.future + + order = {} + order['price'] = price + order['amount'] = amount + order['type'] = tp + + if matchPrice: + order['matchPrice'] = 1 + + try: + self.bulks[symbol] + except KeyError: + self.bulks[symbol] = {} + try: + self.bulks[symbol][future] + except KeyError: + self.bulks[symbol][future] = [] + + self.bulks[symbol][future].append(order) + + Log(QUOTES[LANG]['NEWORDER'] % (symbol.upper(),future.upper(),side.upper(),price,amount,cl)) + + return True + + def BulkOrders(self, symbol=None, future=None): + if symbol is None: + return self.bulks + else: + if future is None: + return self.bulks[symbol] + else: + return self.bulks[symbol][future] + + def BulkClear(self, symbol=None, future=None, notify=True): + if symbol is None: + self.bulks = {} + if notify: + Log(QUOTES[LANG]['CLEARALL'] % (COLORS['RED'])) + else: + if future is None: + self.bulks[symbol] = {} + if notify: + Log(QUOTES[LANG]['CLEARS'] % (symbol.encode().upper(), COLORS['RED'])) + else: + self.bulks[symbol][future] = [] + if notify: + Log(QUOTES[LANG]['CLEAR'] % (symbol.encode().upper(), future.encode().upper(), COLORS['RED'])) + #Log(QUOTES[LANG]['CLEAR'] % (symbol.upper(), future.upper(), COLORS['RED'])) + + return True + + #exchange.IO("api", "POST", "/api/v1/future_batch_trade.do", "symbol=etc_usd&contract_type=this_week&orders_data="+json.dumps(orders)) + def __post(self, symbol='', future=''): + count = len(self.bulks[symbol][future]) + orders = self.bulks[symbol][future] + ret = [] + if count == 0: + return + Log(QUOTES[LANG]['THISBATCH'] % (symbol.upper(),future.upper(),count,COLORS['LAPIS'])) + if count <= 5: + params = 'symbol=%s&contract_type=%s&orders_data=%s' % (symbol, future, json.dumps(orders)) + res = self.IO("api", "POST", "/api/v1/future_batch_trade.do", params) + ret+=res['order_info'] + Log(QUOTES[LANG]['ORDSENT'] % (symbol.upper(),future.upper(),len(orders),COLORS['LAPIS'])) + if count > 5: + Log(QUOTES[LANG]['NEEDSPLIT'] % (COLORS['LAPIS'])) + batch = [] + for item in orders: + batch.append(item) + if len(batch) == 5: + params = 'symbol=%s&contract_type=%s&orders_data=%s' % (symbol, future, json.dumps(batch)) + res = self.IO("api", "POST", "/api/v1/future_batch_trade.do", params) + try: + ret+=res['order_info'] + except: + pass + Log(QUOTES[LANG]['ORDSENT'] % (symbol.upper(),future.upper(),len(batch),COLORS['LAPIS'])) + batch = [] + time.sleep(0.3) # OkEX限制每秒只能进行三个请求 + + params = 'symbol=%s&contract_type=%s&orders_data=%s' % (symbol, future, json.dumps(batch)) + res = self.IO("api", "POST", "/api/v1/future_batch_trade.do", params) + try: + ret+=res['order_info'] + except: + pass + Log(QUOTES[LANG]['ORDSENT'] % (symbol.upper(),future.upper(),len(batch),COLORS['LAPIS'])) + + return ret + + def BulkPost(self, symbol=None, future=None): + ret = [] + count = 0 + if symbol is None: + symbols = self.bulks.keys() + for s in symbols: + futures = self.bulks[s].keys() + for f in futures: + count+=len(self.bulks[s][f]) + ret+=self.__post(s, f) + time.sleep(0.3) # OkEX限制每秒只能进行三个请求 + + self.BulkClear(notify=False) + else: + if future is None: + futures = self.bulks[symbol].keys() + for f in futures: + count+=len(self.bulks[symbol][f]) + ret+=self.__post(symbol, f) + time.sleep(0.3) # OkEX限制每秒只能进行三个请求 + + self.BulkClear(symbol=symbol, notify=False) + else: + count+=len(self.bulks[symbol][future]) + ret+=self.__post(symbol, future) + + self.BulkClear(symbol=symbol, future=future, notify=False) + + Log(QUOTES[LANG]['ORDCOUNT'] % (count,COLORS['LAPIS'])) + return ret + +class OkEXSpot: + + def __init__(self, exchange): + self.IO = exchange.IO + + #TBD + +ext.OkEXFuturePlus = OkEXFuture # 导出OkEXFuture Class, 主策略可以通过FuturePlus = ext.OkEXFuturePlus(exchange, future)调用 +ext.OkEXSpotPlus = OkEXSpot # 导出OkEXSpot Class, 主策略可以通过SpotPlus = ext.OkEXSpotPlus(exchange)调用 + +# 模块功能测试 +def main(): + LogReset() + Log(exchange.GetAccount()) + OKEXPlus = ext.OkEXFuturePlus(exchange) + # 4 Buy 2 Sell 1 next_week + base_price = exchange.GetTicker()['Last'] + OKEXPlus.BulkAdd("sell", base_price*1.2, 1) + OKEXPlus.BulkAdd("closebuy", base_price*1.2, 1) + OKEXPlus.BulkAdd("sell", base_price*1.3, 1) + OKEXPlus.BulkAdd("buy", base_price*0.7, 1, future='next_week') + + OKEXPlus.BulkClear() + + OKEXPlus.BulkAdd("buy", base_price*0.8, 1) + OKEXPlus.BulkAdd("closebuy", base_price*1.2, 1) + OKEXPlus.BulkAdd("sell", base_price*1.3, 1) + OKEXPlus.BulkAdd("buy", base_price*0.7, 1, future='next_week') + + OKEXPlus.BulkClear(symbol=(exchange.GetCurrency()).lower(),future='this_week') + OKEXPlus.BulkClear(symbol=(exchange.GetCurrency()).lower(),future='next_week') + + OKEXPlus.BulkAdd("buy", base_price*0.8, 1) + OKEXPlus.BulkAdd("buy", base_price*0.7, 1, future='next_week') + OKEXPlus.BulkClear(symbol=(exchange.GetCurrency()).lower()) + + OKEXPlus.BulkAdd("buy", base_price*0.8, 1) + OKEXPlus.BulkAdd("buy", base_price*0.81, 1) + OKEXPlus.BulkAdd("buy", base_price*0.82, 1) + OKEXPlus.BulkAdd("closesell", base_price*0.8, 1) + OKEXPlus.BulkAdd("sell", base_price*1.2, 1) + OKEXPlus.BulkAdd("closebuy", base_price*1.2, 1) + OKEXPlus.BulkAdd("sell", base_price*1.3, 1) + OKEXPlus.BulkAdd("buy", base_price*0.7, 1, future='next_week') + + Log(OKEXPlus.BulkOrders()) + for item in OKEXPlus.BulkPost(): + Log(str(item)) + Log(OKEXPlus.BulkOrders()) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/113979 + +> 更新时间 + +2018-11-12 20:55:49 diff --git "a/Paul \"The Gambler\" L\303\251vy.md" "b/Paul \"The Gambler\" L\303\251vy.md" new file mode 100644 index 00000000..507a8e79 --- /dev/null +++ "b/Paul \"The Gambler\" L\303\251vy.md" @@ -0,0 +1,261 @@ + +> 策略名称 + +Paul "The Gambler" Lévy + +> 策略作者 + +FawkesPan + +> 策略描述 + +###### 期货赌徒策略 +##### 方向做错了就自动反向翻倍开仓 +#### 实盘会亏完所有钱!!! +### 实盘会亏完所有钱!!! +## 实盘会亏完所有钱!!! +# 实盘会亏完所有钱!!! + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|STOP_LOSS|0.015|止损距离| +|TAKE_PROFIT|0.03|止盈距离| +|START_SIZE|true|初始仓位| +|RISK_LIMIT|1025|最大仓位| +|LEVERAGE_RATE|20|杠杆大小| +|CONTRACT_TYPE|this_week|合约类型| +|DELAY|30|刷新间隔| +|AMP|2|反向倍数| + + +> 源码 (python) + +``` python + + +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# encoding: utf-8 +# +# Paul "The Gambler" Lévy. +# +# Copyright 2018 FawkesPan +# Contact : i@fawkex.me / Telegram@FawkesPan +# +# Do What the Fuck You Want To Public License +# + +import random +from math import * + +Account = {} +Ticker = {} +LPosition = 0 +SPosition = 0 +Positions = {} +TotalLoss = 0 +TotalWin = 0 +FullLoss = 0 +MaxPosition = 0 +TotalLongs = 0 +TotalShorts = 0 + +def cancelAllOrders(): + orders = exchange.GetOrders() + for order in orders: + exchange.CancelOrder(order['Id'], order) + return True + +def updateMarket(): + global Ticker + + Ticker = exchange.GetTicker() + + return True + +def updateAccount(): + global Account + global LPosition + global SPosition + global Positions + global MaxPosition + + LPosition = 0 + SPosition = 0 + Positions = {} + for item in exchange.GetPosition(): + if item['MarginLevel'] == LEVERAGE_RATE: + if item['Type'] == 1: + Positions['Short'] = item + SPosition += item['Amount'] + else: + Positions['Long'] = item + LPosition += item['Amount'] + MaxPosition = max(MaxPosition, SPosition, LPosition) + + Account = exchange.GetAccount() + + return True + +def updatePositions(): + global TotalWin + global TotalLoss + global FullLoss + + opened = False + + try: + Long = Positions['Long']['Amount'] + LongEntry = Positions['Long']['Price'] + Current = Ticker['Sell'] + + StopLoss = LongEntry * (1-STOP_LOSS) + TakeProfit = LongEntry * (1+TAKE_PROFIT) + + if Current > TakeProfit: + Risked = True + Log('多仓达到预设止盈价位. #0000FF') + TotalWin+=1 + Log('总计止盈次数: ', TotalWin, ' 总计止损次数: ', TotalLoss, ' 完全止损次数: ', FullLoss, ' 持有过的最大仓位: ', MaxPosition, ' 总计开多: ', TotalLongs, ' 总计开空: ', TotalShorts) + coverLong(Long, True) + if Current < StopLoss: + Risked = True + Log('多仓达到预设止损价位. #FF0000') + TotalLoss+=1 + Log('总计止盈次数: ', TotalWin, ' 总计止损次数: ', TotalLoss, ' 完全止损次数: ', FullLoss, ' 持有过的最大仓位: ', MaxPosition, ' 总计开多: ', TotalLongs, ' 总计开空: ', TotalShorts) + coverLong(Long, True) + if Long*AMP < RISK_LIMIT: + openShort(Long*AMP, True) + else: + FullLoss+=1 + Log('超过允许的最大仓位,停止开仓. #FF0000') + Log('总计止盈次数: ', TotalWin, ' 总计止损次数: ', TotalLoss, ' 完全止损次数: ', FullLoss, ' 持有过的最大仓位: ', MaxPosition, ' 总计开多: ', TotalLongs, ' 总计开空: ', TotalShorts) + + opened = True + except KeyError: + pass + + try: + Short = Positions['Short']['Amount'] + ShortEntry = Positions['Short']['Price'] + Current = Ticker['Buy'] + + StopLoss = ShortEntry * (1+STOP_LOSS) + TakeProfit = ShortEntry * (1-TAKE_PROFIT) + + if Current < TakeProfit: + Risked = True + Log('空仓达到预设止盈价位. #0000FF') + TotalWin+=1 + Log('总计止盈次数: ', TotalWin, ' 总计止损次数: ', TotalLoss, ' 完全止损次数: ', FullLoss, ' 持有过的最大仓位: ', MaxPosition, ' 总计开多: ', TotalLongs, ' 总计开空: ', TotalShorts) + coverShort(Short, True) + if Current > StopLoss: + Risked = True + Log('空仓达到预设止损价位. #FF0000') + TotalLoss+=1 + Log('总计止盈次数: ', TotalWin, ' 总计止损次数: ', TotalLoss, ' 完全止损次数: ', FullLoss, ' 持有过的最大仓位: ', MaxPosition, ' 总计开多: ', TotalLongs, ' 总计开空: ', TotalShorts) + coverShort(Short, True) + if Short*AMP < RISK_LIMIT: + openLong(Short*AMP, True) + else: + FullLoss+=1 + Log('超过允许的最大仓位,停止开仓. #FF0000') + Log('总计止盈次数: ', TotalWin, ' 总计止损次数: ', TotalLoss, ' 完全止损次数: ', FullLoss, ' 持有过的最大仓位: ', MaxPosition, ' 总计开多: ', TotalLongs, ' 总计开空: ', TotalShorts) + + opened = True + except KeyError: + pass + + if not opened: + Log('还没开仓,随便开个仓位.') + rand = random.choice([1,2,3,4,5,6]) + if rand in [1,3,5]: + Log('骰子抛到了: ',rand,' 正在开多.') + openLong(START_SIZE, True) + else: + Log('骰子抛到了: ',rand,' 正在开空.') + openShort(START_SIZE, True) + + return True + +def openLong(Amount=0, marketPrice=False): + global TotalLongs + + Amount = floor(Amount) + + TotalLongs+=Amount + + exchange.SetDirection('buy') + + if marketPrice: + exchange.Buy(Ticker['Sell']*1.01, Amount) + else: + exchange.Buy(Ticker['Sell'], Amount) + + return True + +def coverLong(Amount=0, marketPrice=False): + exchange.SetDirection('closebuy') + + if marketPrice: + exchange.Sell(Ticker['Buy']*0.99, Amount) + else: + exchange.Sell(Ticker['Buy'], Amount) + + return True + +def openShort(Amount=0, marketPrice=False): + global TotalShorts + + Amount = floor(Amount) + + TotalShorts+=Amount + + exchange.SetDirection('sell') + + if marketPrice: + exchange.Sell(Ticker['Buy']*0.99, Amount) + else: + exchange.Sell(Ticker['Buy'], Amount) + + return True + +def coverShort(Amount=0, marketPrice=False): + exchange.SetDirection('closesell') + + if marketPrice: + exchange.Buy(Ticker['Sell']*1.01, Amount) + else: + exchange.Buy(Ticker['Sell'], Amount) + + return True + +def onTick(): + cancelAllOrders() + updateMarket() + updateAccount() + updatePositions() + + return True + +def main(): + exchange.SetContractType(CONTRACT_TYPE) + exchange.SetMarginLevel(LEVERAGE_RATE) + + while True: + onTick() + Sleep(DELAY*1000) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/117768 + +> 更新时间 + +2018-09-21 01:34:13 diff --git "a/Push Binance deal order to WeChat|\345\256\236\346\227\266\346\216\250\351\200\201\345\270\201\345\256\211\346\210\220\344\272\244\345\210\260\345\276\256\344\277\241(wss\345\215\217\350\256\256\347\273\203\344\271\240\357\274\211.md" "b/Push Binance deal order to WeChat|\345\256\236\346\227\266\346\216\250\351\200\201\345\270\201\345\256\211\346\210\220\344\272\244\345\210\260\345\276\256\344\277\241(wss\345\215\217\350\256\256\347\273\203\344\271\240\357\274\211.md" new file mode 100644 index 00000000..d4967f31 --- /dev/null +++ "b/Push Binance deal order to WeChat|\345\256\236\346\227\266\346\216\250\351\200\201\345\270\201\345\256\211\346\210\220\344\272\244\345\210\260\345\276\256\344\277\241(wss\345\215\217\350\256\256\347\273\203\344\271\240\357\274\211.md" @@ -0,0 +1,53 @@ + +> 策略名称 + +Push Binance deal order to WeChat|实时推送币安成交到微信(wss协议练习) + +> 策略作者 + +botvsing + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|APIKEY||your binance API Key| + + +> 源码 (javascript) + +``` javascript +function main() { + var listenKey = JSON.parse(HttpQuery('https://api.binance.com/api/v1/userDataStream','',null,'X-MBX-APIKEY:'+APIKEY)).listenKey; + HttpQuery('https://api.binance.com/api/v1/userDataStream', {method:'DELETE',data:'listenKey='+listenKey}, null,'X-MBX-APIKEY:'+ APIKEY); + listenKey = JSON.parse(HttpQuery('https://api.binance.com/api/v1/userDataStream','',null,'X-MBX-APIKEY:'+ APIKEY)).listenKey; + var datastream = Dial("wss://stream.binance.com:9443/ws/"+listenKey, 100); + var update_listenKey_time = Date.now()/1000; + while (true){ + if (Date.now()/1000 - update_listenKey_time > 1800){ + update_listenKey_time = Date.now()/1000; + HttpQuery('https://api.binance.com/api/v1/userDataStream', {method:'PUT',data:'listenKey='+listenKey}, null,'X-MBX-APIKEY:'+ APIKEY); + Log('keep listenKey alive'); + } + var data = datastream.read(); + if(data){ + data = JSON.parse(data); + if(data.e == 'executionReport' && data.x == 'TRADE'){ + Log(data.S, data.s, 'amount is ', data.l, 'at price:', data.p, '@'); + } + } + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/122649 + +> 更新时间 + +2018-10-20 15:06:05 diff --git "a/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" "b/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.md" similarity index 84% rename from "Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" rename to "Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.md" index d8c34876..8fa5b453 100644 --- "a/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.py" +++ "b/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.md" @@ -1,8 +1,13 @@ -''' -策略出处: https://www.fmz.com/strategy/43965 -策略名称: Python 精简多品种 MACD 趋势策略 -策略作者: Zero -策略描述: + +> 策略名称 + +Python 精简多品种 MACD 趋势策略 + +> 策略作者 + +Zero + +> 策略描述 需要引用小小梦公开的商品期货交易类库 @@ -10,13 +15,19 @@ https://www.botvs.com/strategy/24288 +> 策略参数 + -参数 默认值 描述 ------------- ------------ ---- -Amount 2 开仓手数 -ContractList MA701,rb1701 合约列表 -''' +|参数|默认值|描述| +|----|----|----| +|Amount|2|开仓手数| +|ContractList|MA701,rb1701|合约列表| + + +> 源码 (python) + +``` python ''' /*backtest start: 2016-01-30 @@ -77,3 +88,12 @@ def main(): t.onTick() q.poll() Sleep(1000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/43965 + +> 更新时间 + +2017-06-30 10:15:54 diff --git "a/Python API \346\265\213\350\257\225.py" "b/Python API \346\265\213\350\257\225.md" similarity index 94% rename from "Python API \346\265\213\350\257\225.py" rename to "Python API \346\265\213\350\257\225.md" index b181a122..81730463 100644 --- "a/Python API \346\265\213\350\257\225.py" +++ "b/Python API \346\265\213\350\257\225.md" @@ -1,13 +1,21 @@ -''' -策略出处: https://www.fmz.com/strategy/21365 -策略名称: Python API 测试 -策略作者: Zero -策略描述: + +> 策略名称 + +Python API 测试 + +> 策略作者 + +Zero + +> 策略描述 Python API 测试 -''' + +> 源码 (python) + +``` python import sys import time import talib @@ -119,3 +127,12 @@ def main(): x.add(0, [ts, ticker.Buy]) x.add(1, [ts, ticker.Sell]) Sleep(10000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/21365 + +> 更新时间 + +2016-12-18 18:00:34 diff --git "a/Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.py" "b/Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.md" similarity index 91% rename from "Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.py" rename to "Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.md" index 56f4cdc0..53ac70d6 100644 --- "a/Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.py" +++ "b/Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.md" @@ -1,26 +1,40 @@ -''' -策略出处: https://www.fmz.com/strategy/21023 -策略名称: Python 双平台对冲策略 -策略作者: Zero -策略描述: + +> 策略名称 Python 双平台对冲策略 +> 策略作者 + +Zero + +> 策略描述 + +Python 双平台对冲策略 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|MinSpreadA|0.51|A->B差价| +|MinSpreadB|0.52|B->A差价| +|MaxAmount|0.3|最大操作量| +|BalanceTime|10|平衡周期(秒)| +|LoopInterval|200|轮询周期(ms)| -参数 默认值 描述 ------------- ------ -------- -MinSpreadA 0.51 A->B差价 -MinSpreadB 0.52 B->A差价 -MaxAmount 0.3 最大操作量 -BalanceTime 10 平衡周期(秒) -LoopInterval 200 轮询周期(ms) -按钮 默认值 描述 ----- ----- ---------- -A->B 0.51 更改价差(A->B) -B->A 0.52 更改价差(B->A) -''' + +|按钮|默认值|描述| +|----|----|----| +|A->B|0.51|更改价差(A->B)| +|B->A|0.52|更改价差(B->A)| + + +> 源码 (python) + +``` python import time import json @@ -167,3 +181,12 @@ def main(): hedgeNum[HPos] += 1 +``` + +> 策略出处 + +https://www.fmz.com/strategy/21023 + +> 更新时间 + +2016-09-26 11:33:18 diff --git "a/Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.py" "b/Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.md" similarity index 92% rename from "Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.py" rename to "Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.md" index 0623dff2..6ba754ca 100644 --- "a/Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.py" +++ "b/Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.md" @@ -1,8 +1,13 @@ -''' -策略出处: https://www.fmz.com/strategy/21370 -策略名称: Python 机器学习之 SVM 预测买卖 -策略作者: Zero -策略描述: + +> 策略名称 + +Python 机器学习之 SVM 预测买卖 + +> 策略作者 + +Zero + +> 策略描述 Python入门简单策略 sklearn 机器学习库的使用 @@ -11,12 +16,18 @@ 实盘需要在托管者所在机器安装策略需要的库 +> 策略参数 + + -参数 默认值 描述 ---------- ----- ---- -SpreadVal 2 预测价差 -''' +|参数|默认值|描述| +|----|----|----| +|SpreadVal|2|预测价差| + +> 源码 (python) + +``` python from sklearn import svm import numpy as np @@ -106,3 +117,12 @@ def main(): if marketPosition == 0: LogProfit(_N(nowAccount.Balance - initAccount.Balance, 4), nowAccount) +``` + +> 策略出处 + +https://www.fmz.com/strategy/21370 + +> 更新时间 + +2018-06-05 16:46:36 diff --git "a/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" "b/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).md" similarity index 95% rename from "Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" rename to "Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).md" index 1c8a9507..e579ea70 100644 --- "a/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).py" +++ "b/Python\347\211\210 TableTemplet (\346\265\213\350\257\225\347\211\210).md" @@ -1,13 +1,19 @@ -''' -策略出处: https://www.fmz.com/strategy/46031 -策略名称: Python版 TableTemplet (测试版) -策略作者: 小小梦 -策略描述: +> 策略名称 +Python版 TableTemplet (测试版) -''' +> 策略作者 +小小梦 + + + + + +> 源码 (python) + +``` python # TableTemplet import json listener = {} @@ -159,3 +165,12 @@ def main(): +``` + +> 策略出处 + +https://www.fmz.com/strategy/46031 + +> 更新时间 + +2018-01-13 17:44:46 diff --git "a/Python\347\256\200\345\215\225\346\265\213\350\257\225\347\255\226\347\225\245.py" "b/Python\347\256\200\345\215\225\346\265\213\350\257\225\347\255\226\347\225\245.md" similarity index 83% rename from "Python\347\256\200\345\215\225\346\265\213\350\257\225\347\255\226\347\225\245.py" rename to "Python\347\256\200\345\215\225\346\265\213\350\257\225\347\255\226\347\225\245.md" index b263687f..bb76c88f 100644 --- "a/Python\347\256\200\345\215\225\346\265\213\350\257\225\347\255\226\347\225\245.py" +++ "b/Python\347\256\200\345\215\225\346\265\213\350\257\225\347\255\226\347\225\245.md" @@ -1,20 +1,31 @@ -''' -策略出处: https://www.fmz.com/strategy/20761 -策略名称: Python简单测试策略 -策略作者: Zero -策略描述: + +> 策略名称 + +Python简单测试策略 + +> 策略作者 + +Zero + +> 策略描述 需要下载最新的托管者, 托管者机器个需要安装python, (Linux自带无需安装) +> 策略参数 + + -参数 默认值 描述 ----- ------- ------------------- -a 1.2 number -b 你好hello str -c true bool -d 0 select: abc|def|xxx -''' +|参数|默认值|描述| +|----|----|----| +|a|1.2|number| +|b|你好hello|str| +|c|true|bool| +|d|0|select: abc|def|xxx| + +> 源码 (python) + +``` python import time import talib @@ -74,3 +85,12 @@ def main(): x.add(1, [ts, ticker.Sell]) LogStatus(ticker) Sleep(10000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/20761 + +> 更新时间 + +2018-06-05 16:43:46 diff --git "a/R-Breaker \344\272\244\346\230\223\347\255\226\347\225\245.py" "b/R-Breaker \344\272\244\346\230\223\347\255\226\347\225\245.md" similarity index 97% rename from "R-Breaker \344\272\244\346\230\223\347\255\226\347\225\245.py" rename to "R-Breaker \344\272\244\346\230\223\347\255\226\347\225\245.md" index b6619dbc..91489a5a 100644 --- "a/R-Breaker \344\272\244\346\230\223\347\255\226\347\225\245.py" +++ "b/R-Breaker \344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -1,13 +1,21 @@ -''' -策略出处: https://www.fmz.com/strategy/23531 -策略名称: R-Breaker 交易策略 -策略作者: 太极 -策略描述: + +> 策略名称 + +R-Breaker 交易策略 + +> 策略作者 + +太极 + +> 策略描述 R-Breaker 交易策略 -''' + +> 源码 (python) + +``` python #!/usr/local/bin/python #-*- coding: UTF-8 -*- #R-Breaker 交易策略 @@ -224,3 +232,12 @@ def main(): Sleep(1000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/23531 + +> 更新时间 + +2016-10-28 19:37:57 diff --git "a/R-Breaker11 \344\272\244\346\230\223\347\255\226\347\225\245.py" "b/R-Breaker11 \344\272\244\346\230\223\347\255\226\347\225\245.md" similarity index 98% rename from "R-Breaker11 \344\272\244\346\230\223\347\255\226\347\225\245.py" rename to "R-Breaker11 \344\272\244\346\230\223\347\255\226\347\225\245.md" index 9cca28bc..651baa7d 100644 --- "a/R-Breaker11 \344\272\244\346\230\223\347\255\226\347\225\245.py" +++ "b/R-Breaker11 \344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -1,13 +1,21 @@ -''' -策略出处: https://www.fmz.com/strategy/23874 -策略名称: R-Breaker11 交易策略 -策略作者: 太极 -策略描述: + +> 策略名称 + +R-Breaker11 交易策略 + +> 策略作者 + +太极 + +> 策略描述 R-Breaker 交易策略 -''' + +> 源码 (python) + +``` python # botvs@f976b25629baf8373e73da860a54030d #!/usr/local/bin/python #-*- coding: UTF-8 -*- @@ -334,3 +342,12 @@ def main(): nowAccount = ext.GetAccount() #交易模板的导出函数 获取账户信息 print_log(0,nowAccount) Sleep(1000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/23874 + +> 更新时间 + +2017-02-13 11:58:17 diff --git a/README.md b/README.md index 5b7b51d8..4800b71f 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,97 @@ > 开源策略列表 + - [RUMI策略](https://www.fmz.com/strategy/129082) + - [日本云图简化版策略](https://www.fmz.com/strategy/129083) + - [高胜率ORB交易策略](https://www.fmz.com/strategy/129084) + - [麦语言海龟策略体验](https://www.fmz.com/strategy/126968) + - [升级版恒温器策略](https://www.fmz.com/strategy/129086) + - [Dual Thrust (麦语言版)](https://www.fmz.com/strategy/128884) + - [传统均线指标与KD指标的交易策略](https://www.fmz.com/strategy/128249) + - [双均线策略与相对强弱RSI指标组合](https://www.fmz.com/strategy/128250) + - [抛物线转向SAR与价格高低点策略](https://www.fmz.com/strategy/128251) + - [波动率ATR轨道突破策略](https://www.fmz.com/strategy/128252) + - [价格高低点与一目均线双重趋势策略](https://www.fmz.com/strategy/128415) + - [动向指数(DMI)与高低点策略](https://www.fmz.com/strategy/128418) + - [MACD+MA指标组合策略](https://www.fmz.com/strategy/128134) + - [双均线DDI策略](https://www.fmz.com/strategy/128133) + - [高低点突破成交量指数加权策略](https://www.fmz.com/strategy/128125) + - [标准差价格通道策略](https://www.fmz.com/strategy/128121) + - [基于ATR波动率指标构建的通道策略](https://www.fmz.com/strategy/128126) + - [三均线顺势价格突破策略](https://www.fmz.com/strategy/128130) + - [高低点与波动率ROC指标策略](https://www.fmz.com/strategy/128417) + - [瀑布线策略](https://www.fmz.com/strategy/128420) + - [Bitmex仓位变化推送微信(wss协议,需要bitmex api ID)|Bitmex position-change push(websocket)](https://www.fmz.com/strategy/128624) + - [开收盘均价差ATR策略](https://www.fmz.com/strategy/128136) + - [多级止盈趋势策略](https://www.fmz.com/strategy/128122) + - [三轨道波动率策略](https://www.fmz.com/strategy/128129) + - [基于ATR波动率指标构建的通道策略](https://www.fmz.com/strategy/127691) + - [海龟](https://www.fmz.com/strategy/128382) + - [OKEX期现对冲](https://www.fmz.com/strategy/127939) + - [商品期货交易类库(旧版)](https://www.fmz.com/strategy/127341) + - [现现对冲(搬砖)](https://www.fmz.com/strategy/127154) + - [你不知道的MACD+MA指标组合策略](https://www.fmz.com/strategy/127101) + - [BitMEX 高级API功能 V.1.1.0 (期货:批量下单,编辑订单,冰山订单,一键撤单,定时撤单) Python2/3](https://www.fmz.com/strategy/114148) + - [OkEX 高级API功能 V.1.1.0 (期货:批量下单,现货;TBD) Python2/3](https://www.fmz.com/strategy/113979) + - [多交易所集合行情/下单 策略 范例](https://www.fmz.com/strategy/125569) + - [使用画线类库画K线以及均线图表范例](https://www.fmz.com/strategy/125770) + - [MA5](https://www.fmz.com/strategy/125474) + - [设定价格微信推送(教学)](https://www.fmz.com/strategy/125482) + - [OkEX Websocket Realtime](https://www.fmz.com/strategy/91176) + - [移植 OKCoin 韭菜收割机 注释](https://www.fmz.com/strategy/124178) + - [Binance buy and sell statistics|币安买卖统计](https://www.fmz.com/strategy/121917) + - [Push Binance deal order to WeChat|实时推送币安成交到微信(wss协议练习)](https://www.fmz.com/strategy/122649) + - [Get cryptocurrency current and max supply|获取币种供应量](https://www.fmz.com/strategy/122370) + - [指数均衡策略 (教学)](https://www.fmz.com/strategy/120581) + - [指数平衡策略|Index Balance Bot](https://www.fmz.com/strategy/116012) + - [简单均线策略|Moving Average Bot 30 lines](https://www.fmz.com/strategy/103070) + - [币安取消所有交易对未完成订单(IO扩展示范)|Cancel ALL Binance Orders](https://www.fmz.com/strategy/121549) + - [冰山委托卖出简单版|Simple Iceberg order to sell](https://www.fmz.com/strategy/121524) + - [冰山委托买入简单版|Simple Iceberg order to buy](https://www.fmz.com/strategy/121522) + - [简单预定买入后卖出机器人|Buy then Sell (ping-pong strategy)](https://www.fmz.com/strategy/121228) + - [简单固定价格止损机器人|Stop Loss Below Fixed Price](https://www.fmz.com/strategy/121081) + - [经典均线策略](https://www.fmz.com/strategy/12348) + - [闪崩机器人 (教学)](https://www.fmz.com/strategy/118939) + - [模拟测试kdj](https://www.fmz.com/strategy/119057) + - [BTC-V反策略](https://www.fmz.com/strategy/117202) + - [合成任意周期K线 使用请看源码最下面](https://www.fmz.com/strategy/117473) + - [Paul "The Gambler" Lévy](https://www.fmz.com/strategy/117768) + - [动态平衡 做市策略](https://www.fmz.com/strategy/113618) + - [OKEX交易对信息](https://www.fmz.com/strategy/117000) + - [简单网格测试](https://www.fmz.com/strategy/116289) + - [(13)策略框架](https://www.fmz.com/strategy/20663) + - [跨平台套利新手测试](https://www.fmz.com/strategy/115574) + - [Fomo3D 智能合约监控 / Fomo3D Smart Contract Monitoring](https://www.fmz.com/strategy/107916) + - [动态平衡alpha](https://www.fmz.com/strategy/115321) + - [CoinPark交易所通用协议 6.27 16:00 更新 关闭了SSL验证](https://www.fmz.com/strategy/101399) + - [30行赌徒策略](https://www.fmz.com/strategy/113796) + - [交易所最小数量和精度](https://www.fmz.com/strategy/108887) + - [Shannon's Demon](https://www.fmz.com/strategy/64455) + - [BitMEX 高级API功能 (期货:批量下单,一键撤单) JavaScript](https://www.fmz.com/strategy/105056) + - [动态平衡 做市策略 (小高)](https://www.fmz.com/strategy/114044) + - [30行赌徒策略 (做空)](https://www.fmz.com/strategy/113986) + - [GuoJian_First](https://www.fmz.com/strategy/113871) + - [50行网格策略(教学)](https://www.fmz.com/strategy/113144) + - [50行多平台对冲策略(教学)](https://www.fmz.com/strategy/113278) + - [Dual Thrust OKEX期货 (教学)](https://www.fmz.com/strategy/112425) + - [[VNC] SVM Test](https://www.fmz.com/strategy/112188) + - [Dynamic Balance Strategy](https://www.fmz.com/strategy/110900) + - [区块链量化投资系列课程(3) - 跨期套利](https://www.fmz.com/strategy/104964) + - [区块链量化投资系列课程(4) - 动态平衡策略](https://www.fmz.com/strategy/110545) + - [单平台均衡策略](https://www.fmz.com/strategy/345) + - [商品期货跨期对冲 - 单品种套利合约](https://www.fmz.com/strategy/27122) + - [新手上路CoinEx交易 (LTC_USDT)](https://www.fmz.com/strategy/103464) + - [画线类库|Plot library](https://www.fmz.com/strategy/27293) - [Iceberg Buy Order](https://www.fmz.com/strategy/103319) - [Dual Thrust OKEX Feature](https://www.fmz.com/strategy/103247) - - [Moving Average Strategy in 30 lines](https://www.fmz.com/strategy/103070) - [商品期货跟单系统](https://www.fmz.com/strategy/79351) - - [CoinPark交易所通用协议 6.27 16:00 更新 关闭了SSL验证](https://www.fmz.com/strategy/101399) - [转换任意K线周期管理模板(最近更新20180627)](https://www.fmz.com/strategy/41163) - - [商品期货跨期对冲 - 单品种套利合约](https://www.fmz.com/strategy/27122) + - [检查https://quant.la/Argus/是否正常](https://www.fmz.com/strategy/100344) - [2014年的简易短线机器人](https://www.fmz.com/strategy/1088) - - [FCoin交易手续费统计(感谢满总分享)](https://www.fmz.com/strategy/98405) - [fcoin挖矿演示](https://www.fmz.com/strategy/97791) - [币安出售所有山寨币](https://www.fmz.com/strategy/97629) - [RSI 双均线策略](https://www.fmz.com/strategy/46605) + - [商品期货 - 形态策略(增强型锤子)](https://www.fmz.com/strategy/97130) - [追涨杀跌](https://www.fmz.com/strategy/96634) - [Python 机器学习之 SVM 预测买卖](https://www.fmz.com/strategy/21370) - [Python简单测试策略](https://www.fmz.com/strategy/20761) @@ -27,16 +106,17 @@ - [抢盘口做市策略 - 高频逼近型](https://www.fmz.com/strategy/348) - [网格变形策略之单边网格 (OK期货)](https://www.fmz.com/strategy/8474) - [测试-CTP商品期货连接状态 (图表显示)](https://www.fmz.com/strategy/22838) + - [图表模板(增加状态栏表格)](https://www.fmz.com/strategy/20967) - [测试-布林带策略(基于策略框架)](https://www.fmz.com/strategy/28128) - [策略框架模板](https://www.fmz.com/strategy/30861) - [python版CTP商品期货交易类库(支持2/3 测试版)](https://www.fmz.com/strategy/24288) - [指数量化](https://www.fmz.com/strategy/91704) - [顺大势逆小势策略之代码实现及可行性分析](https://www.fmz.com/strategy/59356) - [判断MA线的排列 - btcdw](https://www.fmz.com/strategy/89969) + - [基于回归幅度的反转交易策略](https://www.fmz.com/strategy/69937) - [单边网格](https://www.fmz.com/strategy/88472) - [okex币币最小交易量](https://www.fmz.com/strategy/88754) - [基于CCI周期性区间交易策略](https://www.fmz.com/strategy/60287) - - [商品期货交易类库](https://www.fmz.com/strategy/12961) - [网格变形策略之单边网格](https://www.fmz.com/strategy/629) - [talib简单应用之查找三只乌鸦](https://www.fmz.com/strategy/62163) - [内外盘期货品种实时差价图](https://www.fmz.com/strategy/82929) @@ -52,25 +132,16 @@ - [CTP商品期货多品种海龟交易策略](https://www.fmz.com/strategy/17289) - [python版 Dual Thrust OKCoin 期货](https://www.fmz.com/strategy/21856) - [五线向上&&突破前高](https://www.fmz.com/strategy/76827) - - [单平台均衡策略](https://www.fmz.com/strategy/345) - - [数字货币现货交易类库](https://www.fmz.com/strategy/10989) - [数字货币交易类库 (期货支持OKCoin期货/BitVC, 支持$.CTA函数)](https://www.fmz.com/strategy/57267) - [C++ API调用例子](https://www.fmz.com/strategy/61533) - - [定期定额投资BTC盈利验证](https://www.fmz.com/strategy/65030) - [双平台对冲js版本(two platforms hedging-JS)](https://www.fmz.com/strategy/57556) - [代替废弃的GetMinStock()函数](https://www.fmz.com/strategy/69436) - [Python版 TableTemplet (测试版)](https://www.fmz.com/strategy/46031) - [网格(波段)香农版](https://www.fmz.com/strategy/67495) - [价值平均定投](https://www.fmz.com/strategy/67128) - [定投简单版](https://www.fmz.com/strategy/67098) - - [Shannon's Demon](https://www.fmz.com/strategy/64455) - - [画线类库](https://www.fmz.com/strategy/27293) - [回测保存K线到本地CSV](https://www.fmz.com/strategy/61867) - - [02顺大势逆小势策略之代码实现及可行性分析 (Share 1513097042)](https://www.fmz.com/strategy/63223) - - [03基于商品期货的套利策略模型 (Share 1513096985)](https://www.fmz.com/strategy/63221) - - [幽灵交易者策略 (Share 1512580165)](https://www.fmz.com/strategy/62303) - [bitfinex保证金交易](https://www.fmz.com/strategy/57333) - - [双平台对冲js版本(two platforms hedging-JS) (Copy)](https://www.fmz.com/strategy/61405) - [简单多品种商品期货均线策略](https://www.fmz.com/strategy/57029) - [测试 默认 参数组功能](https://www.fmz.com/strategy/40155) - [全球10大交易系统之 Aberration 多品种商品期货交易系统](https://www.fmz.com/strategy/25943) @@ -78,6 +149,7 @@ - [python版 画线类库 (兼容2/3)](https://www.fmz.com/strategy/39066) - [BotVS 商品期货 量化 测试入门 策略](https://www.fmz.com/strategy/59120) - [如何找出一定Bar数量的 K线前期高点、低点 及 Demo 程序](https://www.fmz.com/strategy/58179) + - [OKCoin期货跨期对冲策略(模板测试使用)](https://www.fmz.com/strategy/36762) - [python版现货数字货币交易类库](https://www.fmz.com/strategy/21104) - [一目均衡](https://www.fmz.com/strategy/55839) - [StochRSI(和okcoin一致)](https://www.fmz.com/strategy/56119) @@ -95,10 +167,10 @@ - [Ma单均线趋势交易](https://www.fmz.com/strategy/42451) - [KingKeltner趋势策略_低频](https://www.fmz.com/strategy/42283) - [buy-hold 买入持有](https://www.fmz.com/strategy/41786) + - [知乎专栏 实例文章策略](https://www.fmz.com/strategy/39586) - [知乎专栏 实例文章策略](https://www.fmz.com/strategy/40266) - [BitMEX 简单测试](https://www.fmz.com/strategy/40289) - [商品期货查看账户详细信息](https://www.fmz.com/strategy/37793) - - [股票证券查询买卖示例](https://www.fmz.com/strategy/5541) - [测试多图表展示](https://www.fmz.com/strategy/38203) - [商品期货结算单平仓盈亏历史查询](https://www.fmz.com/strategy/38083) - [Convert_Record_Cycle](https://www.fmz.com/strategy/37678) @@ -113,13 +185,11 @@ - [范例-定时测试微信消息推送](https://www.fmz.com/strategy/15098) - [Python API 测试](https://www.fmz.com/strategy/21365) - [从第三方获取K线 (商品期货版) Rev. 161216](https://www.fmz.com/strategy/15498) - - [均线策略 30 行搞定](https://www.fmz.com/strategy/12348) - [商品期货跨期对冲 - 百行代码实现](https://www.fmz.com/strategy/23896) - [短信通知类库](https://www.fmz.com/strategy/26921) - [获取和讯期货数据(Python版本)](https://www.fmz.com/strategy/26017) - [高频收割机一号](https://www.fmz.com/strategy/6237) - [R-Breaker 交易策略](https://www.fmz.com/strategy/23531) - - [(13)策略框架](https://www.fmz.com/strategy/20663) - [均线策略(python版)](https://www.fmz.com/strategy/21157) - [Python 双平台对冲策略](https://www.fmz.com/strategy/21023) - [各大平台API可用率统计](https://www.fmz.com/strategy/4404) @@ -130,17 +200,13 @@ - [对冲2.7收益率统计系统 支持多组账号统计](https://www.fmz.com/strategy/18678) - [收益率统计](https://www.fmz.com/strategy/19329) - [从第三方网站获取K线 (0804更新)](https://www.fmz.com/strategy/12977) - - [不要怂就是干](https://www.fmz.com/strategy/18943) - [入门模板之各个平台余额](https://www.fmz.com/strategy/48) - - [商品期货主力合约过滤](https://www.fmz.com/strategy/9837) - [商品期货交易类库(增加下限价单功能)](https://www.fmz.com/strategy/14198) - [获取OK期货实时限价](https://www.fmz.com/strategy/17028) - [定期定额投资BTC盈利验证](https://www.fmz.com/strategy/16845) - [My-1-价值平均定投策略](https://www.fmz.com/strategy/8602) - [记录净资产变动情况2.0](https://www.fmz.com/strategy/8916) - - [非常简单的策略,但是很有效](https://www.fmz.com/strategy/15085) - [单独计算收益(代码来自zero)](https://www.fmz.com/strategy/1084) - - [10行人品策略](https://www.fmz.com/strategy/14436) - [平台价格指标监控1.1](https://www.fmz.com/strategy/12442) - [窜天猴 - 移动止损版](https://www.fmz.com/strategy/13594) - [窜天猴 多空较量 爆破版](https://www.fmz.com/strategy/13597) @@ -156,7 +222,6 @@ - [多平台账户统计](https://www.fmz.com/strategy/7827) - [阶梯下单 - 可设置触发价格](https://www.fmz.com/strategy/639) - [796期货反手加倍算法](https://www.fmz.com/strategy/3648) - - [冰山委托 - 支持价格触发 BitVC期货专用](https://www.fmz.com/strategy/951) - [多线程获取多个交易的深度信息](https://www.fmz.com/strategy/3651) - [账户余额变动邮箱提醒, 支持添加多个交易所](https://www.fmz.com/strategy/2006) - [多线程获取多个交易的账户信息](https://www.fmz.com/strategy/3297) @@ -166,7 +231,6 @@ - [统计K线回测是否存在趋势](https://www.fmz.com/strategy/1125) - [价格波动报警](https://www.fmz.com/strategy/885) - [取消所有订单](https://www.fmz.com/strategy/280) - - [新手入门之 - 下买单卖单](https://www.fmz.com/strategy/796) - [短信通知接口测试](https://www.fmz.com/strategy/653) - [每1分钟统计各个平台间的差价(by JackConan)](https://www.fmz.com/strategy/98) - [统计各个平台间的最大差价(by JackConan)](https://www.fmz.com/strategy/86) diff --git "a/RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.js" "b/RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.md" similarity index 87% rename from "RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.js" rename to "RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.md" index d4504219..1402d547 100644 --- "a/RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.js" +++ "b/RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.md" @@ -1,26 +1,38 @@ -/* -策略出处: https://www.fmz.com/strategy/46605 -策略名称: RSI 双均线策略 -策略作者: yilidalei -策略描述: +> 策略名称 +RSI 双均线策略 +> 策略作者 + +yilidalei + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|RSI_Period|14|RSI周期| +|MA_fast_Period|10|快线周期| +|MA_slow_Period|24|慢线周期| +|SuperSellValue|20|超卖阈值| +|SuperBuyValue|80|超买阈值| -参数 默认值 描述 --------------- ----- ----- -RSI_Period 14 RSI周期 -MA_fast_Period 10 快线周期 -MA_slow_Period 24 慢线周期 -SuperSellValue 20 超卖阈值 -SuperBuyValue 80 超买阈值 -按钮 默认值 描述 ----- ---------- ----- -btn1 __button__ test -btn2 __button__ test2 -*/ + +|按钮|默认值|描述| +|----|----|----| +|btn1|__button__|test| +|btn2|__button__|test2| + + +> 源码 (javascript) + +``` javascript // 以下是测试代码 /*- 状态 在使用 模板时需要在 主策略内声明 var TASK_IDLE = 0; @@ -126,3 +138,12 @@ function main() { $.Relation_Exchange_onTick(exchanges[0], onTick1); $.Trend(); // 不用传参数。 } +``` + +> 策略出处 + +https://www.fmz.com/strategy/46605 + +> 更新时间 + +2018-06-09 17:45:28 diff --git a/RSI_now_sb_ok.js b/RSI_now_sb_ok.md similarity index 90% rename from RSI_now_sb_ok.js rename to RSI_now_sb_ok.md index f9ee3422..b96c98dc 100644 --- a/RSI_now_sb_ok.js +++ b/RSI_now_sb_ok.md @@ -1,23 +1,34 @@ -/* -策略出处: https://www.fmz.com/strategy/11604 -策略名称: RSI_now_sb_ok -策略作者: tfboys -策略描述: + +> 策略名称 + +RSI_now_sb_ok + +> 策略作者 + +tfboys + +> 策略描述 RSI简单买卖测试, 默认 70-100卖出,0-30买入 +> 策略参数 + + -参数 默认值 描述 ----------- ------ --------- -RSIPeriod 14 RSI周期 -SlidePrice 0.3 下单滑动值 -RSIBuyL 50 RSI买入点(低) -RSIBuyH 50 RSI买入点(高) -RSISellL 50 RSI卖出点(低) -RSISellH 50 RSI卖出点(高) -Interval 1000 出错重试(毫秒) -*/ +|参数|默认值|描述| +|----|----|----| +|RSIPeriod|14|RSI周期| +|SlidePrice|0.3|下单滑动值| +|RSIBuyL|50|RSI买入点(低)| +|RSIBuyH|50|RSI买入点(高)| +|RSISellL|50|RSI卖出点(低)| +|RSISellH|50|RSI卖出点(高)| +|Interval|1000|出错重试(毫秒)| + +> 源码 (javascript) + +``` javascript function adjustFloat(v) { return Math.floor(v*1000)/1000; } @@ -180,3 +191,12 @@ function main() { Sleep(Interval); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/11604 + +> 更新时间 + +2016-03-08 16:00:06 diff --git "a/RUMI\347\255\226\347\225\245.md" "b/RUMI\347\255\226\347\225\245.md" new file mode 100644 index 00000000..021a14ee --- /dev/null +++ "b/RUMI\347\255\226\347\225\245.md" @@ -0,0 +1,66 @@ + +> 策略名称 + +RUMI策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略名称:RUMI策略 +- 适用周期:多周期 +- 支持:商品期货、数字货币期货、数字货币现货 +- 官方网站:www.quant.la + + + /upload/asset/df2427683a93f2c896c853c89e3ae494.png + + /upload/asset/67f75ccbe20acf6cbaa62a1d580daeda.png + + +- 主图: + 无 + +- 副图: + AOS指标,公式: AOS:MA(OS,N3); + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N1|3|AOS指标参数1| +|N2|100|AOS指标参数2| +|N3|30|AOS指标参数3| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-01-01 00:00:00 +end: 2018-01-07 00:00:00 +period: 5m +exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}] +args: [["TradeAmount",100,126961],["ContractType","this_week",126961]] +*) + +OS:=MA(CLOSE,N1)-EMA2(CLOSE,N2); +AOS:MA(OS,N3); +CONDITION1:=CROSSUP(AOS,0); +CONDITION2:=CROSSDOWN(AOS,0); +CONDITION1,BPK; +CONDITION2,SPK; +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/129082 + +> 更新时间 + +2018-12-07 11:36:11 diff --git a/Shannon's Demon.js b/Shannon's Demon.md similarity index 71% rename from Shannon's Demon.js rename to Shannon's Demon.md index 9df8f45c..e7b8308e 100644 --- a/Shannon's Demon.js +++ b/Shannon's Demon.md @@ -1,21 +1,42 @@ + +> 策略名称 + +Shannon's Demon + +> 策略作者 + +FawkesPan + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|DELAY|30|平衡间隔| +|DS|1.04|Sell| +|DB|1.08|Buy| +|RSIB|80|RSI Buy| +|RSIS|20|RSI Sell| + + +> 源码 (javascript) + +``` javascript /* -策略出处: https://www.fmz.com/strategy/64455 -策略名称: Shannon's Demon -策略作者: FawkesPan -策略描述: + Shannon's Demon Demo Code + Copyright 2018 FawkesPan + Contact : i@fawkex.me / Telegram@FawkesPan + Do What the Fuck You Want To Public License -参数 默认值 描述 ------ ----- -------- -DELAY 30 平衡间隔 -DS 1.04 Sell -DB 1.08 Buy -RSIB 80 RSI Buy -RSIS 20 RSI Sell */ + function onTick(){ var Account = exchange.GetAccount(); var Depth = exchange.GetDepth(); @@ -50,3 +71,12 @@ function main(){ Sleep(DELAY*1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/64455 + +> 更新时间 + +2018-08-30 03:04:37 diff --git "a/StochRSI(\345\222\214okcoin\344\270\200\350\207\264).js" "b/StochRSI(\345\222\214okcoin\344\270\200\350\207\264).md" similarity index 96% rename from "StochRSI(\345\222\214okcoin\344\270\200\350\207\264).js" rename to "StochRSI(\345\222\214okcoin\344\270\200\350\207\264).md" index d023525d..700f4789 100644 --- "a/StochRSI(\345\222\214okcoin\344\270\200\350\207\264).js" +++ "b/StochRSI(\345\222\214okcoin\344\270\200\350\207\264).md" @@ -1,13 +1,19 @@ -/* -策略出处: https://www.fmz.com/strategy/56119 -策略名称: StochRSI(和okcoin一致) -策略作者: fangj -策略描述: +> 策略名称 +StochRSI(和okcoin一致) -*/ +> 策略作者 +fangj + + + + + +> 源码 (javascript) + +``` javascript function Stoch_RSI(records) { /* LC:=REF(CLOSE,1); @@ -128,3 +134,12 @@ function main() { Sleep(2000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/56119 + +> 更新时间 + +2017-09-26 13:04:37 diff --git a/TableTemplet.js b/TableTemplet.md similarity index 93% rename from TableTemplet.js rename to TableTemplet.md index 314f337f..bf3d2eb0 100644 --- a/TableTemplet.js +++ b/TableTemplet.md @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/44319 -策略名称: TableTemplet -策略作者: 职业养鸡户 -策略描述: + +> 策略名称 + +TableTemplet + +> 策略作者 + +职业养鸡户 + +> 策略描述 //by 养鸡专业户 17/6/21 -*/ + +> 源码 (javascript) + +``` javascript var listener = Array(); //----------绘制Table----------- { @@ -138,3 +146,12 @@ function main(){ tb.SetRowByTableInfo(0,tbInfo) tbMgr.LogStatus("上","下") } +``` + +> 策略出处 + +https://www.fmz.com/strategy/44319 + +> 更新时间 + +2017-06-21 11:27:08 diff --git a/[VNC] SVM Test.md b/[VNC] SVM Test.md new file mode 100644 index 00000000..ba432ce4 --- /dev/null +++ b/[VNC] SVM Test.md @@ -0,0 +1,92 @@ + +> 策略名称 + +[VNC] SVM Test + +> 策略作者 + +virtualpeer + + + + + +> 源码 (python) + +``` python +import numpy as np +import pandas as pd + +data = DataAPI.MktIdxdGet(indexID=u"",ticker=u"000300",tradeDate=u"",beginDate=u"20100101",endDate=u"20180501",exchangeCD=u"XSHE,XSHG",field=u"",pandas="1") +data.set_index('tradeDate', inplace = True) +# 获取HS300的每日价格数据 + +for i in range(1, 21, 1): + data['close-' + str(i) + 'd'] = data['closeIndex'].shift(i) +# 对于收盘价,在data中增加了20列数据,分别为1天前的收盘价至20天前的收盘价 + +hs_close = data[[x for x in data.columns if 'close' in x]].iloc[20:] +# 选取今天及1-20天前的收盘价,iloc[20:]剔除了无效数据 + +hs_close = hs_close.iloc[:, ::-1] +# 将新DataFrame的列按倒序排列 +################################################################################################ +from sklearn import svm +# 从sklearn库中导入svm算法 + +days = 1500 +# 设定全局变量,分割训练集和测试集的数据,1500在上文数据中约占75% + +clf_close = svm.SVR(kernel='linear') +# 使用svm下的SVR算法,'linear'表示线性核 +f_close_train = hs_close[:days] +# 训练集features +l_close_train = hs_close['closeIndex'].shift(-1)[:days] +# 训练集labels,将收盘价shift(-1)表示预测的是下一天的收盘价 +f_close_test = hs_close[days:] +# 测试集features +l_close_test = hs_close['closeIndex'].shift(-1)[days:] +# 训练集labels,将收盘价shift(-1)表示预测的是下一天的收盘价 +clf_close.fit(f_close_train, l_close_train) +# 训练模型 + +###################################################################################### + +p_close_train = clf_close.predict(f_close_train) +# 将训练集features导入模型进行预测,生成预测的收盘价 +df_close_train = pd.DataFrame(l_close_train) +# 新建一个DataFrame,内容为训练集labels,即下一天的收盘价 +df_close_train.columns = ['next close'] +# 列名重命名为'next close' +df_close_train['predicted next close'] = p_close_train +# 加入一列预测的收盘价数据 +df_close_train['next open'] = data['openIndex'][20:20 + days].shift(-1) +# 加入一列下一天开盘价的数据,从data而非hs_close中获取,需要切片 + +trigger = 1.0 +df_close_train['position'] = np.where(df_close_train['predicted next close'] > df_close_train['next open'] * trigger, 1, 0) +# 通过np.where函数判断,当预测的下一天收盘价 > 下一天开盘价相乘或相加一个trigger时,仓位设置为1,否则为0 +df_close_train['PL'] = np.where(df_close_train['position'] == 1, (df_close_train['next close'] - df_close_train['next open']) / df_close_train['next open'], 0) +# 当仓位为1时,在下一天开盘时买入,收盘时卖出,记录下一天应获得的收益率,否则收益率为0 + +df_close_train['strategy'] = (df_close_train['PL'].shift(1) + 1).cumprod() +# 策略每日收益的累积收益率,其中shift(1)表示当日记录的是下一天才能获得的收益率,当日无法获得 +df_close_train['return'] = (df_close_train['next close'].pct_change() + 1).cumprod() +# benchmark的累积收益率 + +df_close_train[['strategy', 'return']].dropna().plot() +# 画出策略与benchmark的累计收益率图 + +########################################################################## +def main(): + Log(exchange.GetAccount()) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/112188 + +> 更新时间 + +2018-08-18 20:34:19 diff --git "a/bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.js" "b/bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.md" similarity index 90% rename from "bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.js" rename to "bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.md" index e269b29d..998ba092 100644 --- "a/bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.js" +++ "b/bitfinex\344\277\235\350\257\201\351\207\221\344\272\244\346\230\223.md" @@ -1,13 +1,19 @@ -/* -策略出处: https://www.fmz.com/strategy/57333 -策略名称: bitfinex保证金交易 -策略作者: 7meter -策略描述: +> 策略名称 +bitfinex保证金交易 -*/ +> 策略作者 +7meter + + + + + +> 源码 (javascript) + +``` javascript var bitfinexIndex = 0; var basecurrency; var quotecurrency; @@ -57,3 +63,12 @@ $.marginBalance = function(){ var balance = exchanges[bitfinexIndex].IO("api", "POST", "/v1/margin_infos") return balance[0].tradable_balance; } +``` + +> 策略出处 + +https://www.fmz.com/strategy/57333 + +> 更新时间 + +2017-12-02 22:04:28 diff --git "a/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.js" "b/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.md" similarity index 89% rename from "buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.js" rename to "buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.md" index fd296608..37f26f29 100644 --- "a/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.js" +++ "b/buy-hold \344\271\260\345\205\245\346\214\201\346\234\211.md" @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/41786 -策略名称: buy-hold 买入持有 -策略作者: ipqhjjybj -策略描述: + +> 策略名称 + +buy-hold 买入持有 + +> 策略作者 + +ipqhjjybj + +> 策略描述 买入持有策略 -*/ + +> 源码 (javascript) + +``` javascript /* 策略出处: rqalpha 策略名称: buy-hold买入持有 @@ -84,3 +92,12 @@ function main() { Sleep(LoopInterval*1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/41786 + +> 更新时间 + +2017-06-02 22:18:11 diff --git "a/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.js" "b/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.md" similarity index 79% rename from "fcoin\346\214\226\347\237\277\346\274\224\347\244\272.js" rename to "fcoin\346\214\226\347\237\277\346\274\224\347\244\272.md" index 145a4369..4e10e67c 100644 --- "a/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.js" +++ "b/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.md" @@ -1,20 +1,31 @@ -/* -策略出处: https://www.fmz.com/strategy/97791 -策略名称: fcoin挖矿演示 -策略作者: 爆仓小王子 -策略描述: + +> 策略名称 + +fcoin挖矿演示 + +> 策略作者 + +爆仓小王子 + +> 策略描述 看到官方api群里开源的python版本,虽然很简单了,但是还有很多人架不起来环境 出问题的原因也有很多种,不太适合新手 本着开源共享的精神,我也开源一份,请大家斧正 +> 策略参数 + + -参数 默认值 描述 ------- ----- ------- -Amount 10 下单量 -Wait true 等待间隔(秒) -*/ +|参数|默认值|描述| +|----|----|----| +|Amount|10|下单量| +|Wait|true|等待间隔(秒)| + +> 源码 (javascript) + +``` javascript function DealOrder(orderType, sellPrice) { var ticker = _C(exchange.GetTicker); var action = orderType == ORDER_TYPE_BUY ? 'Buy' : 'Sell'; @@ -44,3 +55,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/97791 + +> 更新时间 + +2018-06-12 10:28:01 diff --git a/js R-Breaker.js b/js R-Breaker.md similarity index 96% rename from js R-Breaker.js rename to js R-Breaker.md index f21396d1..158e6682 100644 --- a/js R-Breaker.js +++ b/js R-Breaker.md @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/36195 -策略名称: js R-Breaker -策略作者: 太极 -策略描述: + +> 策略名称 + +js R-Breaker + +> 策略作者 + +太极 + +> 策略描述 R-Breaker -*/ + +> 源码 (javascript) + +``` javascript NPeriod=2 //周期 f1=0.47 //中轨上下顶部区间系数 f2=0.07 //中轨上下区间系数 @@ -157,3 +165,12 @@ function main() { +``` + +> 策略出处 + +https://www.fmz.com/strategy/36195 + +> 更新时间 + +2017-02-20 15:33:43 diff --git "a/okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.js" "b/okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.md" similarity index 93% rename from "okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.js" rename to "okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.md" index 26c97e85..3a8093b7 100644 --- "a/okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.js" +++ "b/okex-BTC\345\220\210\347\272\246\350\264\246\346\210\267\345\205\254\345\274\200.md" @@ -1,13 +1,19 @@ -/* -策略出处: https://www.fmz.com/strategy/83189 -策略名称: okex-BTC合约账户公开 -策略作者: leviyuan -策略描述: +> 策略名称 +okex-BTC合约账户公开 -*/ +> 策略作者 +leviyuan + + + + + +> 源码 (javascript) + +``` javascript var exchangeRate = 6.4, usdprice = 1000 @@ -87,3 +93,12 @@ function main() { Sleep(nxttime - nowtime) } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/83189 + +> 更新时间 + +2018-03-29 09:51:37 diff --git "a/okex\345\270\201\345\270\201\346\234\200\345\260\217\344\272\244\346\230\223\351\207\217.js" "b/okex\345\270\201\345\270\201\346\234\200\345\260\217\344\272\244\346\230\223\351\207\217.md" similarity index 98% rename from "okex\345\270\201\345\270\201\346\234\200\345\260\217\344\272\244\346\230\223\351\207\217.js" rename to "okex\345\270\201\345\270\201\346\234\200\345\260\217\344\272\244\346\230\223\351\207\217.md" index 867b5707..7bc1a057 100644 --- "a/okex\345\270\201\345\270\201\346\234\200\345\260\217\344\272\244\346\230\223\351\207\217.js" +++ "b/okex\345\270\201\345\270\201\346\234\200\345\260\217\344\272\244\346\230\223\351\207\217.md" @@ -1,13 +1,19 @@ -/* -策略出处: https://www.fmz.com/strategy/88754 -策略名称: okex币币最小交易量 -策略作者: leviyuan -策略描述: +> 策略名称 +okex币币最小交易量 -*/ +> 策略作者 +leviyuan + + + + + +> 源码 (javascript) + +``` javascript // 数据来源 https://github.com/okcoin-okex/API-docs-OKEx.com/blob/master/%E5%B8%81%E5%B8%81%E6%9C%80%E5%B0%8F%E4%BA%A4%E6%98%93%E9%87%8F(min_trade_size%20for%20spot).mda_btc // 更新时间 2018-4-25 13:37 function main() { @@ -518,3 +524,12 @@ $.GetMinTradeSize = function(exchIndex) { return 0 return min_trade_size[currency] } +``` + +> 策略出处 + +https://www.fmz.com/strategy/88754 + +> 更新时间 + +2018-04-25 13:45:38 diff --git "a/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" "b/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.md" similarity index 92% rename from "python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" rename to "python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.md" index 00a2b8e9..c3bf340b 100644 --- "a/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.py" +++ "b/python\347\211\210 Dual Thrust OKCoin \346\234\237\350\264\247.md" @@ -1,25 +1,36 @@ -''' -策略出处: https://www.fmz.com/strategy/21856 -策略名称: python版 Dual Thrust OKCoin 期货 -策略作者: 小小梦 -策略描述: + +> 策略名称 + +python版 Dual Thrust OKCoin 期货 + +> 策略作者 + +小小梦 + +> 策略描述 Dual Thrust 策略包含完整的图表显示, 图表动态更新,模板引用等功能, 可做学习模板使用. +> 策略参数 + + -参数 默认值 描述 ---------------- ----- -------------- -ContractTypeIdx 0 合约品种: 当周|次周|季度 -MarginLevelIdx 0 杠杆大小: 10|20 -NPeriod 4 计算周期 -Ks 0.5 上轨系数 -Kx 0.5 下轨系数 -AmountOP true 开仓合约张数 -Interval 2000 重试间隔(毫秒) -LoopInterval 3 轮询间隔(秒) -PeriodShow 500 图表最大显示K线柱数 -''' +|参数|默认值|描述| +|----|----|----| +|ContractTypeIdx|0|合约品种: 当周|次周|季度| +|MarginLevelIdx|0|杠杆大小: 10|20| +|NPeriod|4|计算周期| +|Ks|0.5|上轨系数| +|Kx|0.5|下轨系数| +|AmountOP|true|开仓合约张数| +|Interval|2000|重试间隔(毫秒)| +|LoopInterval|3|轮询间隔(秒)| +|PeriodShow|500|图表最大显示K线柱数| + +> 源码 (python) + +``` python import time class Error_noSupport(BaseException): def __init__(self): @@ -231,3 +242,12 @@ def main(): +``` + +> 策略出处 + +https://www.fmz.com/strategy/21856 + +> 更新时间 + +2018-03-23 16:53:49 diff --git "a/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" "b/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).md" similarity index 96% rename from "python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" rename to "python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).md" index 9216ce45..7da9e2bf 100644 --- "a/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).py" +++ "b/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).md" @@ -1,8 +1,13 @@ -''' -策略出处: https://www.fmz.com/strategy/39066 -策略名称: python版 画线类库 (兼容2-3) -策略作者: 小小梦 -策略描述: + +> 策略名称 + +python版 画线类库 (兼容2-3) + +> 策略作者 + +小小梦 + +> 策略描述 简化了策略图表画线的逻辑, 可以直接调用封装好的函数 @@ -16,8 +21,11 @@ 移植于JS版 画线类库 ### 如有问题请联系 小小梦 359706687 -''' + +> 源码 (python) + +``` python # Python 2/3 兼容版本 import time chart = None @@ -239,3 +247,12 @@ def main(): Sleep(60000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/39066 + +> 更新时间 + +2017-11-09 21:22:40 diff --git "a/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" "b/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.md" similarity index 98% rename from "python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" rename to "python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.md" index 3eeb0682..5b3fd1a7 100644 --- "a/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.py" +++ "b/python\347\211\210CTP\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\224\257\346\214\2012-3 \346\265\213\350\257\225\347\211\210\357\274\211.md" @@ -1,20 +1,31 @@ -''' -策略出处: https://www.fmz.com/strategy/24288 -策略名称: python版CTP商品期货交易类库(支持2-3 测试版) -策略作者: 小小梦 -策略描述: + +> 策略名称 + +python版CTP商品期货交易类库(支持2-3 测试版) + +> 策略作者 + +小小梦 + +> 策略描述 python版CTP商品期货交易类库 测试版 如有BUG 欢迎提出,作者QQ : 359706687 小小梦 1、2017.4.25 更新:增加 if (insDetail.MaxLimitOrderVolume == 0) 条件判断,有些期货公司服务器 会返回0 值,特此处理。共修改3处 【1】self.pollTask 【2】function Cover 【3】function Open +> 策略参数 + + -参数 默认值 描述 ---------- ----- ---- -SlideTick true 滑价 -Interval 500 轮询间隔 -''' +|参数|默认值|描述| +|----|----|----| +|SlideTick|true|滑价| +|Interval|500|轮询间隔| + +> 源码 (python) + +``` python import json # json 模块 import types # 类型 模块 import platform # 版本信息 @@ -726,3 +737,12 @@ def NoName1(task, ret): q.poll() Sleep(1000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/24288 + +> 更新时间 + +2018-05-15 14:29:05 diff --git "a/python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.py" "b/python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.md" similarity index 93% rename from "python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.py" rename to "python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.md" index 6dfdeb0d..c1d964ca 100644 --- "a/python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.py" +++ "b/python\347\211\210\347\216\260\350\264\247\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223.md" @@ -1,23 +1,34 @@ -''' -策略出处: https://www.fmz.com/strategy/21104 -策略名称: python版现货数字货币交易类库 -策略作者: 小小梦 -策略描述: + +> 策略名称 + +python版现货数字货币交易类库 + +> 策略作者 + +小小梦 + +> 策略描述 现货数字货币交易类库(python版) +> 策略参数 + + -参数 默认值 描述 -------------- ------ ------------------ -OpMode 0 下单方式: 吃单|挂单 -MaxSpace 0.5 挂单失效距离 -SlidePrice 0.1 下单滑动价 -MaxAmount 0.8 开仓单次最大下单量 -RetryDelay 500 失败重试毫秒 -MAType 0 均线类型: TA.EMA|TA.MA -_GetMinStocks 0.01 最小交易量 -''' +|参数|默认值|描述| +|----|----|----| +|OpMode|0|下单方式: 吃单|挂单| +|MaxSpace|0.5|挂单失效距离| +|SlidePrice|0.1|下单滑动价| +|MaxAmount|0.8|开仓单次最大下单量| +|RetryDelay|500|失败重试毫秒| +|MAType|0|均线类型: TA.EMA|TA.MA| +|_GetMinStocks|0.01|最小交易量| + +> 源码 (python) + +``` python import types # 导入类型模块 import time # 导入时间模块 import platform # 版本信息 @@ -241,3 +252,12 @@ def main(): avgprice = ret['price'] dealamount = ret['amount'] Log("avgprice:",avgprice," dealamount:",dealamount) +``` + +> 策略出处 + +https://www.fmz.com/strategy/21104 + +> 更新时间 + +2017-10-20 18:02:17 diff --git "a/stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).js" "b/stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).md" similarity index 97% rename from "stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).js" rename to "stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).md" index d9889072..cbedf3e8 100644 --- "a/stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).js" +++ "b/stochRSI\347\255\226\347\225\245 (\346\214\207\346\240\207\346\241\206\346\236\266).md" @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/20383 -策略名称: stochRSI策略 (指标框架) -策略作者: 小小梦 -策略描述: + +> 策略名称 + +stochRSI策略 (指标框架) + +> 策略作者 + +小小梦 + +> 策略描述 stochRSI指标策略 -*/ + +> 源码 (javascript) + +``` javascript /*参数 stochRSI 指标参数 数组 [14,14,3,3] 使用现货数字货币交易类库 @@ -331,3 +339,12 @@ function main(){ 4、参数设置 5、可视图表 */ +``` + +> 策略出处 + +https://www.fmz.com/strategy/20383 + +> 更新时间 + +2016-08-22 19:23:00 diff --git "a/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" "b/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.md" similarity index 76% rename from "talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" rename to "talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.md" index cbc686c7..349a0847 100644 --- "a/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.js" +++ "b/talib\347\256\200\345\215\225\345\272\224\347\224\250\344\271\213\346\237\245\346\211\276\344\270\211\345\217\252\344\271\214\351\270\246.md" @@ -1,13 +1,19 @@ -/* -策略出处: https://www.fmz.com/strategy/62163 -策略名称: talib简单应用之查找三只乌鸦 -策略作者: Zero -策略描述: + +> 策略名称 + +talib简单应用之查找三只乌鸦 + +> 策略作者 + +Zero + -*/ +> 源码 (javascript) + +``` javascript /*backtest start: 2017-12-05 00:00:00 end: 2017-12-06 12:00:00 @@ -29,3 +35,12 @@ function main() { Sleep(1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/62163 + +> 更新时间 + +2018-04-07 11:47:38 diff --git "a/\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.js" "b/\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.md" similarity index 92% rename from "\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.js" rename to "\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.md" index 5f8f0cfc..619c8de4 100644 --- "a/\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.js" +++ "b/\343\200\220001\343\200\221\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245 \343\200\220\347\240\224\347\251\266\343\200\221.md" @@ -1,20 +1,31 @@ -/* -策略出处: https://www.fmz.com/strategy/82325 -策略名称: 【001】单平台均衡策略 【研究】 -策略作者: 风利 -策略描述: + +> 策略名称 + +【001】单平台均衡策略 【研究】 + +> 策略作者 + +风利 + +> 策略描述 这个需要建仓,比如账户有5000块钱,跟1个币,如果币的价值大于账户的余额5000了并且差价超过阀值,比如币现在值6000块钱,就卖掉(6000-5000)/6000/2个币,说明币升值了,把钱兑换回来,如果币贬值了,比如4000块钱了,就买入(5000-4000)/4000/2个币, 币跌的时候买一些回来,如果再涨了,就再卖掉,好像天平一样,两边不同的对冲,所以我命名为均衡策略 +> 策略参数 + + -参数 默认值 描述 ------------- ----- ---------- -threshold 10 阀值 -Interval 2000 出错重试间隔(毫秒) -LoopInterval 60 轮询间隔(秒) -*/ +|参数|默认值|描述| +|----|----|----| +|threshold|10|阀值| +|Interval|2000|出错重试间隔(毫秒)| +|LoopInterval|60|轮询间隔(秒)| +> 源码 (javascript) + +``` javascript + /* 单平台策略*/ @@ -124,3 +135,12 @@ function main() { //这里调用了主函数进 Sleep(LoopInterval * 1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/82325 + +> 更新时间 + +2018-03-24 00:41:40 diff --git "a/\343\200\220Demo\343\200\221\345\246\202\344\275\225\345\210\251\347\224\250\342\200\234\347\255\226\347\225\245\344\272\244\344\272\222\342\200\234\345\212\250\346\200\201\350\260\203\346\225\264\347\255\226\347\225\245\345\217\202\346\225\260.js" "b/\343\200\220Demo\343\200\221\345\246\202\344\275\225\345\210\251\347\224\250\342\200\234\347\255\226\347\225\245\344\272\244\344\272\222\342\200\234\345\212\250\346\200\201\350\260\203\346\225\264\347\255\226\347\225\245\345\217\202\346\225\260.md" similarity index 80% rename from "\343\200\220Demo\343\200\221\345\246\202\344\275\225\345\210\251\347\224\250\342\200\234\347\255\226\347\225\245\344\272\244\344\272\222\342\200\234\345\212\250\346\200\201\350\260\203\346\225\264\347\255\226\347\225\245\345\217\202\346\225\260.js" rename to "\343\200\220Demo\343\200\221\345\246\202\344\275\225\345\210\251\347\224\250\342\200\234\347\255\226\347\225\245\344\272\244\344\272\222\342\200\234\345\212\250\346\200\201\350\260\203\346\225\264\347\255\226\347\225\245\345\217\202\346\225\260.md" index 740c1930..71e3e9a4 100644 --- "a/\343\200\220Demo\343\200\221\345\246\202\344\275\225\345\210\251\347\224\250\342\200\234\347\255\226\347\225\245\344\272\244\344\272\222\342\200\234\345\212\250\346\200\201\350\260\203\346\225\264\347\255\226\347\225\245\345\217\202\346\225\260.js" +++ "b/\343\200\220Demo\343\200\221\345\246\202\344\275\225\345\210\251\347\224\250\342\200\234\347\255\226\347\225\245\344\272\244\344\272\222\342\200\234\345\212\250\346\200\201\350\260\203\346\225\264\347\255\226\347\225\245\345\217\202\346\225\260.md" @@ -1,18 +1,31 @@ -/* -策略出处: https://www.fmz.com/strategy/8379 -策略名称: 【Demo】如何利用“策略交互“动态调整策略参数 -策略作者: momox -策略描述: + +> 策略名称 + +【Demo】如何利用“策略交互“动态调整策略参数 + +> 策略作者 + +momox + +> 策略描述 策略需要不断的测试调整,参数也经常改来改去,每次都停止再重启,费事费力,还会丢失原来的盈利进度(虽然也可以通过全局参数来恢复),其实botvs已经提供了动态调整参数的途径--”策略交互“ +> 策略参数 + + + -按钮 默认值 描述 ----- ----- ------ -A3 999 AAA的参数 -B3 Botvs BBB的参数 -*/ +|按钮|默认值|描述| +|----|----|----| +|A3|999|AAA的参数| +|B3|Botvs|BBB的参数| + + +> 源码 (javascript) + +``` javascript var Interval=2000; //AAA,BBB为策略中希望动态调整的参数 @@ -52,3 +65,12 @@ function onTick(){ } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/8379 + +> 更新时间 + +2016-01-09 21:18:07 diff --git "a/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest.js" "b/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest.md" similarity index 91% rename from "\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest.js" rename to "\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest.md" index 256db892..55009ff8 100644 --- "a/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest.js" +++ "b/\343\200\220Demo\343\200\221\351\200\237\345\272\246\346\265\213\350\257\225 websocket vs rest.md" @@ -1,15 +1,23 @@ -/* -策略出处: https://www.fmz.com/strategy/7547 -策略名称: 【Demo】速度测试 websocket vs rest -策略作者: momox -策略描述: + +> 策略名称 + +【Demo】速度测试 websocket vs rest + +> 策略作者 + +momox + +> 策略描述 websocket 接口 与 REST 接口的 速度测试,支持添加多个交易所测试,注意会短时增加你的api调用频率,请在确保不影响其他机器人运行的情况下运行。如果出现”Futures_OP 4: argument error“的错误,请更新到最新的托管者程序 特别提醒:只能添加支持websocket接口的交易所(有点废话,不支持websocket接口,你还测什么速度),不然会出错,目前 ok,火币提供websocket接口 ,BTCC不提供,其他请咨询查阅相关交易所API介绍或帮助 -*/ +> 源码 (javascript) + +``` javascript + var Interval=1000; @@ -133,3 +141,12 @@ function main() { +``` + +> 策略出处 + +https://www.fmz.com/strategy/7547 + +> 更新时间 + +2016-01-09 20:58:20 diff --git "a/\344\270\200\347\233\256\345\235\207\350\241\241.js" "b/\344\270\200\347\233\256\345\235\207\350\241\241.md" similarity index 92% rename from "\344\270\200\347\233\256\345\235\207\350\241\241.js" rename to "\344\270\200\347\233\256\345\235\207\350\241\241.md" index e4e1941a..038601a8 100644 --- "a/\344\270\200\347\233\256\345\235\207\350\241\241.js" +++ "b/\344\270\200\347\233\256\345\235\207\350\241\241.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/55839 -策略名称: 一目均衡 -策略作者: icesun963 -策略描述: + +> 策略名称 + +一目均衡 + +> 策略作者 + +icesun963 + +> 策略描述 一目均衡 初级版 @@ -10,17 +15,23 @@ 通过云层厚度,基准线和转换线为信号,进行买入卖出。 未作判断止损。 +> 策略参数 + + -参数 默认值 描述 ------------------- ----- --------------------- -keh 12 HullMA -TenkanSenPeriods 9 TenkanSen转换值间隔 -KijunSenPeriods 24 Kijun Sen基准线 间隔 -SenkouSpanBPeriods 51 Senkou Span B 先行上限2间隔 -displacement 24 Displacement延迟线间隔 -CX 100 云层厚度 -*/ +|参数|默认值|描述| +|----|----|----| +|keh|12|HullMA| +|TenkanSenPeriods|9|TenkanSen转换值间隔| +|KijunSenPeriods|24|Kijun Sen基准线 间隔| +|SenkouSpanBPeriods|51|Senkou Span B 先行上限2间隔| +|displacement|24|Displacement延迟线间隔| +|CX|100|云层厚度| + +> 源码 (javascript) + +``` javascript var diffarray = []; var diff1array = []; var TenkanSenArray = []; @@ -229,3 +240,12 @@ function main() { Sleep(60 * 60 * 1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/55839 + +> 更新时间 + +2017-09-27 13:52:15 diff --git "a/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245.md" "b/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245.md" new file mode 100644 index 00000000..8577dea9 --- /dev/null +++ "b/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245.md" @@ -0,0 +1,73 @@ + +> 策略名称 + +三均线顺势价格突破策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 公式名称:三均线顺势价格突破策略 +- 数据周期:多周期 +- 数据合约:指数合约 +- 交易合约:主力合约 +- 适合品种:商品期货 +- 官方网站:www.quant.la + +/upload/asset/4327c3e54a8618bb6f5b0ac3ea54dfc2.png + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|SLOSS|2|止损百分比| +|N1|30|均线1参数| +|N2|60|均线2参数| +|N3|90|均线3参数| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-01-01 00:00:00 +end: 2018-02-28 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","balance":20000}] +*) + +LOTS:=MAX(1,INTPART(MONEYTOT/(O*UNIT*0.1))); + +MA1^^MA(C,N1); +MA2^^MA(C,N2); +MA3^^MA(C,N3); + +BUYK:=BARPOS>N3 AND BKVOL=0 AND MA1>MA2 AND MA2>MA3 AND C>MA1; +SELLK:=BARPOS>N3 AND SKVOL=0 AND MA10 AND CROSS(C,MA2) AND C>MA1 AND C<=SKPRICE*(1-2*SLOSS*0.01); +SELLP:=BKVOL>0 AND CROSS(MA2,C) AND MA1>C AND C>=BKPRICE*(1+2*SLOSS*0.01); + +BUYK,BK(LOTS); +SELLK,SK(LOTS); + +//止盈 +BUYP,BP(SKVOL); +SELLP,SP(BKVOL); + +//止损 +C>=SKPRICE*(1+SLOSS*0.01),BP(SKVOL); +C<=BKPRICE*(1-SLOSS*0.01),SP(BKVOL); +//TRADE_OTHER('AUTO'); +``` + +> 策略出处 + +https://www.fmz.com/strategy/128130 + +> 更新时间 + +2018-12-04 22:11:09 diff --git "a/\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245.md" "b/\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245.md" new file mode 100644 index 00000000..570c61ea --- /dev/null +++ "b/\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245.md" @@ -0,0 +1,89 @@ + +> 策略名称 + +三轨道波动率策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- K线走完下单:收盘价开仓、平仓 +- 数据合约:螺纹指数,郑煤指数,热卷指数,铁矿指数,焦炭指数,棕榈指数,橡胶指数,郑醇指数,PP指数,沪铜指数; +- 交易合约:螺纹主连,郑煤主连,热卷主连,铁矿主连,焦炭主连,棕榈主连,橡胶主连,郑醇主连,PP主连,沪铜主连; +- 数据级别:日K线; + +/upload/asset/785c3a0e4e8c164bc831b05dcdc355a3.png + +- 主图指标显示: + MIDTR^^MA(C,CN); // 确定MIDTR + UPTR^^MIDTR+2*STD(C,CN); // 确定UPTR + DOWNTR^^MIDTR-2*STD(C,CN); // 确定DOWNTR + HPOINT^^HV(H,CN),DOT,COLORRED; // 计算前一周期CN周期内最高价的最大值。 + LPOINT^^LV(L,CN),DOT,COLORBLUE; // 计算前一周期CN周期内最低价的最小值。 + +- 副图: + 无 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|AMOUNT|true|单仓| +|N|20|标准差周期数| +|MINN|20|CN最小值| +|MAXN|60|CN最大值| +|STOPRANGE|50|止损幅度| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2017-07-01 00:00:00 +end: 2018-11-30 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +*) + +// 确定CN +VOLAT:=STD(C,N); // VOLAT(波动率):M周期收盘价的标准差 +VOLATCHANGE:=(VOLAT-REF(VOLAT,1))/VOLAT; // 2个VOLAT的变化率 +N1:=(1+VOLATCHANGE)*MINN; // VOLATCHANGE : 波动率变化 +N2:=INTPART(N1); // 取整 +N3:=MIN(N2,MAXN); // 确认CN不大于60 +CN:=MAX(N3,MINN); // 确认CN不小于20 + +MIDTR^^MA(C,CN); // 确定MIDTR +UPTR^^MIDTR+2*STD(C,CN); // 确定UPTR +DOWNTR^^MIDTR-2*STD(C,CN); // 确定DOWNTR +HPOINT^^HV(H,CN),DOT,COLORRED; // 计算前一周期CN周期内最高价的最大值。 +LPOINT^^LV(L,CN),DOT,COLORBLUE; // 计算前一周期CN周期内最低价的最小值。 + +// 开仓 +L<=LPOINT AND LMINN,SK(AMOUNT); // 当最低价小于DOWNTR和低点,且K线位置大于60,收盘价卖开 +H>=HPOINT AND H>UPTR AND BARPOS>MINN,BK(AMOUNT); // 当最高价大于UPTR和高点,且K线位置大于60,收盘价买开 + +// 启动止损 +C>=SKPRICE*(1+STOPRANGE*0.001),BP(SKVOL); +C<=BKPRICE*(1-STOPRANGE*0.001),SP(BKVOL); + +// 平仓 +CMIDTR,BP(SKVOL); // 当收盘价大于MIDTR,收盘价买平 + +// 动态止损 +REF(BKHIGH,1)>BKPRICE*(1+2*0.001*STOPRANGE) AND CLV(C,BARSSK)*(1+STOPRANGE*0.001),BP(SKVOL); // 卖开后最低价小于卖开价*(1-2*0.001*STOPRANGE),且收盘价大于卖开后最低收盘价*(1+STOPRANGE*0.001),收盘价买平 +``` + +> 策略出处 + +https://www.fmz.com/strategy/128129 + +> 更新时间 + +2018-12-03 09:52:12 diff --git "a/\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262.js" "b/\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262.js" deleted file mode 100644 index 8036595c..00000000 --- "a/\344\270\215\350\246\201\346\200\202\345\260\261\346\230\257\345\271\262.js" +++ /dev/null @@ -1,74 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/18943 -策略名称: 不要怂就是干 -策略作者: qq110888000 -策略描述: - -"Talk is cheap. Show me the code" - - -注: ` 策略使用了交易模板类库` - -`希望新手从此策略入门, 一步步学习编写策略, 并体验到模拟与真实环境对交易系统的影响` - -https://dn-filebox.qbox.me/fb4d0c7d773ca83e9d0230927705d419dc0bbeaa.png - - -参数 默认值 描述 -------------- ----- ------- -EnterPeriod 2 入市观察期 -FastPeriod 5 入市快线周期 -SlowPeriod 30 入市慢线周期 -PositionRatio true 仓位比例 -Interval 10 轮询周期(秒) -SlidePrice 0.01 滑动值 - -按钮 默认值 描述 ----- ---------- ---- -简单策略 __button__ 不懂 -*/ - -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); - } -} diff --git "a/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" "b/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.md" similarity index 86% rename from "\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" rename to "\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.md" index 9b12a102..4bfe1a94 100644 --- "a/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.py" +++ "b/\344\272\224\347\272\277\345\220\221\344\270\212&&\347\252\201\347\240\264\345\211\215\351\253\230.md" @@ -1,13 +1,21 @@ -''' -策略出处: https://www.fmz.com/strategy/76827 -策略名称: 五线向上&&突破前高 -策略作者: 围龙小子 -策略描述: + +> 策略名称 + +五线向上&&突破前高 + +> 策略作者 + +围龙小子 + +> 策略描述 均线策略(python版)教学性质,实盘慎用。 -''' + +> 源码 (python) + +``` python import types import peakutils import os @@ -46,3 +54,12 @@ def main(): reported_price_list.append(previous_high) Sleep(1000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/76827 + +> 更新时间 + +2018-03-16 12:42:24 diff --git "a/\344\272\244\346\230\223\346\211\200\346\234\200\345\260\217\346\225\260\351\207\217\345\222\214\347\262\276\345\272\246.md" "b/\344\272\244\346\230\223\346\211\200\346\234\200\345\260\217\346\225\260\351\207\217\345\222\214\347\262\276\345\272\246.md" new file mode 100644 index 00000000..efcc031e --- /dev/null +++ "b/\344\272\244\346\230\223\346\211\200\346\234\200\345\260\217\346\225\260\351\207\217\345\222\214\347\262\276\345\272\246.md" @@ -0,0 +1,1668 @@ + +> 策略名称 + +交易所最小数量和精度 + +> 策略作者 + +imaltai + +> 策略描述 + +直接从交易所资料获取 + +最小交易量 +数量和价格精度 + + +在下单之前,请使用API函数 SetPrecision 设置精度,以避免交易所的调用错误 + +目前仅支持火币和Okex的数据 +对于目前未支持的交易所,首先在火币或者OK里面寻找币对,如果找到币对,直接使用定义的精度数据,找不到则使用默认数据 + +默认如下: +最小交易量 1 +数量精度 0.01 +价格精度 0.0001 + + + +> 源码 (javascript) + +``` javascript + + +/* +-- 策略引用该模板以后直接用 $.Test() 调用此方法 +-- main 函数在策略中不会触发, 只做为模板调试的入口 +*/ + +var DEFAULT_MINAMOUNT = 1; +var DEFAULT_AMOUNTPRECISION = 2; +var DEFAULT_PRICEPRECISION = 4; + +function findItem(array, keyName, value) { + var result = null; + value = value.toLowerCase().trim(); + + for (var i = 0; i < array.length; i++) { + if (array[i][keyName].toLowerCase().trim() == value) { + result = array[i]; + break; + } + } + + if (!result && (value.includes('usd') && !value.includes('usdt'))) { + value = value + 't'; //usd 在 币对里面肯定放在最后 + for (var i = 0; i < array.length; i++) { + if (array[i][keyName].toLowerCase().trim() == value) { + result = array[i]; + break; + } + } + } + + return result; +} + +//1.0000 0.1.,.. +function getPrecision(number) { + //Log("test precision " + number); + var str = String(number.toFixed(12)), result = 0; + if (str[1] == '.') + for (var i = 0; i < str.length; i++) { + if (str[i] == '1') { + if (i == 0) + result = 0; + else + result = i - 1; + } + } + + //Log("test " + result); + return result; +} + +$.HasMinTotal = function(jiaoyisuo) { + return (jiaoyisuo.toLowerCase().includes('binance')); +} + +$.GetMinAmount = function (jiaoyisuo, bidui) { + var item; + var unknown = true, isHuobi, isOk, isBinance; + if (jiaoyisuo.toLowerCase().includes('huobi')) { + isHuobi = true; + unknown = false; + } + else if (jiaoyisuo.toLowerCase().includes('ok')) { + isOk = true; + unknown = false; + } + else if (jiaoyisuo.toLowerCase().includes('binance')) { + isBinance = true; + unknown = false; + } + + if (isHuobi || unknown) + item = findItem(huobiMinAmounts, "symbol", bidui); + if (isBinance || (unknown && !item)) + item = findItem(binanceRegulation, "symbol", bidui); + if (isOk || (unknown && !item)) + item = findItem(okexRegulation, "symbol", bidui); + + if (item) + return item.minamount; + + return DEFAULT_MINAMOUNT; +} + +$.GetAmountPrecision = function (jiaoyisuo, bidui) { + var item; + var unknown = true, isHuobi, isOk, isBinance; + if (jiaoyisuo.toLowerCase().includes('huobi')) { + isHuobi = true; + unknown = false; + } + else if (jiaoyisuo.toLowerCase().includes('ok')) { + isOk = true; + unknown = false; + } + else if (jiaoyisuo.toLowerCase().includes('binance')) { + isBinance = true; + unknown = false; + } + + if (isHuobi || unknown) { + item = findItem(huobiPrecisions, "symbol", bidui); + if (item) + return item.amountprecision; + } + + if (isBinance || (unknown && !item)) { + item = findItem(binanceRegulation, "symbol", bidui); + if (item) + return getPrecision(item.minamount); //币安使用最小数量作为数量精度 + } + + if (isOk || (unknown && !item)) { + item = findItem(okexRegulation, "symbol", bidui); + if (item) + return getPrecision(item.amountprecision); + } + + return DEFAULT_AMOUNTPRECISION; +} + +$.GetPricePrecision = function (jiaoyisuo, bidui) { + var item; + var unknown = true, isHuobi, isOk, isBinance; + if (jiaoyisuo.toLowerCase().includes('huobi')) { + isHuobi = true; + unknown = false; + } + else if (jiaoyisuo.toLowerCase().includes('ok')) { + isOk = true; + unknown = false; + } + else if (jiaoyisuo.toLowerCase().includes('binance')) { + isBinance = true; + unknown = false; + } + + if (isHuobi || unknown) { + item = findItem(huobiPrecisions, "symbol", bidui); + if (item) + return item.priceprecision; + } + + if (isBinance || (unknown && !item)) { + item = findItem(binanceRegulation, "symbol", bidui); + //Log("test Binance PricePrecision=" + item.priceprecision + " item=" + JSON.stringify(item)); + if (item) { + //币安的数据有误,eth 6位,btc 7位,而数据列表显示8位 + var binanceP = getPrecision(item.priceprecision); + if (binanceP > 6) binanceP = 6; //强制使用6位数 + + return binanceP; + } + } + + if (isOk || (unknown && !item)) { + item = findItem(okexRegulation, "symbol", bidui); + if (item) + return getPrecision(item.priceprecision); + } + + return DEFAULT_PRICEPRECISION; +} + +$.GetMinTotal = function (jiaoyisuo, bidui) { + var item; + var unknown = true, isBinance; + + if (jiaoyisuo.toLowerCase().includes('binance')) { + isBinance = true; + unknown = false; + } + + if (isBinance || unknown) { + item = findItem(binanceRegulation, "symbol", bidui); + if (item) + return item.minstock; + } + + return 0; +} + +huobiMinAmounts = [{"symbol":"AST_BTC", "minamount":1}, +{"symbol":"ACT_BTC", "minamount":0.1}, +{"symbol":"ADX_BTC", "minamount":0.01}, +{"symbol":"ABT_BTC", "minamount":0.1}, +{"symbol":"APPC_BTC", "minamount":0.01}, +{"symbol":"AIDOC_BTC", "minamount":1}, +{"symbol":"BAT_BTC", "minamount":1}, +{"symbol":"BCH_BTC", "minamount":0.001}, +{"symbol":"BCX_BTC", "minamount":1}, +{"symbol":"BTG_BTC", "minamount":0.001}, +{"symbol":"BCD_BTC", "minamount":0.001}, +{"symbol":"BTM_BTC", "minamount":1}, +{"symbol":"BIFI_BTC", "minamount":0.01}, +{"symbol":"BLZ_BTC", "minamount":0.1}, +{"symbol":"CMT_BTC", "minamount":0.1}, +{"symbol":"CVC_BTC", "minamount":0.1}, +{"symbol":"CHAT_BTC", "minamount":0.1}, +{"symbol":"DASH_BTC", "minamount":0.001}, +{"symbol":"DGD_BTC", "minamount":0.001}, +{"symbol":"DBC_BTC", "minamount":0.1}, +{"symbol":"DAT_BTC", "minamount":1}, +{"symbol":"DTA_BTC", "minamount":1}, +{"symbol":"ETC_BTC", "minamount":0.01}, +{"symbol":"ETH_BTC", "minamount":0.001}, +{"symbol":"ELF_BTC", "minamount":1}, +{"symbol":"EOS_BTC", "minamount":0.1}, +{"symbol":"EKO_BTC", "minamount":1}, +{"symbol":"EVX_BTC", "minamount":0.01}, +{"symbol":"ELA_BTC", "minamount":0.01}, +{"symbol":"ENG_BTC", "minamount":0.001}, +{"symbol":"EDU_BTC", "minamount":1}, +{"symbol":"GNT_BTC", "minamount":0.1}, +{"symbol":"GNX_BTC", "minamount":0.1}, +{"symbol":"GAS_BTC", "minamount":0.001}, +{"symbol":"HT_BTC", "minamount":0.1}, +{"symbol":"HSR_BTC", "minamount":0.01}, +{"symbol":"ITC_BTC", "minamount":0.1}, +{"symbol":"ICX_BTC", "minamount":0.1}, +{"symbol":"IOST_BTC", "minamount":1}, +{"symbol":"KNC_BTC", "minamount":0.1}, +{"symbol":"LTC_BTC", "minamount":0.01}, +{"symbol":"LET_BTC", "minamount":1}, +{"symbol":"LUN_BTC", "minamount":0.001}, +{"symbol":"LSK_BTC", "minamount":0.001}, +{"symbol":"LINK_BTC", "minamount":0.1}, +{"symbol":"MANA_BTC", "minamount":1}, +{"symbol":"MTL_BTC", "minamount":0.01}, +{"symbol":"MCO_BTC", "minamount":0.01}, +{"symbol":"MDS_BTC", "minamount":1}, +{"symbol":"MEE_BTC", "minamount":1}, +{"symbol":"MTN_BTC", "minamount":0.1}, +{"symbol":"MTX_BTC", "minamount":0.1}, +{"symbol":"NEO_BTC", "minamount":0.001}, +{"symbol":"NAS_BTC", "minamount":0.01}, +{"symbol":"OMG_BTC", "minamount":0.01}, +{"symbol":"OST_BTC", "minamount":0.1}, +{"symbol":"OCN_BTC", "minamount":1}, +{"symbol":"ONT_BTC", "minamount":0.01}, +{"symbol":"PAY_BTC", "minamount":0.1}, +{"symbol":"POWR_BTC", "minamount":0.1}, +{"symbol":"PROPY_BTC", "minamount":0.01}, +{"symbol":"QASH_BTC", "minamount":0.1}, +{"symbol":"QSP_BTC", "minamount":1}, +{"symbol":"QTUM_BTC", "minamount":0.01}, +{"symbol":"QUN_BTC", "minamount":1}, +{"symbol":"RDN_BTC", "minamount":0.1}, +{"symbol":"RCN_BTC", "minamount":1}, +{"symbol":"REQ_BTC", "minamount":0.1}, +{"symbol":"RPX_BTC", "minamount":0.1}, +{"symbol":"RUFF_BTC", "minamount":1}, +{"symbol":"SALT_BTC", "minamount":0.1}, +{"symbol":"SBTC_BTC", "minamount":0.0001}, +{"symbol":"SMT_BTC", "minamount":1}, +{"symbol":"SNT_BTC", "minamount":0.1}, +{"symbol":"STORJ_BTC", "minamount":0.1}, +{"symbol":"SWFTC_BTC", "minamount":1}, +{"symbol":"SOC_BTC", "minamount":1}, +{"symbol":"STK_BTC", "minamount":1}, +{"symbol":"SRN_BTC", "minamount":0.01}, +{"symbol":"SNC_BTC", "minamount":0.1}, +{"symbol":"TNB_BTC", "minamount":1}, +{"symbol":"TNT_BTC", "minamount":1}, +{"symbol":"TRX_BTC", "minamount":1}, +{"symbol":"TOPC_BTC", "minamount":1}, +{"symbol":"THETA_BTC", "minamount":1}, +{"symbol":"UTK_BTC", "minamount":0.1}, +{"symbol":"VEN_BTC", "minamount":0.1}, +{"symbol":"WAX_BTC", "minamount":0.001}, +{"symbol":"WPR_BTC", "minamount":0.1}, +{"symbol":"WICC_BTC", "minamount":0.1}, +{"symbol":"XRP_BTC", "minamount":1}, +{"symbol":"XEM_BTC", "minamount":0.1}, +{"symbol":"YEE_BTC", "minamount":1}, +{"symbol":"ZEC_BTC", "minamount":0.001}, +{"symbol":"ZRX_BTC", "minamount":1}, +{"symbol":"ZIL_BTC", "minamount":1}, +{"symbol":"ZLA_BTC", "minamount":0.1}, +{"symbol":"CTXC_BTC", "minamount":0.1}, +{"symbol":"BTC_USDT", "minamount":0.001}, +{"symbol":"BCH_USDT", "minamount":0.001}, +{"symbol":"CVC_USDT", "minamount":0.1}, +{"symbol":"DTA_USDT", "minamount":1}, +{"symbol":"DASH_USDT", "minamount":0.001}, +{"symbol":"DBC_ETH", "minamount":0.1}, +{"symbol":"ETH_USDT", "minamount":0.001}, +{"symbol":"ETC_USDT", "minamount":0.01}, +{"symbol":"EOS_USDT", "minamount":0.01}, +{"symbol":"ELF_USDT", "minamount":0.1}, +{"symbol":"ELA_USDT", "minamount":0.001}, +{"symbol":"GNT_USDT", "minamount":0.1}, +{"symbol":"HT_USDT", "minamount":0.1}, +{"symbol":"HSR_USDT", "minamount":0.01}, +{"symbol":"ITC_USDT", "minamount":0.01}, +{"symbol":"IOST_USDT", "minamount":1}, +{"symbol":"LET_USDT", "minamount":1}, +{"symbol":"LTC_USDT", "minamount":0.001}, +{"symbol":"MDS_USDT", "minamount":0.1}, +{"symbol":"NEO_USDT", "minamount":0.001}, +{"symbol":"NAS_USDT", "minamount":0.01}, +{"symbol":"OMG_USDT", "minamount":0.01}, +{"symbol":"QTUM_USDT", "minamount":0.01}, +{"symbol":"RUFF_USDT", "minamount":1}, +{"symbol":"SNT_USDT", "minamount":0.1}, +{"symbol":"STORJ_USDT", "minamount":0.01}, +{"symbol":"SMT_USDT", "minamount":1}, +{"symbol":"TRX_USDT", "minamount":1}, +{"symbol":"THETA_USDT", "minamount":0.1}, +{"symbol":"VEN_USDT", "minamount":0.1}, +{"symbol":"XRP_USDT", "minamount":1}, +{"symbol":"XEM_USDT", "minamount":0.1}, +{"symbol":"ZEC_USDT", "minamount":0.001}, +{"symbol":"ZIL_USDT", "minamount":1}, +{"symbol":"ACT_ETH", "minamount":0.1}, +{"symbol":"ADX_ETH", "minamount":0.01}, +{"symbol":"ABT_ETH", "minamount":0.1}, +{"symbol":"APPC_ETH", "minamount":0.1}, +{"symbol":"AIDOC_ETH", "minamount":1}, +{"symbol":"BAT_ETH", "minamount":1}, +{"symbol":"BTM_ETH", "minamount":1}, +{"symbol":"BLZ_ETH", "minamount":0.1}, +{"symbol":"CMT_ETH", "minamount":0.1}, +{"symbol":"CVC_ETH", "minamount":0.1}, +{"symbol":"CHAT_ETH", "minamount":0.1}, +{"symbol":"DGD_ETH", "minamount":0.001}, +{"symbol":"DBC_ETH", "minamount":0.1}, +{"symbol":"DAT_ETH", "minamount":1}, +{"symbol":"DTA_ETH", "minamount":1}, +{"symbol":"EOS_ETH", "minamount":0.1}, +{"symbol":"ELF_ETH", "minamount":1}, +{"symbol":"EVX_ETH", "minamount":0.01}, +{"symbol":"EKO_ETH", "minamount":1}, +{"symbol":"ELA_ETH", "minamount":0.01}, +{"symbol":"ENG_ETH", "minamount":0.01}, +{"symbol":"EDU_ETH", "minamount":1}, +{"symbol":"GNT_ETH", "minamount":0.1}, +{"symbol":"GAS_ETH", "minamount":0.001}, +{"symbol":"GNX_ETH", "minamount":0.1}, +{"symbol":"HT_ETH", "minamount":0.1}, +{"symbol":"HSR_ETH", "minamount":0.01}, +{"symbol":"ITC_ETH", "minamount":0.1}, +{"symbol":"ICX_ETH", "minamount":0.1}, +{"symbol":"IOST_ETH", "minamount":1}, +{"symbol":"LET_ETH", "minamount":1}, +{"symbol":"LUN_ETH", "minamount":0.001}, +{"symbol":"LSK_ETH", "minamount":0.001}, +{"symbol":"LINK_ETH", "minamount":0.1}, +{"symbol":"MANA_ETH", "minamount":1}, +{"symbol":"MCO_ETH", "minamount":0.01}, +{"symbol":"MDS_ETH", "minamount":1}, +{"symbol":"MEE_ETH", "minamount":1}, +{"symbol":"MTN_ETH", "minamount":0.1}, +{"symbol":"MTX_ETH", "minamount":0.1}, +{"symbol":"NAS_ETH", "minamount":0.01}, +{"symbol":"OMG_ETH", "minamount":0.01}, +{"symbol":"OST_ETH", "minamount":0.1}, +{"symbol":"OCN_ETH", "minamount":1}, +{"symbol":"ONT_ETH", "minamount":0.01}, +{"symbol":"PAY_ETH", "minamount":0.1}, +{"symbol":"POWR_ETH", "minamount":0.1}, +{"symbol":"PROPY_ETH", "minamount":0.01}, +{"symbol":"QASH_ETH", "minamount":0.1}, +{"symbol":"QSP_ETH", "minamount":1}, +{"symbol":"QTUM_ETH", "minamount":0.01}, +{"symbol":"QUN_ETH", "minamount":1}, +{"symbol":"RDN_ETH", "minamount":0.1}, +{"symbol":"RCN_ETH", "minamount":1}, +{"symbol":"REQ_ETH", "minamount":0.1}, +{"symbol":"RUFF_ETH", "minamount":1}, +{"symbol":"SALT_ETH", "minamount":0.1}, +{"symbol":"SMT_ETH", "minamount":1}, +{"symbol":"SWFTC_ETH", "minamount":1}, +{"symbol":"SOC_ETH", "minamount":1}, +{"symbol":"STK_ETH", "minamount":1}, +{"symbol":"SRN_ETH", "minamount":0.01}, +{"symbol":"SNC_ETH", "minamount":0.1}, +{"symbol":"TNT_ETH", "minamount":1}, +{"symbol":"TNB_ETH", "minamount":1}, +{"symbol":"TRX_ETH", "minamount":1}, +{"symbol":"TOPC_ETH", "minamount":1}, +{"symbol":"THETA_ETH", "minamount":1}, +{"symbol":"UTK_ETH", "minamount":0.1}, +{"symbol":"VEN_ETH", "minamount":0.1}, +{"symbol":"WICC_ETH", "minamount":0.1}, +{"symbol":"WPR_ETH", "minamount":0.01}, +{"symbol":"WAX_ETH", "minamount":0.01}, +{"symbol":"YEE_ETH", "minamount":1}, +{"symbol":"ZIL_ETH", "minamount":1}, +{"symbol":"ZLA_ETH", "minamount":0.1}, +{"symbol":"CTXC_ETH", "minamount":0.1}]; + +huobiPrecisions = [{"symbol":"btc_usdt","priceprecision":2,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"bch_usdt","priceprecision":2,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"eth_usdt","priceprecision":2,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"etc_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"ltc_usdt","priceprecision":2,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"eos_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"xrp_usdt","priceprecision":4,"amountprecision":2,"symbol-partition":"main"}, +{"symbol":"omg_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"dash_usdt","priceprecision":2,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"zec_usdt","priceprecision":2,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"ada_usdt","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"steem_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"iota_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"ocn_usdt","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"soc_usdt","priceprecision":4,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"ctxc_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"act_usdt","priceprecision":4,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"btm_usdt","priceprecision":4,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"bts_usdt","priceprecision":4,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"ont_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"iost_usdt","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"ht_usdt","priceprecision":4,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"trx_usdt","priceprecision":6,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"dta_usdt","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"neo_usdt","priceprecision":2,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"qtum_usdt","priceprecision":2,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"smt_usdt","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"ela_usdt","priceprecision":4,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"ven_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"theta_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"snt_usdt","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"zil_usdt","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"xem_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"nas_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"ruff_usdt","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"hsr_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"let_usdt","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"mds_usdt","priceprecision":6,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"storj_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"elf_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"itc_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"cvc_usdt","priceprecision":4,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"gnt_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"xmr_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"bch_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"eth_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"ltc_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"etc_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"eos_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"main"}, +{"symbol":"omg_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"xrp_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"main"}, +{"symbol":"dash_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"zec_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"ada_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"main"}, +{"symbol":"steem_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"main"}, +{"symbol":"iota_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"main"}, +{"symbol":"poly_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"kan_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"lba_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"wan_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"bft_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"btm_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"ont_btc","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"iost_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"ht_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"trx_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"smt_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"ela_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"wicc_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"ocn_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"zla_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"abt_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"mtx_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"nas_btc","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"ven_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"dta_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"neo_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"wax_btc","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"bts_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"zil_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"theta_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"ctxc_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"srn_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"xem_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"icx_btc","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"dgd_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"chat_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"wpr_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"lun_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"swftc_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"snt_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"meet_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"yee_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"elf_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"let_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"qtum_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"lsk_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"itc_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"soc_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"qash_btc","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"mds_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"eko_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"topc_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"mtn_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"act_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"hsr_btc","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"stk_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"storj_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"gnx_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"dbc_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"snc_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"cmt_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"tnb_btc","priceprecision":10,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"ruff_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"qun_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"zrx_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"knc_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"blz_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"propy_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"rpx_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"appc_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"aidoc_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"powr_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"cvc_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"pay_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"qsp_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"dat_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"rdn_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"mco_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"rcn_btc","priceprecision":10,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"mana_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"utk_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"tnt_btc","priceprecision":10,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"gas_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"bat_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"ost_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"link_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"gnt_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"mtl_btc","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"evx_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"req_btc","priceprecision":8,"amountprecision":1,"symbol-partition":"innovation"}, +{"symbol":"adx_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"ast_btc","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"eng_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"salt_btc","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"edu_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"wtc_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"bifi_btc","priceprecision":8,"amountprecision":4,"symbol-partition":"bifurcation"}, +{"symbol":"bcx_btc","priceprecision":8,"amountprecision":4,"symbol-partition":"bifurcation"}, +{"symbol":"bcd_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"bifurcation"}, +{"symbol":"sbtc_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"bifurcation"}, +{"symbol":"btg_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"bifurcation"}, +{"symbol":"xmr_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"eos_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"main"}, +{"symbol":"omg_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"iota_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"ada_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"steem_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"poly_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"kan_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"lba_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"wan_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"bft_eth","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"zrx_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"ast_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"knc_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"ont_eth","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"ht_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"btm_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"iost_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"smt_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"ela_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"trx_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"abt_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"nas_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"ocn_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"wicc_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"zil_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"ctxc_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"zla_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"wpr_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"dta_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"mtx_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"theta_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"srn_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"ven_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"bts_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"wax_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"hsr_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"icx_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"mtn_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"act_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"blz_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"qash_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"ruff_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"cmt_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"elf_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"meet_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"soc_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"qtum_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"itc_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"swftc_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"yee_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"lsk_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"lun_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"let_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"gnx_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"chat_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"eko_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"topc_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"dgd_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"stk_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"mds_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"dbc_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"snc_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"pay_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"qun_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"aidoc_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"tnb_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"appc_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"rdn_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"utk_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"powr_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"bat_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"propy_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"mana_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"req_eth","priceprecision":8,"amountprecision":1,"symbol-partition":"innovation"}, +{"symbol":"cvc_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"qsp_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"evx_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"dat_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"mco_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"gnt_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"gas_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"ost_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"link_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"rcn_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"tnt_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, +{"symbol":"eng_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"salt_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"adx_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"edu_eth","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"wtc_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"xrp_ht","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"iost_ht","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"dash_ht","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"wicc_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"eos_ht","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"bch_ht","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"ltc_ht","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"etc_ht","priceprecision":6,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"waves_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"waves_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"hb10_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"main"}, +{"symbol":"cmt_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"dcr_btc","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"dcr_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"pai_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"pai_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"box_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"box_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"dgb_btc","priceprecision":10,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"dgb_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"gxs_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"gxs_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"xlm_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"xlm_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"bix_btc","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, +{"symbol":"bix_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"bix_usdt","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}]; + +okexRegulation = [ + {"symbol":"bch_btc", "minamount":0.001, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"ltc_btc", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, + {"symbol":"eth_btc", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, + {"symbol":"etc_btc", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"eth_usdt", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"btc_usdt", "minamount":0.001, "amountprecision":0.00000001, "priceprecision": 0.0001}, + {"symbol":"bt2_btc", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"etc_eth", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"btg_btc", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"ltc_usdt", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"etc_usdt", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.0001}, + {"symbol":"bch_usdt", "minamount":0.001, "amountprecision":0.00000001, "priceprecision": 0.0001}, + {"symbol":"qtum_btc", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"qtum_usdt", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.0001}, + {"symbol":"qtum_eth", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"neo_btc", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"gas_btc", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"hsr_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"neo_eth", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"gas_eth", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"hsr_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"neo_usdt", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.0001}, + {"symbol":"gas_usdt", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.0001}, + {"symbol":"hsr_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"dash_btc", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, + {"symbol":"xrp_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"zec_btc", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, + {"symbol":"dash_eth", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, + {"symbol":"xrp_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"zec_eth", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, + {"symbol":"dash_usdt", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"xrp_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"zec_usdt", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"iota_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"xuc_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"iota_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"xuc_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"iota_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"xuc_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"eos_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"omg_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"eos_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"omg_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"eos_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"omg_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"act_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"btm_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"act_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"btm_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"act_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"btm_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"bcd_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"bcd_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"storj_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"snt_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"storj_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"snt_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"storj_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"snt_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"pay_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"dgd_btc", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, + {"symbol":"gnt_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"pay_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"dgd_eth", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, + {"symbol":"gnt_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"pay_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"dgd_usdt", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"gnt_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"lrc_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"nuls_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"mco_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"lrc_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"nuls_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"mco_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"lrc_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"nuls_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"mco_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"btg_usdt", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.0001}, + {"symbol":"cmt_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"itc_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"cmt_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"itc_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"cmt_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"itc_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"sbtc_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"pra_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"san_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"edo_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"avt_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"pra_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"san_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"edo_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"avt_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"pra_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"san_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"edo_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"avt_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"ltc_eth", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, + {"symbol":"link_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"salt_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"1st_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"wtc_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"sngls_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"snm_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"zrx_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"bnt_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"cvc_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"link_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"salt_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"1st_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"wtc_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"sngls_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"snm_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"zrx_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"bnt_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"cvc_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"link_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"salt_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"1st_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"wtc_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"sngls_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"snm_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"zrx_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"bnt_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"cvc_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"bcx_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"mana_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"rcn_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"mana_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"mana_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"vee_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"vee_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"vee_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"tnb_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"tnb_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"tnb_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"amm_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"amm_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"amm_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"knc_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"knc_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"knc_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"dat_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"dat_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"dat_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"gnx_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"gnx_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"gnx_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"icx_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"icx_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"icx_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"ark_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"ark_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"ark_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"yoyo_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"yoyo_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"yoyo_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"qvt_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"qvt_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"qvt_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"elf_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"elf_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"elf_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"ast_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ast_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ast_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"sub_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"sub_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"sub_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"dnt_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"dnt_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"dnt_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"fun_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"fun_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"fun_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"ace_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"ace_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"ace_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"trx_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"trx_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"trx_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"evx_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"evx_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"evx_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"mda_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"mda_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"mda_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"mth_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"mth_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"mth_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"mtl_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"mtl_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"mtl_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"xem_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"xem_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"xem_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"icn_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"icn_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"icn_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"eng_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"req_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"oax_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"dgb_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"ppt_btc", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"dgb_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"dgb_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"ppt_eth", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"ppt_usdt", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.0001}, + {"symbol":"oax_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"oax_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"req_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"req_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"eng_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"eng_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"rcn_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"rcn_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"swftc_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"swftc_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"swftc_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"rdn_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"rdn_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"rdn_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"xmr_btc", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, + {"symbol":"xmr_eth", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, + {"symbol":"xmr_usdt", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"xlm_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"xlm_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"xlm_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"kcash_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"kcash_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"kcash_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"mdt_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"mdt_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"mdt_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"nas_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"nas_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"nas_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"rnt_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"rnt_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"rnt_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"wrc_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"wrc_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"wrc_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"ukg_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ukg_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ukg_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"ugc_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"ugc_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"ugc_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"dpy_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"dpy_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"dpy_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"read_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"read_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"read_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"ssc_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"ssc_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"ssc_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"aac_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"fair_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"aac_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"aac_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"fair_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"fair_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"ubtc_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"ubtc_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"ubtc_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"cag_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"cag_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"cag_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"dna_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"lend_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"lend_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"dna_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"lend_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"dna_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"rct_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"rct_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"rct_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"bch_eth", "minamount":0.001, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"show_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"show_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"show_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"vib_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"vib_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"vib_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"mot_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"mot_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"mot_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"utk_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"utk_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"utk_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"mag_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"mag_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"mag_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"topc_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"topc_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"brd_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"topc_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"qun_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"brd_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"qun_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"qun_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"brd_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"viu_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"viu_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"ost_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"viu_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"ost_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ost_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"aidoc_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"aidoc_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"aidoc_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"int_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"la_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"la_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"la_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"int_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"int_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"ipc_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ipc_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ipc_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"ngc_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ngc_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ngc_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"tio_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"tio_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"tio_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"iost_btc", "minamount":0.1, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"iost_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"iost_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"poe_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"poe_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"poe_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"mof_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"yee_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"mof_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"yee_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"yee_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"mof_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"ins_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ins_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ins_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"tct_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"tct_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"tct_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"atl_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"atl_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"atl_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"theta_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"theta_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"lev_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"theta_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"lev_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"lev_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"stc_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"spf_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"stc_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"spf_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"spf_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"stc_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"ref_btc", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"ref_eth", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"ref_usdt", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.0001}, + {"symbol":"snc_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"snc_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"snc_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"pst_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"pst_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"pst_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"can_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"can_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"can_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"hot_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"mkr_btc", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, + {"symbol":"mkr_eth", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, + {"symbol":"mkr_usdt", "minamount":0.001, "amountprecision":0.00000001, "priceprecision": 0.0001}, + {"symbol":"hot_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"key_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"hot_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"key_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"key_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"light_btc", "minamount":10, "amountprecision":1, "priceprecision": 1E-10}, + {"symbol":"light_eth", "minamount":10, "amountprecision":1, "priceprecision": 0.000000001}, + {"symbol":"light_usdt", "minamount":10, "amountprecision":1, "priceprecision": 0.000001}, + {"symbol":"true_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"true_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"true_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"of_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 1E-10}, + {"symbol":"of_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 1E-10}, + {"symbol":"of_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.000001}, + {"symbol":"soc_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"soc_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"soc_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"wbtc_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"dent_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"dent_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"dent_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"zen_btc", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"zen_eth", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.00000001}, + {"symbol":"zen_usdt", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.0001}, + {"symbol":"hmc_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"hmc_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"hmc_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"zip_btc", "minamount":10, "amountprecision":1, "priceprecision": 0.000000001}, + {"symbol":"zip_eth", "minamount":10, "amountprecision":1, "priceprecision": 0.00000001}, + {"symbol":"zip_usdt", "minamount":10, "amountprecision":1, "priceprecision": 0.000001}, + {"symbol":"nano_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"nano_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"nano_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"cic_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"cic_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"cic_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"gto_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"gto_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"gto_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"chat_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"chat_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"chat_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"insur_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"insur_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"insur_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"cbt_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"cbt_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"cbt_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"r_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"r_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"r_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"uct_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"uct_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"uct_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"bec_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"bec_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"bec_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"mith_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"mith_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"mith_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"abt_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"abt_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"abt_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"bkx_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"bkx_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"bkx_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"gtc_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"gtc_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"gtc_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"auto_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"auto_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"auto_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"gsc_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"gsc_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"gsc_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"rfr_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"rfr_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"rfr_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"trio_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"trio_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"trio_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"tra_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"tra_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"tra_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"ren_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"ren_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"ren_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"wfee_btc", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"wfee_eth", "minamount":10, "amountprecision":0.1, "priceprecision": 0.00000001}, + {"symbol":"wfee_usdt", "minamount":10, "amountprecision":0.1, "priceprecision": 0.0001}, + {"symbol":"dadi_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"dadi_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"dadi_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"enj_btc", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"enj_eth", "minamount":10, "amountprecision":0.01, "priceprecision": 0.00000001}, + {"symbol":"enj_usdt", "minamount":10, "amountprecision":0.01, "priceprecision": 0.0001}, + {"symbol":"ont_btc", "minamount":0.1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ont_eth", "minamount":0.1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ont_usdt", "minamount":0.1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"okb_usdt", "minamount":1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"okb_btc", "minamount":1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"okb_eth", "minamount":1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"ltc_okb", "minamount":0.01, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"etc_okb", "minamount":0.01, "amountprecision":0.00001, "priceprecision": 0.0001}, + {"symbol":"bch_okb", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"xrp_okb", "minamount":0.01, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"eos_okb", "minamount":0.01, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"qtum_okb", "minamount":0.01, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"dash_okb", "minamount":0.01, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"neo_okb", "minamount":0.01, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"iota_okb", "minamount":0.01, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"zec_okb", "minamount":0.01, "amountprecision":0.000001, "priceprecision": 0.0001}, + {"symbol":"ctxc_btc", "minamount":0.01, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ctxc_eth", "minamount":0.01, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"ctxc_usdt", "minamount":0.01, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"zil_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"zil_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"zil_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"you_okb", "minamount":10, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"you_btc", "minamount":0.1, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"you_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"you_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00001}, + {"symbol":"lba_okb", "minamount":0.1, "amountprecision":0.001, "priceprecision": 0.0001}, + {"symbol":"lba_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"lba_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"lba_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"ok06ett_usdt", "minamount":0.01, "amountprecision":0.00000001, "priceprecision": 0.0001}, + {"symbol":"cai_okb", "minamount":10, "amountprecision":0.001, "priceprecision": 0.000001}, + {"symbol":"lsk_btc", "minamount":0.01, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"lsk_eth", "minamount":0.01, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"lsk_usdt", "minamount":0.01, "amountprecision":0.00000001, "priceprecision": 0.0001}, + {"symbol":"cai_btc", "minamount":10, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"cai_eth", "minamount":10, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"cai_usdt", "minamount":10, "amountprecision":0.0001, "priceprecision": 0.000001}, + {"symbol":"ae_btc", "minamount":0.01, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"ae_okb", "minamount":0.01, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"sc_okb", "minamount":10, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"kan_okb", "minamount":10, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"win_okb", "minamount":10, "amountprecision":0.001, "priceprecision": 0.000001}, + {"symbol":"sc_eth", "minamount":10, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"sc_btc", "minamount":10, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"sc_usdt", "minamount":10, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"ae_eth", "minamount":0.01, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"ae_usdt", "minamount":0.01, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"kan_btc", "minamount":10, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"kan_eth", "minamount":10, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"kan_usdt", "minamount":10, "amountprecision":0.0001, "priceprecision": 0.00001}, + {"symbol":"win_btc", "minamount":10, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"win_eth", "minamount":10, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"win_usdt", "minamount":10, "amountprecision":0.001, "priceprecision": 0.000001}, + {"symbol":"ors_okb", "minamount":1, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"mvp_okb", "minamount":10, "amountprecision":0.0001, "priceprecision": 0.00001}, + {"symbol":"dcr_okb", "minamount":0.01, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"dcr_btc", "minamount":0.01, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"dcr_eth", "minamount":0.01, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"dcr_usdt", "minamount":0.01, "amountprecision":0.00000001, "priceprecision": 0.0001}, + {"symbol":"waves_okb", "minamount":0.01, "amountprecision":0.0001, "priceprecision": 0.0001}, + {"symbol":"waves_btc", "minamount":0.01, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"waves_eth", "minamount":0.01, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"waves_usdt", "minamount":0.01, "amountprecision":0.00000001, "priceprecision": 0.0001}, + {"symbol":"ors_btc", "minamount":1, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"ors_eth", "minamount":1, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"ors_usdt", "minamount":1, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"mvp_btc", "minamount":10, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"mvp_eth", "minamount":10, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"mvp_usdt", "minamount":10, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"nas_okb", "minamount":0.1, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"xas_okb", "minamount":0.1, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"cvt_okb", "minamount":1, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"nxt_btc", "minamount":1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"zco_okb", "minamount":1, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"ardr_btc", "minamount":1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"egt_okb", "minamount":1, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"xas_btc", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"xas_eth", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"xas_usdt", "minamount":0.1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"cvt_btc", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"cvt_eth", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00000001}, + {"symbol":"cvt_usdt", "minamount":1, "amountprecision":0.001, "priceprecision": 0.00001}, + {"symbol":"egt_btc", "minamount":1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"egt_eth", "minamount":1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"egt_usdt", "minamount":1, "amountprecision":0.0001, "priceprecision": 0.00001}, + {"symbol":"zco_btc", "minamount":1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"zco_eth", "minamount":1, "amountprecision":0.0001, "priceprecision": 0.00000001}, + {"symbol":"bcn_okb", "minamount":10, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"bcn_btc", "minamount":10, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"bcn_usdt", "minamount":10, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"let_okb", "minamount":1, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"let_btc", "minamount":1, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"let_eth", "minamount":1, "amountprecision":0.00000001, "priceprecision": 0.00000001}, + {"symbol":"let_usdt", "minamount":1, "amountprecision":0.00000001, "priceprecision": 0.00001}, + {"symbol":"cit_okb", "minamount":1, "amountprecision":0.00000001, "priceprecision": 0.00001}]; + +var binanceRegulation = [{"symbol":"ETH_BTC", "minamount":0.001, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"LTC_BTC", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"BNB_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"NEO_BTC", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"GAS_BTC", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"BCC_BTC", "minamount":0.001, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"MCO_BTC", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"WTC_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"QTUM_BTC", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"OMG_BTC", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"ZRX_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"STRAT_BTC", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"SNGLS_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"BQX_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"KNC_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"FUN_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"SNM_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"LINK_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"XVG_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"CTR_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"SALT_BTC", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"IOTA_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"MDA_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"MTL_BTC", "minamount":1, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"SUB_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"EOS_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"SNT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"ETC_BTC", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"MTH_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"ENG_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"DNT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"BNT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"AST_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"DASH_BTC", "minamount":0.001, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"ICN_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"OAX_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"BTG_BTC", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"EVX_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"REQ_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"LRC_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"VIB_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"HSR_BTC", "minamount":1, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"TRX_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"POWR_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"ARK_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"YOYO_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"XRP_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"MOD_BTC", "minamount":1, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"ENJ_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"STORJ_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"VET_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"KMD_BTC", "minamount":1, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"RCN_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"NULS_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"RDN_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"XMR_BTC", "minamount":0.001, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"DLT_BTC", "minamount":0.001, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"AMB_BTC", "minamount":0.001, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"BAT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"ZEC_BTC", "minamount":0.001, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"BCPT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"ARN_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"GVT_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"CDT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"GXS_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"POE_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"QSP_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"BTS_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"XZC_BTC", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"LSK_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"TNT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"FUEL_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"MANA_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"BCD_BTC", "minamount":0.001, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"DGD_BTC", "minamount":0.001, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"ADX_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"ADA_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"PPT_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"CMT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"XLM_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"CND_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"LEND_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"WABI_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"TNB_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"WAVES_BTC", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"ICX_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"GTO_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"OST_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"ELF_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"AION_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"NEBL_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"BRD_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"EDO_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"WINGS_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"NAV_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"LUN_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"TRIG_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"APPC_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"VIBE_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"RLC_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"INS_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"PIVX_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"IOST_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"CHAT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"STEEM_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"NANO_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"VIA_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"BLZ_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"AE_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"RPX_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"NCASH_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"POA_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"ZIL_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"ONT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"STORM_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"XEM_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"WAN_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"QLC_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"SYS_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"WPR_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"GRS_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"CLOAK_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"GNT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"LOOM_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"BCN_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"REP_BTC", "minamount":0.001, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"TUSD_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"ZEN_BTC", "minamount":0.001, "priceprecision":0.000001, "mintotal":0.001}, +{"symbol":"CVC_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"THETA_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"IOTX_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"QKC_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"AGI_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"NXS_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"DATA_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"SC_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"NPXS_BTC", "minamount":0.1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"KEY_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"NAS_BTC", "minamount":0.01, "priceprecision":0.0000001, "mintotal":0.001}, +{"symbol":"MFT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"DENT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"ARDR_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"HOT_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"DOCK_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"POLY_BTC", "minamount":1, "priceprecision":0.00000001, "mintotal":0.001}, +{"symbol":"BNB_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"QTUM_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"SNT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"BNT_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"EOS_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"OAX_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"DNT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"MCO_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"ICN_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"WTC_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"OMG_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"ZRX_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"STRAT_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"SNGLS_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"BXQ_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"KNC_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"FUN_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"SNM_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"NEO_ETH", "minamount":0.01, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"LINK_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"XVG_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"CTR_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"SALT_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"IOTA_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"MDA_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"MTL_ETH", "minamount":1, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"SUB_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"ETC_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"MTH_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"ENG_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"AST_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"DASH_ETH", "minamount":0.001, "priceprecision":0.00001, "mintotal":0.01}, +{"symbol":"BTG_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"EVX_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"REQ_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"LRC_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"VIB_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"HSR_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"TRX_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"POWR_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"ARK_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"YOYO_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"XRP_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"MOD_ETH", "minamount":1, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"ENJ_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"STORJ_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"VET_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"KMD_ETH", "minamount":1, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"RCN_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"NULS_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"RDN_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"XMR_ETH", "minamount":1, "priceprecision":0.00001, "mintotal":0.01}, +{"symbol":"DLT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"AMB_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"BCC_ETH", "minamount":1, "priceprecision":0.00001, "mintotal":0.01}, +{"symbol":"BAT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"ZEC_ETH", "minamount":0.001, "priceprecision":0.00001, "mintotal":0.01}, +{"symbol":"BCPT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"ARN_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"GVT_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"CDT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"GXS_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"POE_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"QSP_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"BTS_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"XZC_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"LSK_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"TNT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"FUEL_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"MANA_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"BCD_ETH", "minamount":0.001, "priceprecision":0.00001, "mintotal":0.01}, +{"symbol":"DGD_ETH", "minamount":0.001, "priceprecision":0.00001, "mintotal":0.01}, +{"symbol":"ADX_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"ADA_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"PPT_ETH", "minamount":1, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"CMT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"XLM_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"CND_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"LEND_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"WABI_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"LTC_ETH", "minamount":0.001, "priceprecision":0.00001, "mintotal":0.01}, +{"symbol":"TNB_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"WAVES_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"ICX_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"GTO_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"OST_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"ELF_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"AION_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"NEBL_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"BRD_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"EDO_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"WINGS_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"NAV_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"LUN_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"TRIG_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"APPC_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"VIBE_ETH", "minamount":1, "priceprecision":0.0000001, "mintotal":0.01}, +{"symbol":"RLC_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"INS_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"PIVX_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"IOST_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"CHAT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"STEEM_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"NANO_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"VIA_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"BLZ_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"AE_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"RPX_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"NCASH_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"POA_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"ZIL_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"ONT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"STORM_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"XEM_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"WAN_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"QLC_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"SYS_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"WPR_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"GRS_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"CLOAK_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"GNT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"LOOM_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"BCN_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"REP_ETH", "minamount":0.001, "priceprecision":0.00001, "mintotal":0.01}, +{"symbol":"TUSD_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"ZEN_ETH", "minamount":0.001, "priceprecision":0.00001, "mintotal":0.01}, +{"symbol":"CVC_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"THETA_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"IOTX_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"QKC_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"AGI_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"NXS_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"DATA_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"SC_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"NPXS_ETH", "minamount":0.1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"KEY_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"NAS_ETH", "minamount":0.01, "priceprecision":0.000001, "mintotal":0.01}, +{"symbol":"MFT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"DENT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"ARDR_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"HOT_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"DOCK_ETH", "minamount":1, "priceprecision":0.00000001, "mintotal":0.01}, +{"symbol":"VET_BNB", "minamount":0.1, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"YOYO_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"POWR_BNB", "minamount":0.01, "priceprecision":0.0001, "mintotal":1}, +{"symbol":"NULS_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"RCN_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"RDN_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"DLT_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"WTC_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"AMB_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"BCC_BNB", "minamount":0.00001, "priceprecision":0.01, "mintotal":1}, +{"symbol":"BAT_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"BCPT_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"NEO_BNB", "minamount":0.001, "priceprecision":0.001, "mintotal":1}, +{"symbol":"QSP_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"BTS_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"XZC_BNB", "minamount":0.001, "priceprecision":0.001, "mintotal":1}, +{"symbol":"LSK_BNB", "minamount":0.001, "priceprecision":0.0001, "mintotal":1}, +{"symbol":"IOTA_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"ADX_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"CMT_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"XLM_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"CND_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"WABI_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"LTC_BNB", "minamount":0.00001, "priceprecision":0.01, "mintotal":1}, +{"symbol":"WAVES_BNB", "minamount":0.01, "priceprecision":0.0001, "mintotal":1}, +{"symbol":"ICX_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"GTO_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"OST_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"AION_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"NEBL_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"BRD_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"MCO_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"NAV_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"TRIG_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"APPC_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"RLC_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"PIVX_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"STEEM_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"NANO_BNB", "minamount":0.01, "priceprecision":0.0001, "mintotal":1}, +{"symbol":"VIA_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"BLZ_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"AE_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"RPX_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"NCASH_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"POA_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"ZIL_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"ONT_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"STORM_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"QTUM_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"XEM_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"WAN_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"SYS_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"QLC_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"ADA_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"GNT_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"LOOM_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"BCN_BNB", "minamount":1, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"REP_BNB", "minamount":0.001, "priceprecision":0.001, "mintotal":1}, +{"symbol":"TUSD_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"ZEN_BNB", "minamount":0.001, "priceprecision":0.001, "mintotal":1}, +{"symbol":"SKY_BNB", "minamount":0.001, "priceprecision":0.001, "mintotal":1}, +{"symbol":"EOS_BNB", "minamount":0.01, "priceprecision":0.0001, "mintotal":1}, +{"symbol":"CVC_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"THETA_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"XRP_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"AGI_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"NXS_BNB", "minamount":0.01, "priceprecision":0.0001, "mintotal":1}, +{"symbol":"ENJ_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"ETC_BNB", "minamount":0.01, "priceprecision":0.0001, "mintotal":1}, +{"symbol":"SC_BNB", "minamount":0.1, "priceprecision":0.000001, "mintotal":1}, +{"symbol":"NAS_BNB", "minamount":0.1, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"MFT_BNB", "minamount":1, "priceprecision":0.000001, "mintotal":1}, +{"symbol":"ARDR_BNB", "minamount":0.01, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"POLY_BNB", "minamount":0.1, "priceprecision":0.00001, "mintotal":1}, +{"symbol":"BTC_USDT", "minamount":0.000001, "priceprecision":0.01, "mintotal":10}, +{"symbol":"ETH_USDT", "minamount":0.00001, "priceprecision":0.01, "mintotal":10}, +{"symbol":"BNB_USDT", "minamount":0.01, "priceprecision":0.0001, "mintotal":10}, +{"symbol":"BCC_USDT", "minamount":0.00001, "priceprecision":0.01, "mintotal":10}, +{"symbol":"NEO_USDT", "minamount":0.001, "priceprecision":0.001, "mintotal":10}, +{"symbol":"LTC_USDT", "minamount":0.00001, "priceprecision":0.01, "mintotal":10}, +{"symbol":"QTUM_USDT", "minamount":0.001, "priceprecision":0.01, "mintotal":10}, +{"symbol":"ADA_USDT", "minamount":0.001, "priceprecision":0.00001, "mintotal":10}, +{"symbol":"XRP_USDT", "minamount":0.01, "priceprecision":0.00001, "mintotal":10}, +{"symbol":"EOS_USDT", "minamount":0.01, "priceprecision":0.0001, "mintotal":10}, +{"symbol":"XLM_USDT", "minamount":0.01, "priceprecision":0.00001, "mintotal":10}, +{"symbol":"IOTA_USDT", "minamount":0.01, "priceprecision":0.0001, "mintotal":10}, +{"symbol":"TUSD_USDT", "minamount":0.01, "priceprecision":0.0001, "mintotal":10}, +{"symbol":"ONT_USDT", "minamount":0.01, "priceprecision":0.001, "mintotal":10}, +{"symbol":"TRX_USDT", "minamount":0.1, "priceprecision":0.00001, "mintotal":10}, +{"symbol":"ETC_USDT", "minamount":0.1, "priceprecision":0.0001, "mintotal":10}, +{"symbol":"ICX_USDT", "minamount":0.01, "priceprecision":0.0001, "mintotal":10}, +{"symbol":"VET_USDT", "minamount":0.1, "priceprecision":0.00001, "mintotal":10}, +{"symbol":"NULS_USDT", "minamount":0.01, "priceprecision":0.0001, "mintotal":10}]; + +$.Test = function() { + Log($.GetMinAmount('huobi', 'eth_usdt')); + Log($.GetPricePrecision('huobi', 'eth_usdt')); + Log($.GetAmountPrecision('huobi', 'eth_usdt')); +}; + +function main() { + $.Test(); +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/108887 + +> 更新时间 + +2018-08-30 23:47:33 diff --git "a/\344\273\216\347\254\254\344\270\211\346\226\271\347\275\221\347\253\231\350\216\267\345\217\226K\347\272\277 (0804\346\233\264\346\226\260).js" "b/\344\273\216\347\254\254\344\270\211\346\226\271\347\275\221\347\253\231\350\216\267\345\217\226K\347\272\277 (0804\346\233\264\346\226\260).md" similarity index 92% rename from "\344\273\216\347\254\254\344\270\211\346\226\271\347\275\221\347\253\231\350\216\267\345\217\226K\347\272\277 (0804\346\233\264\346\226\260).js" rename to "\344\273\216\347\254\254\344\270\211\346\226\271\347\275\221\347\253\231\350\216\267\345\217\226K\347\272\277 (0804\346\233\264\346\226\260).md" index d6ef80d5..d2a010c7 100644 --- "a/\344\273\216\347\254\254\344\270\211\346\226\271\347\275\221\347\253\231\350\216\267\345\217\226K\347\272\277 (0804\346\233\264\346\226\260).js" +++ "b/\344\273\216\347\254\254\344\270\211\346\226\271\347\275\221\347\253\231\350\216\267\345\217\226K\347\272\277 (0804\346\233\264\346\226\260).md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/12977 -策略名称: 从第三方网站获取K线 (0804更新) -策略作者: 数·狂 -策略描述: + +> 策略名称 + +从第三方网站获取K线 (0804更新) + +> 策略作者 + +数·狂 + +> 策略描述 对于不支持获取K线数据的平台(BitVC期货、BTCC的BTC现货、中国比特币的ETH、ETC),如果在策略开始时必须获取足够多的K线,使用本模板则可从第三方网站直接获得平台的历史K线数据。 注意: @@ -12,9 +17,12 @@ K线数据每3秒更新一次,因此无法高频调用。 0427更新:处理了Parse JSON数据时可能抛出的异常、出现异常时返回值统一为null。 -*/ +> 源码 (javascript) + +``` javascript + $.AltRecords = function(exchange, timeframe, size, includeLastBar) { var symbol; var info; @@ -63,3 +71,12 @@ function main() { rec = $.AltRecords(exchange, "4hour", 100, 1); // 获取4小时K线, 100条, 含最后一条Bar if (rec) Log(rec.length, rec[rec.length-1]); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/12977 + +> 更新时间 + +2016-08-04 22:35:27 diff --git "a/\344\273\216\347\254\254\344\270\211\346\226\271\350\216\267\345\217\226K\347\272\277 (\345\225\206\345\223\201\346\234\237\350\264\247\347\211\210) Rev. 161216.js" "b/\344\273\216\347\254\254\344\270\211\346\226\271\350\216\267\345\217\226K\347\272\277 (\345\225\206\345\223\201\346\234\237\350\264\247\347\211\210) Rev. 161216.md" similarity index 96% rename from "\344\273\216\347\254\254\344\270\211\346\226\271\350\216\267\345\217\226K\347\272\277 (\345\225\206\345\223\201\346\234\237\350\264\247\347\211\210) Rev. 161216.js" rename to "\344\273\216\347\254\254\344\270\211\346\226\271\350\216\267\345\217\226K\347\272\277 (\345\225\206\345\223\201\346\234\237\350\264\247\347\211\210) Rev. 161216.md" index 2e14f932..440242f3 100644 --- "a/\344\273\216\347\254\254\344\270\211\346\226\271\350\216\267\345\217\226K\347\272\277 (\345\225\206\345\223\201\346\234\237\350\264\247\347\211\210) Rev. 161216.js" +++ "b/\344\273\216\347\254\254\344\270\211\346\226\271\350\216\267\345\217\226K\347\272\277 (\345\225\206\345\223\201\346\234\237\350\264\247\347\211\210) Rev. 161216.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/15498 -策略名称: 从第三方获取K线 (商品期货版) Rev. 161216 -策略作者: 数·狂 -策略描述: + +> 策略名称 + +从第三方获取K线 (商品期货版) Rev. 161216 + +> 策略作者 + +数·狂 + +> 策略描述 如果在策略开始时必须获取足够多的K线,使用本模板则可从第三方直接获得指定合约的历史K线数据。 Update 20160810:支持和讯数据源。(推荐!注意:K线周期支持1、5、15、30、60<分钟>和1440<日线>、10080<周线>) @@ -11,8 +16,11 @@ Update 20160615:支持新浪财经数据源。 仅适用于实盘交易。 作者不保证第三方数据准确性和程序正确性,仅供学习参考。 -*/ + +> 源码 (javascript) + +``` javascript $.BTRecords = function(instrument, timeframe, size, includeLastBar) { var info; var record = []; @@ -188,3 +196,12 @@ function main() { rec = $.SNRecords('i1705', 15, 100, true); // 新浪财经数据对比 if (rec) Log(rec.length, rec[rec.length - 1]); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/15498 + +> 更新时间 + +2016-12-16 17:23:55 diff --git "a/\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.js" "b/\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.md" similarity index 74% rename from "\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.js" rename to "\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.md" index bdd4479f..061f4761 100644 --- "a/\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.js" +++ "b/\344\273\223\344\275\215\345\235\207\350\241\241\347\255\226\347\225\245.md" @@ -1,18 +1,27 @@ -/* -策略出处: https://www.fmz.com/strategy/54182 -策略名称: 仓位均衡策略 -策略作者: 春哥 -策略描述: +> 策略名称 +仓位均衡策略 +> 策略作者 -参数 默认值 描述 ---------------- ----- ----- -TARGET_POSITION 0.5 固定仓位 -ACT_DIFF 0.1 仓位变化量 -*/ +春哥 + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|TARGET_POSITION|0.5|固定仓位| +|ACT_DIFF|0.1|仓位变化量| + + +> 源码 (javascript) + +``` javascript function main() { while (true) { Sleep(300000); @@ -41,3 +50,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/54182 + +> 更新时间 + +2017-09-06 21:57:31 diff --git "a/\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.js" "b/\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.md" similarity index 84% rename from "\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.js" rename to "\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.md" index ccc31da2..4611fda9 100644 --- "a/\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.js" +++ "b/\344\273\243\346\233\277\345\272\237\345\274\203\347\232\204GetMinStock()\345\207\275\346\225\260.md" @@ -1,13 +1,19 @@ -/* -策略出处: https://www.fmz.com/strategy/69436 -策略名称: 代替废弃的GetMinStock()函数 -策略作者: hugo_zhou -策略描述: +> 策略名称 +代替废弃的GetMinStock()函数 -*/ +> 策略作者 +hugo_zhou + + + + + +> 源码 (javascript) + +``` javascript /**************** 针对 火币pro 获取不同货币对的最小交易量 其他平台需要自行添加不同的错误解析代码 @@ -35,3 +41,12 @@ function main() { Log(exchange.GetName()+huobipro[j],":",_G(exchange.GetName()+huobipro[j])); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/69436 + +> 更新时间 + +2018-01-17 17:42:25 diff --git "a/\344\273\267\345\200\2740.418.js" "b/\344\273\267\345\200\2740.418.md" similarity index 92% rename from "\344\273\267\345\200\2740.418.js" rename to "\344\273\267\345\200\2740.418.md" index f0eb7684..60f5f0cb 100644 --- "a/\344\273\267\345\200\2740.418.js" +++ "b/\344\273\267\345\200\2740.418.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/10744 -策略名称: 价值0.418 -策略作者: kakababy -策略描述: + +> 策略名称 + +价值0.418 + +> 策略作者 + +kakababy + +> 策略描述 设定一个用于投资的资金额度,如10000元。设定一个资金和比特币的价值比例,如50:50。根据现价,一直维持资金和比特币的价值比例。 @@ -12,18 +17,24 @@ 同理,币价下跌时则买入以保持比例不变。 +> 策略参数 + + -参数 默认值 描述 --------------- ----- --------- -UseAccount true 使用帐户内全部资金 -InitMoney 10000 初始资金量。 -InitStock 5 初始币数。 -StockRatio 0.418 币价值占总价值比例 -InvestInterval true 投资间隔。 -ErrorInterval 300 出错重试间隔。 -SlidePrice 0.01 滑点 -*/ +|参数|默认值|描述| +|----|----|----| +|UseAccount|true|使用帐户内全部资金| +|InitMoney|10000|初始资金量。| +|InitStock|5|初始币数。| +|StockRatio|0.418|币价值占总价值比例| +|InvestInterval|true|投资间隔。| +|ErrorInterval|300|出错重试间隔。| +|SlidePrice|0.01|滑点| + +> 源码 (javascript) + +``` javascript var initAccount = null; var initPrice = 0; var stockHold = 0; @@ -246,3 +257,12 @@ function onexit() { Log('Set prices:', prices); Log('Robot Stopped!#ff0000@'); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/10744 + +> 更新时间 + +2016-02-14 00:09:10 diff --git "a/\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225.js" "b/\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225.md" similarity index 88% rename from "\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225.js" rename to "\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225.md" index a99c648c..7a241b0f 100644 --- "a/\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225.js" +++ "b/\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225.md" @@ -1,19 +1,28 @@ -/* -策略出处: https://www.fmz.com/strategy/67128 -策略名称: 价值平均定投 -策略作者: 小码哥 -策略描述: +> 策略名称 +价值平均定投 +> 策略作者 -参数 默认值 描述 ------------------- ----- ----- -singleInvestAmount 0.1 单次买入量 -expectGrowthRate 0.008 预期增长率 -*/ +小码哥 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|singleInvestAmount|0.1|单次买入量| +|expectGrowthRate|0.008|预期增长率| +> 源码 (javascript) + +``` javascript + /*backtest start: 2017-12-01 end: 2018-01-01 @@ -90,3 +99,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/67128 + +> 更新时间 + +2018-01-04 21:01:07 diff --git "a/\344\273\267\346\240\274\346\263\242\345\212\250\346\212\245\350\255\246.js" "b/\344\273\267\346\240\274\346\263\242\345\212\250\346\212\245\350\255\246.md" similarity index 86% rename from "\344\273\267\346\240\274\346\263\242\345\212\250\346\212\245\350\255\246.js" rename to "\344\273\267\346\240\274\346\263\242\345\212\250\346\212\245\350\255\246.md" index 0a6a6973..bbc73461 100644 --- "a/\344\273\267\346\240\274\346\263\242\345\212\250\346\212\245\350\255\246.js" +++ "b/\344\273\267\346\240\274\346\263\242\345\212\250\346\212\245\350\255\246.md" @@ -1,23 +1,34 @@ -/* -策略出处: https://www.fmz.com/strategy/885 -策略名称: 价格波动报警 -策略作者: Zero -策略描述: + +> 策略名称 + +价格波动报警 + +> 策略作者 + +Zero + +> 策略描述 程序监视指定周期内价格波动幅度,如果超过指定幅度, 就短信通知给指定手机用户, 使用短信宝接口,可以发送给多个手机号, 以逗号分开 周期请选择K线周期, K线周期为1分钟则为监视一分钟内的数据 +> 策略参数 + + -参数 默认值 描述 ------------- ----- --------- -MaxRatio 1.5 波动幅度(百分比) -LoopInterval 5 采集间隔(秒) -EnableSMS true 开启短信通知 -SMSUser test 短信宝用户名 -SMSPass test 短信宝密码MD5 -PhoneNum 111 通知手机号 -*/ +|参数|默认值|描述| +|----|----|----| +|MaxRatio|1.5|波动幅度(百分比)| +|LoopInterval|5|采集间隔(秒)| +|EnableSMS|true|开启短信通知| +|SMSUser|test|短信宝用户名| +|SMSPass|test|短信宝密码MD5| +|PhoneNum|111|通知手机号| + +> 源码 (javascript) + +``` javascript function _N(v) { return Math.floor(parseFloat(v.toFixed(10))*1000)/1000; } @@ -110,3 +121,12 @@ function main() { Sleep(LoopInterval * 1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/885 + +> 更新时间 + +2014-10-11 18:47:40 diff --git "a/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245.md" "b/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245.md" new file mode 100644 index 00000000..e1c4562c --- /dev/null +++ "b/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245.md" @@ -0,0 +1,67 @@ + +> 策略名称 + +价格高低点与一目均线双重趋势策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略名称:价格高低点与一目均线双重趋势策略 +- 数据周期:15M等 +- 支持:商品期货 +- 官方网站:www.quant.la + +/upload/asset/487949c7affb8521d9c041610551c3cd.png + +- 主图: + + LINE1指标线,公式:LINE1^^(HHV(H,N1)+LLV(L,N1))*0.5; + + LINE2指标线,公式:LINE2^^(HHV(H,N2)+LLV(L,N2))*0.5; + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N1|150|高点低点均值1周期| +|N2|500|高点低点均值2周期| +|SLOSS|2|止损百分比| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-07-01 00:00:00 +end: 2018-08-16 00:00:00 +period: 15m +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["N1",90],["N2",150]] +*) + +LINE1^^(HHV(H,N1)+LLV(L,N1))*0.5; +LINE2^^(HHV(H,N2)+LLV(L,N2))*0.5; + +BKVOL=0 AND BARPOS>N2 AND REF(LINE1,1)=LINE2,BPK; +SKVOL=0 AND BARPOS>N2 AND REF(LINE1,1)>REF(LINE2,1) AND LINE1<=LINE2,SPK; + +BKVOL=0 AND H>=HHV(H,N1),BK; +SKVOL=0 AND L<=LLV(L,N1),SK; + +CSKPRICE*(1+SLOSS*0.01),BP(SKVOL); +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/128415 + +> 更新时间 + +2018-12-05 16:59:14 diff --git "a/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" new file mode 100644 index 00000000..346afb96 --- /dev/null +++ "b/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -0,0 +1,73 @@ + +> 策略名称 + +传统均线指标与KD指标的交易策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略名称:传统均线指标与KD指标的交易策略 +- 数据周期:15M,30M等 +- 支持:商品期货 +- 指标使用了EMA,KD线,其中KD线使用的是默认参数(指标参数固定3,3,9) +- 官方网站:www.quant.la + +/upload/asset/f842e44b0b8451cb562b8d5bd888e4c0.png + +- 主图 + EMA均线,公式:MAC^^EMA(C,N); + + +- 副图 + + KD线中的K线,公式:K:SMA(RSV,M1,1);//RSV的移动平均值 + KD线中的D线,公式:D:SMA(K,M2,1);//K的移动平均值 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|SLOSS|2|止损百分比| +|N|120|EMA参数| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-04-01 00:00:00 +end: 2018-05-15 00:00:00 +period: 30m +exchanges: [{"eid":"Futures_BitMEX","currency":"XBT_USD"}] +args: [["TradeAmount",100,126961],["ContractType","XBTUSD",126961]] +*) + +MAC^^EMA(C,N); + +NKD:=9; +M1:=3; +M2:=3; +RSV:=(CLOSE-LLV(LOW,NKD))/(HHV(HIGH,NKD)-LLV(LOW,NKD))*100;//收盘价与NKD周期最低值做差,NKD周期最高值与NKD周期最低值做差,两差之间做比值。 +K:SMA(RSV,M1,1);//RSV的移动平均值 +D:SMA(K,M2,1);//K的移动平均值 + +BARPOS>N AND C>MAC AND KN AND CD,SK; +C<=BKPRICE*(1-SLOSS*0.01),SP(BKVOL); +C>=SKPRICE*(1+SLOSS*0.01),BP(SKVOL); +C>=BKPRICE*(1+SLOSS*0.01) AND CMAC,BP(SKVOL); +``` + +> 策略出处 + +https://www.fmz.com/strategy/128249 + +> 更新时间 + +2018-12-05 18:34:08 diff --git "a/\344\274\240\347\273\237\346\234\237\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247 (CTP).js" "b/\344\274\240\347\273\237\346\234\237\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247 (CTP).md" similarity index 85% rename from "\344\274\240\347\273\237\346\234\237\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247 (CTP).js" rename to "\344\274\240\347\273\237\346\234\237\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247 (CTP).md" index 2e5b2ff8..660e83e5 100644 --- "a/\344\274\240\347\273\237\346\234\237\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247 (CTP).js" +++ "b/\344\274\240\347\273\237\346\234\237\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247 (CTP).md" @@ -1,24 +1,35 @@ -/* -策略出处: https://www.fmz.com/strategy/5379 -策略名称: 传统期货差价监控 (CTP) -策略作者: Zero -策略描述: + +> 策略名称 + +传统期货差价监控 (CTP) + +> 策略作者 + +Zero + +> 策略描述 只支持两个交易所, 可自定义差价的类型, 支持2.77托管者的自定义图表功能 +> 策略参数 + + -参数 默认值 描述 ------------- ------ ---------------------- -AInstrument au1506 主合约 -BInstrument au1512 次合约 -AType 0 主合约价格类型: 上次成交价|买一价|卖一价 -BType 0 次合约价格类型: 上次成交价|买一价|卖一价 -Interval 2000 出错重试间隔(毫秒) -TickInterval 2000 检测频率(毫秒) -NormalDiff 0.1 普通差价 -HighDiff 0.3 较高差价 -*/ +|参数|默认值|描述| +|----|----|----| +|AInstrument|au1506|主合约| +|BInstrument|au1512|次合约| +|AType|0|主合约价格类型: 上次成交价|买一价|卖一价| +|BType|0|次合约价格类型: 上次成交价|买一价|卖一价| +|Interval|2000|出错重试间隔(毫秒)| +|TickInterval|2000|检测频率(毫秒)| +|NormalDiff|0.1|普通差价| +|HighDiff|0.3|较高差价| + +> 源码 (javascript) + +``` javascript var __lastDiff = 0; var __AType = ["Last", "Buy", "Sell"][AType]; var __BType = ["Last", "Buy", "Sell"][BType]; @@ -143,3 +154,12 @@ function main() { Sleep(TickInterval); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/5379 + +> 更新时间 + +2016-01-21 00:54:49 diff --git "a/\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" "b/\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" new file mode 100644 index 00000000..712f4095 --- /dev/null +++ "b/\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" @@ -0,0 +1,79 @@ + +> 策略名称 + +你不知道的MACD+MA指标组合策略 + +> 策略作者 + +Zero + +> 策略描述 + +本期分享MACD+MA指标组合策略,在技术分析中,指标的组合使用是非常常见的,不同的指标组合在一起具有不同的操作要点和分析方法,指标的组合使用可以增强信号的准确性。该策略正是通过比较价格与MA的相互关系,再以MACD指标衡量价格运动加速度,来判断市场所处的状态,构建一种简单的择时交易策略。 + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-11-01 00:00:00 +end: 2018-11-22 00:00:00 +period: 1h +exchanges: [{"eid":"OKCoin_EN","currency":"BTC_USD"}] +*) + +// 公式名称:MACD+MA指标组合策略 +// 数据周期:4小时 +// 适合品种:商品期货/数字货币现货/数字货币期货 + +// MACD计算参数 +FASTLENGTH:=12; +SLOWLENGTH:=26; +MACDLENGTH:=9; + +// 均线长度 +L1:=50; +L2:=120; + +// 止损5% +STOPLOSS:=5; + +//MACD +MACDVALUE:=EMA(CLOSE,FASTLENGTH)-EMA(CLOSE,SLOWLENGTH); +AVGMACD:=EMA(MACDVALUE,MACDLENGTH); +MACDDIFF:=MACDVALUE-AVGMACD; + +//MA1、MA2 +DMA1:=MA(C,L1); +DMA2:=MA(C,L2); +买入开仓价:=VALUEWHEN(BARSBK=1,O); +卖出开仓价:=VALUEWHEN(BARSSK=1,O); +BUYCONDITION:=MACDVALUE>0 && DMA1>DMA2 && MACDDIFF>0 && C>DMA1 && REF(C,1)>REF(DMA1,1); +SELLCONDITION:=MACDVALUE<0 && DMA10 AND (REF(MACDVALUE,1)<0 OR REF(DMA1,1)0 AND (REF(MACDVALUE,1)>0 OR REF(DMA1,1)>REF(DMA2,1)),BP; + +// 启动止损 +SKVOL>0 AND HIGH>=卖出开仓价*(1+STOPLOSS*0.01),BP; +SETSIGPRICETYPE(BP,MAX(O,卖出开仓价*(1+STOPLOSS*0.01))); +BKVOL>0 AND LOW<=买入开仓价*(1-STOPLOSS*0.01),SP; +SETSIGPRICETYPE(SP,MIN(O,买入开仓价*(1-STOPLOSS*0.01))); +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/127101 + +> 更新时间 + +2018-11-22 22:47:00 diff --git "a/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.js" "b/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.md" similarity index 94% rename from "\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.js" rename to "\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.md" index e420efef..62afe742 100644 --- "a/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.js" +++ "b/\344\275\277\347\224\250 BotVS \346\236\204\345\273\272\344\270\200\344\270\252\346\234\272\346\242\260\345\214\226\347\255\226\347\225\245.md" @@ -1,14 +1,22 @@ -/* -策略出处: https://www.fmz.com/strategy/40357 -策略名称: 使用 BotVS 构建一个机械化策略 -策略作者: 小小梦 -策略描述: + +> 策略名称 + +使用 BotVS 构建一个机械化策略 + +> 策略作者 + +小小梦 + +> 策略描述 知乎专栏文章 附带策略 使用 BotVS 构建一个机械化策略 -*/ + +> 源码 (javascript) + +``` javascript // 参数 var ContractType = "rb1710"; var PointAmount = 1; @@ -140,3 +148,12 @@ function main(){ Sleep(Interval); // 暂停 0.5 秒, 避免轮询频率过高,访问交易所服务器过于频繁导致问题。 } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/40357 + +> 更新时间 + +2017-09-21 09:16:02 diff --git "a/\344\275\277\347\224\250\347\224\273\347\272\277\347\261\273\345\272\223\347\224\273K\347\272\277\344\273\245\345\217\212\345\235\207\347\272\277\345\233\276\350\241\250\350\214\203\344\276\213.md" "b/\344\275\277\347\224\250\347\224\273\347\272\277\347\261\273\345\272\223\347\224\273K\347\272\277\344\273\245\345\217\212\345\235\207\347\272\277\345\233\276\350\241\250\350\214\203\344\276\213.md" new file mode 100644 index 00000000..cc94be39 --- /dev/null +++ "b/\344\275\277\347\224\250\347\224\273\347\272\277\347\261\273\345\272\223\347\224\273K\347\272\277\344\273\245\345\217\212\345\235\207\347\272\277\345\233\276\350\241\250\350\214\203\344\276\213.md" @@ -0,0 +1,67 @@ + +> 策略名称 + +使用画线类库画K线以及均线图表范例 + +> 策略作者 + +小小梦 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|MaCyc|10|均线参数| + + +> 源码 (javascript) + +``` javascript +var PreBarTime = 0 +function PlotMA_Kline(records, param, isFirst){ + var ma = TA.MA(records, param) + $.PlotRecords(records, "K") + if(isFirst){ + for(var i = records.length - 1; i >= 0; i--){ + if(ma[i] !== null){ + $.PlotLine("ma", ma[i], records[i].Time) + } + } + PreBarTime = records[records.length - 1].Time + } else { + if(PreBarTime !== records[records.length - 1].Time){ + $.PlotLine("ma", ma[ma.length - 2], records[records.length - 2].Time) + PreBarTime = records[records.length - 1].Time + } + $.PlotLine("ma", ma[ma.length - 1], records[records.length - 1].Time) + } + + +} + +function main(){ + var maCyc = MaCyc + var isFirst = true + + while(1){ + var records = exchange.GetRecords() + if(records && records.length > maCyc){ + PlotMA_Kline(records, maCyc, isFirst) + isFirst = false + } + Sleep(1000) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/125770 + +> 更新时间 + +2018-11-12 11:39:09 diff --git "a/\345\205\245\351\227\250\346\250\241\346\235\277\344\271\213\345\220\204\344\270\252\345\271\263\345\217\260\344\275\231\351\242\235.js" "b/\345\205\245\351\227\250\346\250\241\346\235\277\344\271\213\345\220\204\344\270\252\345\271\263\345\217\260\344\275\231\351\242\235.md" similarity index 75% rename from "\345\205\245\351\227\250\346\250\241\346\235\277\344\271\213\345\220\204\344\270\252\345\271\263\345\217\260\344\275\231\351\242\235.js" rename to "\345\205\245\351\227\250\346\250\241\346\235\277\344\271\213\345\220\204\344\270\252\345\271\263\345\217\260\344\275\231\351\242\235.md" index 1185b53b..2cc9cbe5 100644 --- "a/\345\205\245\351\227\250\346\250\241\346\235\277\344\271\213\345\220\204\344\270\252\345\271\263\345\217\260\344\275\231\351\242\235.js" +++ "b/\345\205\245\351\227\250\346\250\241\346\235\277\344\271\213\345\220\204\344\270\252\345\271\263\345\217\260\344\275\231\351\242\235.md" @@ -1,17 +1,28 @@ -/* -策略出处: https://www.fmz.com/strategy/48 -策略名称: 入门模板之各个平台余额 -策略作者: Zero -策略描述: + +> 策略名称 + +入门模板之各个平台余额 + +> 策略作者 + +Zero + +> 策略描述 查看各个平台的余额和货币数量 +> 策略参数 + + -参数 默认值 描述 ------------ ----- ------ -DisableRate false 禁用汇率转换 -*/ +|参数|默认值|描述| +|----|----|----| +|DisableRate|false|禁用汇率转换| + +> 源码 (javascript) + +``` javascript function main() { for (var i = 0; i < exchanges.length; i++) { if (DisableRate) { @@ -36,3 +47,12 @@ function main() { } } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/48 + +> 更新时间 + +2016-07-25 16:10:13 diff --git "a/\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.js" "b/\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.md" similarity index 92% rename from "\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.js" rename to "\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.md" index 30249525..5a0a2f69 100644 --- "a/\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.js" +++ "b/\345\205\250\347\220\20310\345\244\247\344\272\244\346\230\223\347\263\273\347\273\237\344\271\213 Aberration \345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\263\273\347\273\237.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/25943 -策略名称: 全球10大交易系统之 Aberration 多品种商品期货交易系统 -策略作者: Zero -策略描述: + +> 策略名称 + +全球10大交易系统之 Aberration 多品种商品期货交易系统 + +> 策略作者 + +Zero + +> 策略描述 全球10大交易系统之一, 是做为商品期货多品种操作策略入门的不二之选 @@ -19,27 +24,36 @@ https://dn-filebox.qbox.me/e65b74536656f064f5c55842d8376a4b29043dbc.png `是的, 免费开源给BotVS用户, 完整的策略像一个完整的人生, 每个环节都不可少` +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Symbols|MA701:5,CF701:3,rb1701|合约品种| +|NPeriod|35|计算周期| +|Ks|2|上轨系数| +|Kx|2|下轨系数| +|AmountOP|true|默认开仓合约张数| +|LoopInterval|3|轮询间隔(秒)| +|NotifyWX|true|下单微信通知| +|Reset|false|启动时重置| +|RCMode|true|启用风控模块| +|MinNetAsset|10000|最小净值| +|RCCoverAll|true|触发后平掉所有仓位| +|AutoRestore|false|自动根据仓位恢复进度| -参数 默认值 描述 ------------- ---------------------- ---------- -Symbols MA701:5,CF701:3,rb1701 合约品种 -NPeriod 35 计算周期 -Ks 2 上轨系数 -Kx 2 下轨系数 -AmountOP true 默认开仓合约张数 -LoopInterval 3 轮询间隔(秒) -NotifyWX true 下单微信通知 -Reset false 启动时重置 -RCMode true 启用风控模块 -MinNetAsset 10000 最小净值 -RCCoverAll true 触发后平掉所有仓位 -AutoRestore false 自动根据仓位恢复进度 - -按钮 默认值 描述 ------ -------------------------- ---- -Debug Log(exchange.GetAccount()) 调试 -*/ + + +|按钮|默认值|描述| +|----|----|----| +|Debug|Log(exchange.GetAccount())|调试| + + +> 源码 (javascript) + +``` javascript /*backtest start: 2016-01-15 09:00:00 end: 2017-01-01 15:00:00 @@ -371,3 +385,12 @@ function main() { LogStatus('`' + JSON.stringify([tblRuntime, tblPosition, tblMarket, initAccountTbl, nowAcccountTbl]) + '`\n价格最后更新: ' + _D() + ', 持仓最后更新: ' + _D(prePosUpdate) + '\n当前持仓总盈亏: ' + _N(holdProfit, 3) + suffix) } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/25943 + +> 更新时间 + +2017-11-11 10:47:09 diff --git "a/\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.js" "b/\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.md" similarity index 87% rename from "\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.js" rename to "\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.md" index cc74e608..95e1752a 100644 --- "a/\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.js" +++ "b/\345\206\205\345\244\226\347\233\230\346\234\237\350\264\247\345\223\201\347\247\215\345\256\236\346\227\266\345\267\256\344\273\267\345\233\276.md" @@ -1,20 +1,29 @@ -/* -策略出处: https://www.fmz.com/strategy/82929 -策略名称: 内外盘期货品种实时差价图 -策略作者: Zero -策略描述: +> 策略名称 +内外盘期货品种实时差价图 +> 策略作者 -参数 默认值 描述 --------- ------------- ------- -FSymbol NYMEX CL 1805 外盘品种 -LSymbol sc1809 内盘品种 -USDCNY 6.28 USDNCY -Interval 10 收集周期(秒) -*/ +Zero + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|FSymbol|NYMEX CL 1805|外盘品种| +|LSymbol|sc1809|内盘品种| +|USDCNY|6.28|USDNCY| +|Interval|10|收集周期(秒)| + + +> 源码 (javascript) + +``` javascript function main() { LogReset(); LogProfitReset(); @@ -109,3 +118,12 @@ function main() { Sleep(Interval * 1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/82929 + +> 更新时间 + +2018-04-02 10:40:18 diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.js" "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.md" similarity index 85% rename from "\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.js" rename to "\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.md" index 6d245a30..2ced9a48 100644 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.js" +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.md" @@ -1,28 +1,39 @@ -/* -策略出处: https://www.fmz.com/strategy/236 -策略名称: 冰山委托 - 买入 -策略作者: Zero -策略描述: + +> 策略名称 + +冰山委托 - 买入 + +> 策略作者 + +Zero + +> 策略描述 冰山委托指的是投资者在进行大额交易时,为避免对市场造成过大冲击,将大单委托自动拆为多笔委托,根据当前的最新买一/卖一价格和客户设定的价格策略自动进行小单委托,在上一笔委托被全部成交或最新价格明显偏离当前委托价时,自动重新进行委托。 例子: 如果单次均值浮动点数设置为10那么: 每一笔委托的数量为其单次委托平均值的90%~110%,委托价格为最新买1价*(1-委托深度),在上一笔委托全部成交后再进行新的一笔委托,在最新成交价格距离该笔委托超过委托深度*2时自动撤单并重新进行委托。在策略总成交量等于其总委托数量时停止委托。当市场的最新成交价格高于其最高买入价格时停止委托,在最新成交价格重新低于最高买入价后恢复委托。 +> 策略参数 + + -参数 默认值 描述 ------------- ------ ------------- -TotalBuyNet 10000 购买总金额(元) -AvgBuyOnce 100 单次购买数量均值(元) -FloatPoint 10 单次均值浮动点数(百分比) -EntrustDepth 0.1 委托深度(百分比) -MaxBuyPrice 20000 最高买入价格(元) -Interval 1000 失败重试(毫秒) -MinStock 0.0001 最小交易量 -LoopInterval true 价格轮询间隔(秒) -*/ +|参数|默认值|描述| +|----|----|----| +|TotalBuyNet|10000|购买总金额(元)| +|AvgBuyOnce|100|单次购买数量均值(元)| +|FloatPoint|10|单次均值浮动点数(百分比)| +|EntrustDepth|0.1|委托深度(百分比)| +|MaxBuyPrice|20000|最高买入价格(元)| +|Interval|1000|失败重试(毫秒)| +|MinStock|0.0001|最小交易量| +|LoopInterval|true|价格轮询间隔(秒)| +> 源码 (javascript) + +``` javascript + function CancelPendingOrders() { while (true) { @@ -105,3 +116,12 @@ function main() { Log("委托全部完成", _C(exchange.GetAccount)); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/236 + +> 更新时间 + +2018-03-27 16:21:44 diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.js" "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.md" similarity index 84% rename from "\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.js" rename to "\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.md" index 67fc9ff0..dc719993 100644 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.js" +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.md" @@ -1,28 +1,39 @@ -/* -策略出处: https://www.fmz.com/strategy/241 -策略名称: 冰山委托 - 卖出 -策略作者: Zero -策略描述: + +> 策略名称 + +冰山委托 - 卖出 + +> 策略作者 + +Zero + +> 策略描述 冰山委托指的是投资者在进行大额交易时,为避免对市场造成过大冲击,将大单委托自动拆为多笔委托,根据当前的最新买一/卖一价格和客户设定的价格策略自动进行小单委托,在上一笔委托被全部成交或最新价格明显偏离当前委托价时,自动重新进行委托。 例子: 如果单次均值浮动点数设置为10那么: 每一笔委托的数量为其单次委托平均值的90%~110%,委托价格为最新卖1价*(1+委托深度),在上一笔委托全部成交后再进行新的一笔委托,在最新成交价格距离该笔委托超过委托深度*2时自动撤单并重新进行委托。在策略总成交量等于其总委托数量时停止委托。当市场的最新成交价格低于其最低卖出价格时停止委托,在最新成交价格重新高于最低卖出价后恢复委托。 +> 策略参数 + + -参数 默认值 描述 ---------------- --------- ------------- -TotalSellStocks 10 卖出总数量(币) -AvgSellOnce 0.3 单次卖出数量均值(币) -FloatPoint 10 单次均值浮动点数(百分比) -EntrustDepth 0.1 委托深度(百分比) -MinSellPrice 3800 最低卖出价格(元) -Interval 1000 失败重试(毫秒) -MinStock 0.0001 最小交易量 -LoopInterval 300 价格轮询间隔(毫秒) -*/ +|参数|默认值|描述| +|----|----|----| +|TotalSellStocks|10|卖出总数量(币)| +|AvgSellOnce|0.3|单次卖出数量均值(币)| +|FloatPoint|10|单次均值浮动点数(百分比)| +|EntrustDepth|0.1|委托深度(百分比)| +|MinSellPrice|3800|最低卖出价格(元)| +|Interval|1000|失败重试(毫秒)| +|MinStock|0.0001|最小交易量| +|LoopInterval|300|价格轮询间隔(毫秒)| +> 源码 (javascript) + +``` javascript + function CancelPendingOrders() { while (true) { @@ -102,3 +113,12 @@ function main() { } +``` + +> 策略出处 + +https://www.fmz.com/strategy/241 + +> 更新时间 + +2018-03-27 16:23:50 diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \346\224\257\346\214\201\344\273\267\346\240\274\350\247\246\345\217\221 BitVC\346\234\237\350\264\247\344\270\223\347\224\250.js" "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \346\224\257\346\214\201\344\273\267\346\240\274\350\247\246\345\217\221 BitVC\346\234\237\350\264\247\344\270\223\347\224\250.js" deleted file mode 100644 index 72f7923e..00000000 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \346\224\257\346\214\201\344\273\267\346\240\274\350\247\246\345\217\221 BitVC\346\234\237\350\264\247\344\270\223\347\224\250.js" +++ /dev/null @@ -1,329 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/951 -策略名称: 冰山委托 - 支持价格触发 BitVC期货专用 -策略作者: Zero -策略描述: - -冰山委托指的是投资者在进行大额交易时,为避免对市场造成过大冲击,将大单委托自动拆为多笔委托,根据当前的最新买一/卖一价格和客户设定的价格策略自动进行小单委托,在上一笔委托被全部成交或最新价格明显偏离当前委托价时,自动重新进行委托。 -说明: -委托类型: 直接吃单, 盘口抢单, 盘口挂单, 盘口埋单 -支持合约: 周, 季 -支持订单: 开多, 开空, 平多, 平空 -支持杠杆: 5, 10, 20 -支持触发: 当价格涨超或者跌落指定的价格时才开始委托 -支持协作: 可以等待其它冰山策略运行完成以后继续当前策略 - -委托类型说明: - -直接吃单: 卖1或者买1的价格符合下单要求的话,直接吃单 -盘口抢单: 如果要买就与盘口买1进行抢单(加上滑动价), 要卖则减去滑动价与卖一抢单 -盘口挂单: 如果要买, 买一是多少, 就挂多少, 不加滑动价, 卖的话一样的操作,与盘口买一卖一合并 -盘口埋单: 挂一个比盘口价格向后的单子, 不占据买1卖1, 等盘口买一卖一被人吃掉后, 用户挂单浮现后也被吃掉(传统冰山) - - -参数 默认值 描述 -------------- ----- ------------------------- -ContractType 0 合约类型: 周|季 -OpType 0 操作类型: 开多|开空|平多|平空 -MLevel 0 杠杆大小: 5倍|10倍|20倍 -EnableTrigger false 使用触发条件 -TriggerType 0 触发方式: 涨超|跌落 -TriggerPrice 2000 触发价格(元) -TotalOp 300 操作总金额(元) -OpOnce 100 单次操作金额(元) -MaxPrice 2000 最高买入/最低卖出(元) -EntrustType 0 下单方式: 直接吃单|盘口抢单|盘口挂单|盘口埋单 -SlidePrice 0.1 抢单滑价(元) -Interval 1000 失败重试(毫秒) -LoopInterval 300 价格轮询间隔(毫秒) -WaitRobot false 等待其它机器人 -WaitRobotID 999 等待的机器人ID -TTL false 机器人运行周期(小时) -*/ - -var _ContractType = ["week", "quarter"][ContractType]; -var _TradeType = ["buy", "sell", "closebuy", "closesell"][OpType]; -var _MarginLevel = [5, 10, 20][MLevel]; -var _OrderType = [ORDER_TYPE_BUY, ORDER_TYPE_SELL, ORDER_TYPE_SELL, ORDER_TYPE_BUY][OpType]; -var _PositionType = [ORDER_TYPE_BUY, ORDER_TYPE_SELL, ORDER_TYPE_BUY, ORDER_TYPE_SELL][OpType]; -var _LastOrderPrice = 0; -var _InitPosition = 0; -var _PositionPrice = 0; -var _TradeCall = null; -var _LastFinished = 0; - -function _N(v, precision) { - if (typeof(precision) != 'number') { - precision = 4; - } - var d = parseFloat(v.toFixed(Math.max(10, precision+5))); - var s = d.toString().split("."); - if (s.length < 2 || s[1].length <= precision) { - return d; - } - - var b = Math.pow(10, precision); - return Math.floor(d*b)/b; -} - -function GetPosition() { - var positions; - while (!(positions = exchange.GetPosition())) { - Sleep(Interval); - } - for (var i = 0; i < positions.length; i++) { - if (positions[i].ContractType == _ContractType && positions[i].Type == _PositionType) { - _PositionPrice = positions[i].Price; - return positions[i].Amount; - } - } - return 0; -} - -function GetTicker() { - var ticker; - while (!(ticker = exchange.GetTicker())) { - Sleep(Interval); - } - return ticker; -} - -function GetAccount(maxRetry) { - var account; - var counter = 0; - while (!(account = exchange.GetAccount())) { - Sleep(Interval); - counter++; - if (typeof(maxRetry) == 'number' && counter > maxRetry) { - break; - } - } - return account; -} - -function GetOrders() { - var myorders = []; - var orders = null; - while (!(orders = exchange.GetOrders())) { - Sleep(Interval); - } - for (var i = 0; i < orders.length; i++) { - if (orders[i].Type == _OrderType) { - myorders.push(orders[i]); - } - } - return myorders; -} - -function CancelPendingOrders() { - var counter = 0; - while (true) { - var orders = GetOrders(); - if (orders.length == 0) { - return; - } - - for (var i = 0; i < orders.length; i++) { - exchange.CancelOrder(orders[i].Id); - if (i < (orders.length-1)) { - Sleep(Interval); - } - } - counter++; - if (counter > 100) { - throw "挂单取消失败次数过多, 请检测账户是否有人工委托单"; - } - } -} - -function dispatch() { - var EntrustDepth = 0; - if (EntrustType == 3) { - EntrustDepth = 0.1; - } - var ticker = GetTicker(); - if ((_OrderType == ORDER_TYPE_BUY ? (MaxPrice - ticker.Sell) : (ticker.Buy - MaxPrice)) > 300) { - Log(ticker); - throw "委托价格与市价场脱离过多"; - } - var position = GetPosition(); - var finished = _N((_TradeType == "buy" || _TradeType == "sell") ? (position - _InitPosition) : (_InitPosition - position)); - // 在最新成交价格距离该笔委托超过委托深度*2时自动撤单并重新进行委托 - if (_LastOrderPrice > 0) { - // 订单没有完成 - if (GetOrders().length > 0) { - var ratio = 2*(EntrustDepth/100); - var needCancel = false; - if (EntrustType > 1) { - if (((_OrderType == ORDER_TYPE_BUY) && (ticker.Buy > _LastOrderPrice && ((ticker.Buy - _LastOrderPrice) / _LastOrderPrice) > ratio)) || - ((_OrderType == ORDER_TYPE_SELL) && (ticker.Sell < _LastOrderPrice && ((_LastOrderPrice - ticker.Sell) / _LastOrderPrice) > ratio)) ) { - Log('偏离过多, 最新盘口报价:', _OrderType == ORDER_TYPE_BUY ? ticker.Buy : ticker.Sell, '当前委托价', _LastOrderPrice); - needCancel = true; - } - } else { - if (EntrustType == 0) { - needCancel = true; - } else { - var price = _N(_OrderType == ORDER_TYPE_BUY ? ticker.Buy + SlidePrice : ticker.Sell - SlidePrice); - if (price != _LastOrderPrice) { - needCancel = true; - } - } - } - if (needCancel) { - CancelPendingOrders(); - } else { - return true; - } - } else { - if (finished != _LastFinished) { - _LastFinished = finished; - Log("委托完成, 累计花费:", finished, "持仓均价:", _PositionPrice); - } - if (finished >= TotalOp) { - return false; - } - } - _LastOrderPrice = 0; - } - - - var orderPrice = 0; - if (EntrustType == 0) { - orderPrice = _N(_OrderType == ORDER_TYPE_BUY ? ticker.Sell : ticker.Buy); - } else if (EntrustType == 1) { - orderPrice = _N(_OrderType == ORDER_TYPE_BUY ? ticker.Buy + SlidePrice : ticker.Sell - SlidePrice); - } else { - // 委托价格为最新买1价*(1-委托深度)或者 卖1价*(1+委托深度) - orderPrice = _N(_OrderType == ORDER_TYPE_BUY ? (ticker.Buy * (1 - EntrustDepth/100)) : (ticker.Sell * (1 + EntrustDepth/100))); - } - if ((_OrderType == ORDER_TYPE_BUY && orderPrice > MaxPrice) || (_OrderType == ORDER_TYPE_SELL && orderPrice < MaxPrice)) { - return true; - } - var once = Math.min(OpOnce, TotalOp - finished); - if (_TradeType == "closebuy" || _TradeType == "closesell") { - once = Math.min(position, once); - } - once = parseInt(once); - - var i = 0; - var maxRetry = 20; - for (i = 0; i < maxRetry; i++) { - var orderId = _TradeCall(orderPrice, once, 'Buy:', ticker.Buy, 'Sell:', ticker.Sell); - if (typeof(orderId) == 'number') { - break; - } else { - Sleep(Interval); - } - } - if (i == maxRetry) { - throw "下单失败次数过多.."; - } - - _LastOrderPrice = orderPrice; - return true; -} - -function onexit() { - _G("bitvc", null); - CancelPendingOrders(); - Log("退出成功"); -} - -function main() { - if (parseFloat(Version()) < 2.63) { - throw "要求托管者2.63版本以上"; - } - - if (exchange.GetName() != 'Futures_BitVC') { - throw "该策略为BitVC期货专用策略"; - } - - if (_MarginLevel == 20 && exchange.GetCurrency() == "LTC") { - throw "LTC不支持20倍杠杆"; - } - - if (TotalOp % 100 != 0) { - throw "操作总金额必须是100的倍数"; - } - - if (OpOnce % 100 != 0) { - throw "单次操作金额必须是100的倍数"; - } - - if (!GetAccount(10)) { - throw "获取账户信息失败, 请检测API配置是否正确"; - } - - SetErrorFilter("502:|503:|network|timeout|WSARecv|Connect|GetAddr|no such|reset"); - - if (_G("bitvc")) { - //throw "该策略不允许并发运行, 必须等待其它同策略机器人完成"; - } - - Log('当前机器人ID: ', _G(), '开始运行...'); - if (WaitRobot) { - if (!_G(WaitRobotID)) { - throw "没有发现ID为" + WaitRobotID + "的机器人运行"; - } - Log('等待ID为', WaitRobotID, '的机器人退出'); - while (_G(WaitRobotID)) { - Sleep(500); - } - Log('等待完成, 继续当前策略'); - } - _G("bitvc", true); - - exchange.SetMarginLevel(_MarginLevel); - - _TradeCall = _OrderType == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell; - - LoopInterval = Math.max(LoopInterval, 100); - - if (EnableTrigger) { - var ticker = GetTicker(); - Log('当前价格:', ticker.Last, '等待价格', TriggerType == 0 ? '涨超' : '跌破', TriggerPrice, '元...'); - while (true) { - if (TriggerType == 1 && ticker.Last < TriggerPrice) { - Log('价格跌破 ', TriggerPrice, '元, 开始按计划委托'); - break; - } else if (TriggerType == 0 && ticker.Last > TriggerPrice) { - Log('价格涨超 ', TriggerPrice, '元, 开始按计划委托'); - break; - } - ticker = GetTicker(); - Sleep(LoopInterval); - } - } - - CancelPendingOrders(); - _InitPosition = GetPosition(); - if ((_TradeType == "closebuy" || _TradeType == "closesell")) { - if (_InitPosition == 0) { - throw "没有找到仓位"; - } - TotalOp = Math.min(TotalOp, _InitPosition); - } - Log('初始仓位数量: ', _InitPosition); - if (TTL > 0) { - Log("机器人将在 ", TTL, "小时后退出."); - } - exchange.SetContractType(_ContractType); - exchange.SetDirection(_TradeType); - var st = new Date().getTime(); - var finished = true; - while (dispatch()) { - Sleep(LoopInterval); - if (TTL > 0) { - if ((new Date().getTime() - st) >= (TTL * 60 * 60 * 1000)) { - Log("到达指定退出时间, 现在退出"); - finished = false; - break; - } - } - } - if (finished) { - Log("委托全部完成"); - } - Log("当前持仓: ", GetPosition()); -} diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230\344\271\260\345\205\245\347\256\200\345\215\225\347\211\210|Simple Iceberg order to buy.md" "b/\345\206\260\345\261\261\345\247\224\346\211\230\344\271\260\345\205\245\347\256\200\345\215\225\347\211\210|Simple Iceberg order to buy.md" new file mode 100644 index 00000000..4d14e7b9 --- /dev/null +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230\344\271\260\345\205\245\347\256\200\345\215\225\347\211\210|Simple Iceberg order to buy.md" @@ -0,0 +1,57 @@ + +> 策略名称 + +冰山委托买入简单版|Simple Iceberg order to buy + +> 策略作者 + +botvsing + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|BUYAMOUNT|2|amount to buy| +|BUYSIZE|0.1|iceberg order size| +|INTERVAL|3|orders exist time(second)| + + +> 源码 (javascript) + +``` javascript +function main(){ + var initAccount = _C(exchange.GetAccount) + while(true){ + var account = _C(exchange.GetAccount) + var dealAmount = account.Stocks - initAccount.Stocks + var ticker = _C(exchange.GetTicker) + if(BUYAMOUNT - dealAmount > BUYSIZE){ + var id = exchange.Buy(ticker.Sell, BUYSIZE) + Sleep(INTERVAL*1000) + if(id){ + exchange.CancelOrder(id) // May cause error log when the order is completed, which is all right. + }else{ + throw 'buy error' + } + }else{ + account = _C(exchange.GetAccount) + var avgCost = (initAccount.Balance - account.Balance)/(account.Stocks - initAccount.Stocks) + Log('Iceberg order to buy is done, avg cost is ', avgCost) // including fee cost + return + } + + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/121522 + +> 更新时间 + +2018-10-16 10:57:07 diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230\345\215\226\345\207\272\347\256\200\345\215\225\347\211\210|Simple Iceberg order to sell.md" "b/\345\206\260\345\261\261\345\247\224\346\211\230\345\215\226\345\207\272\347\256\200\345\215\225\347\211\210|Simple Iceberg order to sell.md" new file mode 100644 index 00000000..72154fe7 --- /dev/null +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230\345\215\226\345\207\272\347\256\200\345\215\225\347\211\210|Simple Iceberg order to sell.md" @@ -0,0 +1,62 @@ + +> 策略名称 + +冰山委托卖出简单版|Simple Iceberg order to sell + +> 策略作者 + +botvsing + +> 策略描述 + +Very simple, just for learn. +Code is best annotation. + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|SELLAMOUNT|2|amount to sell| +|SELLSIZE|0.1|sell orders size| +|INTERVAL|3|order exist time(second)| + + +> 源码 (javascript) + +``` javascript +function main(){ + var initAccount = _C(exchange.GetAccount) + if (initAccount.Stocks < SELLAMOUNT){ + throw 'check your account amount to sell' + } + while(true){ + var account = _C(exchange.GetAccount) + var dealAmount = initAccount.Stocks - account.Stocks + var ticker = _C(exchange.GetTicker) + if(SELLAMOUNT - dealAmount > SELLSIZE){ + var id = exchange.Sell(ticker.Buy, SELLSIZE) + Sleep(INTERVAL*1000) + if(id){ + exchange.CancelOrder(id) // May cause error log when the order is completed, which is all right. + }else{ + throw 'sell error' + } + }else{ + account = _C(exchange.GetAccount) + var avgCost = (account.Balance - initAccount.Balance)/(initAccount.Stocks - account.Stocks) + Log('Iceberg order to sell is done, avg price is ', avgCost) // including fee cost + return + } + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/121524 + +> 更新时间 + +2018-10-16 10:57:32 diff --git "a/\345\207\275\346\225\260\350\207\252\345\212\250\345\256\271\351\224\231\346\250\241\346\235\277.js" "b/\345\207\275\346\225\260\350\207\252\345\212\250\345\256\271\351\224\231\346\250\241\346\235\277.md" similarity index 60% rename from "\345\207\275\346\225\260\350\207\252\345\212\250\345\256\271\351\224\231\346\250\241\346\235\277.js" rename to "\345\207\275\346\225\260\350\207\252\345\212\250\345\256\271\351\224\231\346\250\241\346\235\277.md" index ac3ff426..0b3d4f3e 100644 --- "a/\345\207\275\346\225\260\350\207\252\345\212\250\345\256\271\351\224\231\346\250\241\346\235\277.js" +++ "b/\345\207\275\346\225\260\350\207\252\345\212\250\345\256\271\351\224\231\346\250\241\346\235\277.md" @@ -1,20 +1,31 @@ -/* -策略出处: https://www.fmz.com/strategy/11609 -策略名称: 函数自动容错模板 -策略作者: Zero -策略描述: + +> 策略名称 + +函数自动容错模板 + +> 策略作者 + +Zero + +> 策略描述 打勾调用此模板后会自动对指定的Api函数进行重试容错, 支持多交易所 +> 策略参数 + + -参数 默认值 描述 ------------------ ---------------------------------------------------------------------------- ---------- -RetryInterval 500 容错重试间隔(毫秒) -Debug true 显示重试记录 -EnableErrorFilter false 屏蔽常见网络错误信息 -ApiList GetAccount,GetDepth,GetTicker,GetRecords,GetTrades,GetOrders,SetContractType 容错API列表 -*/ +|参数|默认值|描述| +|----|----|----| +|RetryInterval|500|容错重试间隔(毫秒)| +|Debug|true|显示重试记录| +|EnableErrorFilter|false|屏蔽常见网络错误信息| +|ApiList|GetAccount,GetDepth,GetTicker,GetRecords,GetTrades,GetOrders,SetContractType|容错API列表| + +> 源码 (javascript) + +``` javascript // 模板初始化时调用 function init() { // 过滤常见错误 @@ -49,3 +60,12 @@ function main() { // 此时GetTicker就不需要重试了 Log(exchange.GetTicker()); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/11609 + +> 更新时间 + +2016-04-03 17:17:41 diff --git "a/\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.py" "b/\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.md" similarity index 80% rename from "\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.py" rename to "\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.md" index 7f57d119..a6f9592d 100644 --- "a/\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.py" +++ "b/\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.md" @@ -1,13 +1,19 @@ -''' -策略出处: https://www.fmz.com/strategy/89969 -策略名称: 判断MA线的排列 - btcdw -策略作者: 比特币大王www.btcdw.com -策略描述: +> 策略名称 +判断MA线的排列 - btcdw -''' +> 策略作者 +比特币大王www.btcdw.com + + + + + +> 源码 (python) + +``` python def main(): # records = exchange.GetRecords(PERIOD_M3) #获取3分钟K线数据 ma_5 = TA.MA(records, 5) #返回一个5分钟移动平均线数组 @@ -22,3 +28,12 @@ def main(): # Sleep(1000) Log("0") +``` + +> 策略出处 + +https://www.fmz.com/strategy/89969 + +> 更新时间 + +2018-05-04 01:33:33 diff --git "a/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" "b/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" new file mode 100644 index 00000000..c9b1f184 --- /dev/null +++ "b/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" @@ -0,0 +1,79 @@ + +> 策略名称 + +动向指数(DMI)与高低点策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略名称:动向指数(DMI)与高低点策略 +- 数据周期:5M +- 支持:商品期货 +- 官方网站:www.quant.la + + + +/upload/asset/739ea1e668541f362205d9b5acb43372.png + +- 主图: + AMA1指标,公式:AMA1^^EMA(DMA(CLOSE,CQ1),2); + + AMA2指标,公式:AMA2^^EMA(DMA(CLOSE,CQ2),2); + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N|20|AMA1指标参数(1)| +|N1|4|AMA1指标参数(2)| +|N2|60|AMA1指标参数(3)| +|M|40|AMA2指标参数(1)| +|M1|8|AMA2指标参数(2)| +|M2|120|AMA2指标参数(3)| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-11-04 00:00:00 +end: 2018-11-30 00:00:00 +period: 5m +exchanges: [{"eid":"Futures_BitMEX","currency":"XBT_USD"}] +args: [["TradeAmount",100,126961],["ContractType","XBTUSD",126961]] +*) + + +DIR1:=ABS(CLOSE-REF(CLOSE,N)); +VIR1:=SUM(ABS(CLOSE-REF(CLOSE,1)),N); +ER1:=DIR1/VIR1; +CS1:=ER1*(2/(N1+1)-2/(N2+1))+2/(N2+1); +CQ1:=CS1*CS1; +AMA1^^EMA(DMA(CLOSE,CQ1),2); + +DIR2:=ABS(CLOSE-REF(CLOSE,M)); +VIR2:=SUM(ABS(CLOSE-REF(CLOSE,1)),M); +ER2:=DIR2/VIR2; +CS2:=ER2*(2/(M1+1)-2/(M2+1))+2/(M2+1); +CQ2:=CS2*CS2; +AMA2^^EMA(DMA(CLOSE,CQ2),2); + +cq22:CQ2; +aa:DMA(CLOSE,CQ2); + +BKVOL=0 AND REF(AMA1,1)REF(AMA2,1) AND AMA2>AMA1,SPK; +``` + +> 策略出处 + +https://www.fmz.com/strategy/128418 + +> 更新时间 + +2018-12-05 12:38:58 diff --git "a/\345\212\250\346\200\201\345\271\263\350\241\241 \345\201\232\345\270\202\347\255\226\347\225\245 (\345\260\217\351\253\230).md" "b/\345\212\250\346\200\201\345\271\263\350\241\241 \345\201\232\345\270\202\347\255\226\347\225\245 (\345\260\217\351\253\230).md" new file mode 100644 index 00000000..f5a6514e --- /dev/null +++ "b/\345\212\250\346\200\201\345\271\263\350\241\241 \345\201\232\345\270\202\347\255\226\347\225\245 (\345\260\217\351\253\230).md" @@ -0,0 +1,160 @@ + +> 策略名称 + +动态平衡 做市策略 (小高) + +> 策略作者 + +gaotiansong + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|DELAY|5|平衡间隔| +|PRICE_INCREMENT|1e-06|最小价格变化| +|AMOUNT_INCREMENT|0.01|最小数量变化| +|AMOUNT_MINIMUM|0.01|最低交易数量| +|SPREAD|0.3|挂单价格间隔| + + +> 源码 (javascript) + +``` javascript +var Coin = '' +var Fiat = '' +var RefreshLoop = 0 +var Account = '' +var Depth = '' +var Orders = '' +var BuyWeighted = 0 +var SellWeighted = 0 +var MidPrice = 0 +var InitialBalance = exchange.GetAccount().Balance + exchange.GetAccount().Stocks * exchange.GetDepth().Bids[0].Price + +function CancelPendingOrders() { + for (var j = 0; j < Orders.length; j++) { + exchange.CancelOrder(Orders[j].Id, Orders[j])} +} + +function UpdateAll() { + Account = exchange.GetAccount() + Depth = exchange.GetDepth() + Orders = exchange.GetOrders() + //Log("UpdateAll") +} + +function UpdatePrice() { + //MidPrice = (Depth.Asks[0].Price+Depth.Bids[0].Price)/2 + BuyWeighted = Depth.Asks[0].Price * (1+SPREAD/100) + SellWeighted = Depth.Bids[0].Price * (1-SPREAD/100) + //Log("UpdatePrice") +} + +function onTick(){ + // 刷新账户余额及行情数据 + //Log("UpdateAll") + UpdateAll() + var Buy = Depth.Asks[0].Price + var Sell = Depth.Bids[0].Price + + // 计算加权价格 + //Log("UpdatePrice") + UpdatePrice() + + // 检查当前存在订单 + if (Orders.length==2){ + return + } + if (Orders.length>2){ + CancelPendingOrders() + UpdateAll() + } + // 处理单一订单 + if (Orders.length==1){ + Order = Orders[0] + Price=Order.Price + if (Order.Type==0){ + if (Price/(1-SPREAD/100) > Sell){ + return + }else{ + CancelPendingOrders() + UpdateAll() + } + }else{ + if (Price/(1+SPREAD/100) < Buy){ + return + }else{ + CancelPendingOrders() + UpdateAll() + } + } + } + + // 计算所持仓位价值 + var ValueByBuy = Account.Stocks * BuyWeighted + var ValueBySell = Account.Stocks * SellWeighted + Log(Coin + " Value By Weighted Ask - " + Fiat +" Balance : " + (ValueByBuy-Account.Balance)) + Log(Fiat + " Balance - " + Coin +" Value By Weighted Bid : " +(Account.Balance-ValueBySell)) + //Log(ValueByBuy) + //Log(ValueBySell) + + // 所持币价值高于定价货币 卖出所持的币 + if (ValueByBuy > Account.Balance){ + ToBeSold = (ValueByBuy - Account.Balance)/2/BuyWeighted + if (ToBeSold > AMOUNT_MINIMUM){ + ToBeSold = _N(Math.ceil(ToBeSold / AMOUNT_INCREMENT) * AMOUNT_INCREMENT) + Log("将要售出的 " + Coin + " 数量:" + ToBeSold) + exchange.Sell(BuyWeighted,ToBeSold) + } + } + // 所持定价货币价值高于所持币 买入币 + if (ValueBySell < Account.Balance){ + ToBeBought = (Account.Balance - ValueBySell)/2/SellWeighted + if (ToBeBought > AMOUNT_MINIMUM){ + ToBeBought = _N(Math.ceil(ToBeBought / AMOUNT_INCREMENT) * AMOUNT_INCREMENT) + Log("将要购买的 " + Coin + " 数量:" + ToBeBought) + exchange.Buy(SellWeighted,ToBeBought) + } + } + Log(Fiat + " 数量:" + Account.Balance) + Log(Coin + " 数量:" + Account.Stocks) + + RefreshLoop = RefreshLoop+1 + if (RefreshLoop>60) { + var Profit = _N(Account.Stocks*Sell) + _N(Account.Balance) - _N(InitialBalance) + LogProfit(Profit) + RefreshLoop = 0 + } +} +function main(){ + var Pair = exchange.GetCurrency() + LogReset() + LogProfitReset() + LogProfit(0) + UpdateAll() + CancelPendingOrders() + Coin = Pair.split("_")[0] + Fiat = Pair.split("_")[1] + while (true){ + try { + onTick() + } catch (err) { + Log(err) + } + Sleep(DELAY*1000) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/114044 + +> 更新时间 + +2018-08-29 17:28:23 diff --git "a/\345\212\250\346\200\201\345\271\263\350\241\241 \345\201\232\345\270\202\347\255\226\347\225\245.md" "b/\345\212\250\346\200\201\345\271\263\350\241\241 \345\201\232\345\270\202\347\255\226\347\225\245.md" new file mode 100644 index 00000000..72c43476 --- /dev/null +++ "b/\345\212\250\346\200\201\345\271\263\350\241\241 \345\201\232\345\270\202\347\255\226\347\225\245.md" @@ -0,0 +1,171 @@ + +> 策略名称 + +动态平衡 做市策略 + +> 策略作者 + +FawkesPan + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|DELAY|5|平衡间隔| +|PRICE_INCREMENT|1e-06|最小价格变化| +|AMOUNT_INCREMENT|0.01|最小数量变化| +|AMOUNT_MINIMUM|0.01|最低交易数量| +|SPREAD|0.3|挂单价格间隔| + + +> 源码 (javascript) + +``` javascript +/* + +Rebalance With MarketMake + +Copyright 2018 FawkesPan +Contact : i@fawkex.me / Telegram@FawkesPan + +GNU General Public License v3.0 + +*/ + +var Coin = '' +var Fiat = '' +var RefreshLoop = 0 +var Account = '' +var Depth = '' +var Orders = '' +var BuyWeighted = 0 +var SellWeighted = 0 +var MidPrice = 0 +var InitialBalance = exchange.GetAccount().Balance + exchange.GetAccount().Stocks * exchange.GetDepth().Bids[0].Price + +function CancelPendingOrders() { + for (var j = 0; j < Orders.length; j++) { + exchange.CancelOrder(Orders[j].Id, Orders[j])} +} + +function UpdateAll() { + Account = exchange.GetAccount() + Depth = exchange.GetDepth() + Orders = exchange.GetOrders() + //Log("UpdateAll") +} + +function UpdatePrice() { + //MidPrice = (Depth.Asks[0].Price+Depth.Bids[0].Price)/2 + BuyWeighted = Depth.Asks[0].Price * (1+SPREAD/100) + SellWeighted = Depth.Bids[0].Price * (1-SPREAD/100) + //Log("UpdatePrice") +} + +function onTick(){ + // 刷新账户余额及行情数据 + //Log("UpdateAll") + UpdateAll() + var Buy = Depth.Asks[0].Price + var Sell = Depth.Bids[0].Price + + // 计算加权价格 + //Log("UpdatePrice") + UpdatePrice() + + // 检查当前存在订单 + if (Orders.length==2){ + return + } + if (Orders.length>2){ + CancelPendingOrders() + UpdateAll() + } + // 处理单一订单 + if (Orders.length==1){ + Order = Orders[0] + Price=Order.Price + if (Order.Type==0){ + if (Price/(1-SPREAD/100) > Sell){ + return + }else{ + CancelPendingOrders() + UpdateAll() + } + }else{ + if (Price/(1+SPREAD/100) < Buy){ + return + }else{ + CancelPendingOrders() + UpdateAll() + } + } + } + + // 计算所持仓位价值 + var ValueByBuy = Account.Stocks * BuyWeighted + var ValueBySell = Account.Stocks * SellWeighted + Log(Coin + " Value By Weighted Ask - " + Fiat +" Balance : " + (ValueByBuy-Account.Balance)) + Log(Fiat + " Balance - " + Coin +" Value By Weighted Bid : " +(Account.Balance-ValueBySell)) + //Log(ValueByBuy) + //Log(ValueBySell) + + // 所持币价值高于定价货币 卖出所持的币 + if (ValueByBuy > Account.Balance){ + ToBeSold = (ValueByBuy - Account.Balance)/2/BuyWeighted + if (ToBeSold > AMOUNT_MINIMUM){ + ToBeSold = _N(Math.ceil(ToBeSold / AMOUNT_INCREMENT) * AMOUNT_INCREMENT) + Log("将要售出的 " + Coin + " 数量:" + ToBeSold) + exchange.Sell(BuyWeighted,ToBeSold) + } + } + // 所持定价货币价值高于所持币 买入币 + if (ValueBySell < Account.Balance){ + ToBeBought = (Account.Balance - ValueBySell)/2/SellWeighted + if (ToBeBought > AMOUNT_MINIMUM){ + ToBeBought = _N(Math.ceil(ToBeBought / AMOUNT_INCREMENT) * AMOUNT_INCREMENT) + Log("将要购买的 " + Coin + " 数量:" + ToBeBought) + exchange.Buy(SellWeighted,ToBeBought) + } + } + Log(Fiat + " 数量:" + Account.Balance) + Log(Coin + " 数量:" + Account.Stocks) + + RefreshLoop = RefreshLoop+1 + if (RefreshLoop>60) { + var Profit = _N(Account.Stocks*Sell) + _N(Account.Balance) - _N(InitialBalance) + LogProfit(Profit) + RefreshLoop = 0 + } +} +function main(){ + var Pair = exchange.GetCurrency() + LogReset() + LogProfitReset() + LogProfit(0) + UpdateAll() + CancelPendingOrders() + Coin = Pair.split("_")[0] + Fiat = Pair.split("_")[1] + while (true){ + try { + onTick() + } catch (err) { + Log(err) + } + Sleep(DELAY*1000) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/113618 + +> 更新时间 + +2018-09-18 21:02:19 diff --git "a/\345\212\250\346\200\201\345\271\263\350\241\241alpha.md" "b/\345\212\250\346\200\201\345\271\263\350\241\241alpha.md" new file mode 100644 index 00000000..c00eae6e --- /dev/null +++ "b/\345\212\250\346\200\201\345\271\263\350\241\241alpha.md" @@ -0,0 +1,105 @@ + +> 策略名称 + +动态平衡alpha + +> 策略作者 + +中本大料 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|threshold|0.05|阈值| +|LoopInterval|60|循环时间| +|Minstock|0.001|最小交易量| +|XPrecision|4|量精度| +|YPrecision|8|价精度| + + +> 源码 (javascript) + +``` javascript +var threshold = 0.05 +var LoopInterval = 60 +var Minstock = 0.001 +var XPrecision = 4 +var ZPrecision = 8 + +//撤单函数 +function CancelPendingOrders() { + Sleep(1000); + var ret = false; + while (true) { + var orders = null; + while (!(orders = exchange.GetOrders())) { + Sleep(1000); + } + if(orders.length == 0){ + return ret; + } + for (var j = 0; j< orders.length; j++){ + exchange.CancelOrder(orders[j].Id); + ret = true; + if(j<(orders.length-1)){ + Sleep(1000); + } + } + } +} + +//下单函数 +function onTick() { + var acc = _C(exchange.GetAccount); //获取账户信息 + var ticker = _C(exchange.GetTicker); //获取Ticker数据 + var spread = ticker.Sell - ticker.Buy; //获取Ticker数据的买卖价差 + var diffAsset = (acc.Balance - (acc.Stocks * ticker.Sell)) / 2;//账户余额与当前持仓价值的差值的0.5倍 + var ratio = diffAsset / acc.Balance; + LogStatus('ratio:'.ratio, _D()); //打印ratio和当前时间 + if (Math.abs(ratio) < threshold) { //如果ratio的绝对值小于指定阈值 + print("spread") + return false; //返回false + } + if (ratio > 0) { //如果ratio大于0; + var buyPrice = _N(ticker.Sell + spread, ZPrecision); + var buyAmount = _N(diffAsset / buyPrice, XPrecision); + if (buyAmount < Minstock) { //如果下单量小于最小交易量 + return false; + } + exchange.Buy(buyPrice, buyAmount, diffAsset, ratio);//买入下单 + }else{ + var sellPrice = _N(ticker.Buy - spread, ZPrecision);//计算下单价格 + var sellAmount = _N(-diffAsset / sellPrice, XPrecision);//计算下单量 + if(sellAmount < Minstock){ + return false; + } + exchange.Sell(sellPrice, sellAmount, diffAsset, ratio); //卖出下单 + } + return true; +} + +//主函数 +function main() { + //SetErrorFilter("GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout"); //过滤非重要信息 + while (true) { + if (onTick()) { + CancelPendingOrders(); + Log(_C(exchange.GetAccount)); + } + Sleep(LoopInterval * 1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/115321 + +> 更新时间 + +2018-09-06 09:50:43 diff --git "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" new file mode 100644 index 00000000..92531a78 --- /dev/null +++ "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" @@ -0,0 +1,431 @@ + +> 策略名称 + +区块链量化投资系列课程(3) - 跨期套利 + +> 策略作者 + +Hukybo + +> 策略描述 + +阅读原文:[区块链量化投资系列课程(3) - 跨期套利](https://quant.la/Article/View/816/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%283%29---%E8%B7%A8%E6%9C%9F%E5%A5%97%E5%88%A9.html) +### NO.1 +索罗斯在1987年撰写的《金融炼金术》 一书中,曾经提出过一个重要的命题:I believe the market prices are always wrong in the sense that they present a biased view of the future. +[]( https://dn-filebox.qbox.me/ff79e72d5042d66611bb87f552cb8413238bee41.jpg ) +市场有效假说只是理论上的假设,实际上市场参与者并不总是理性的,并且在每一个时间点上,参与者不可能完全获取和客观解读所有的信息,再者就算是同样的信息,每个人的反馈都不尽相同。 + +也就是说,价格本身就已经包含了市场参与者的错误预期,所以本质上市场价格总错误的。这或许是套利者的利润来源。 + + + +### NO.2 +根据上述原理,我们也就知道,在一个非有效的期货市场中,不同时期交割合约之间受到市场影响也并不总是同步,其定价也并非完全有效的原因。 + +那么,根据同一种交易标的的不同时期交割合约价格为基础,如果两个价格出现了较大的价差幅度,就可以同时买卖不同时期的期货合约,进行跨期套利。 +[]( https://dn-filebox.qbox.me/8b2eeef30c771f29c2463b8e2bafeb2e68fc6113.jpg ) +与商品期货一样,数字货币也有与之相关的跨期套利合约组合。如在 OkEX 交易所中就有:ETC 当周、ETC 次周、ETC 季度。 + +举个例子,假设 ETC 当周和 ETC 季度的价差长期维持在 5 左右。如果某一天价差达到 7,我们预计价差会在未来某段时间回归到 5。那么就可以卖出 ETC 当周,同时买入 ETC 季度,来做空这个价差。反之亦然。 + + + +### NO.3 +尽管这种价差是存在的,但是人工操作耗时、准确性差以及价格变化的影响,人工套利往往存在诸多不确定性。 + +通过量化模型捕捉套利机会并制定套利交易策略,以及程序化算法自动向交易所下达交易订单,快速准确捕捉机会,高效稳定赚取收益,这就是量化套利的魅力所在。 +[]( https://dn-filebox.qbox.me/5f2018b8b1842582feb548f9479e2d2e529ad5c0.jpg ) +本篇将会教大家如何在数字货币交易中,利用发明者量化交易平台和 OkEX 交易所中 ETC 期货合约,以一个简单的套利策略,来演示如果捕捉瞬时的套利机会,把握住每一次可以看得到的利润,同时对冲有可能遇到的风险。 + + + +### NO.4 +创建一个数字货币跨期套利策略 +难易度:普通级 + [](https://dn-filebox.qbox.me/32464ad1bda6480421765081ba72c0422ce82016.jpg ) + + 策略环境: +- 交易标的:以太经典(ETC) +- 价差数据:ETC 当周 - ETC 季度(省略协整性检验) +- 交易周期:5 分钟 +- 头寸匹配:1:1 +- 交易类型:同品种跨期 + +策略逻辑: +- 做多价差开仓条件:如果当前账户没有持仓,并且价差小于 boll 下轨,就做多价差。即:买开 ETC 当周,卖开 ETC 季度。 +- 做空价差开仓条件:如果当前账户没有持仓,并且价差大于 boll 上轨,就做空价差。即:卖开 ETC 当周,买开 ETC 季度。 +- 做多价差平仓条件:如果当前账户持有 ETC 当周多单,并且持有 ETC 季度空单,并且价差大于 boll 中轨,就平多价差。即:卖平 ETC 当周,买平 ETC 季度。 +- 做空价差平仓条件:如果当前账户持有 ETC 当周空单,并且持有 ETC 季度多单,并且价差小于 boll 中轨,就平空价差。即:买平 ETC 当周,卖平 ETC 季度。 + + + +### NO.5 +上面是一个简单的数字货币跨期套利策略逻辑描述,那么如何在程序中实现自己的想法呢?我们试着在发明者量化交易平台先把框架搭建起来。 +**策略框架:** + [发明者量化(www.fmz.com)](https://dn-filebox.qbox.me/6611dc32473011546052197ef9633a633cddea98.jpg ) + 对照着策略思路以及交易流程,可以很轻松把策略框架搭建起来。整个策略可以简化为三个步骤: + 1.交易前预处理。 +2.获取并计算数据。 +3.下单并对后续处理。 + + + +### NO.6 +接下来,我们就需要根据实际交易流程和交易细节,在策略框架里面填充必要的细节代码。 +##### 一、交易前预处理 +第1步:在全局环境中,声明必要的全局变量。 + +- 声明一个配置图表的 chart 对象 +var chart = { } +- 调用 Chart 函数,初始化图表 +var ObjChart = Chart ( chart ) +- 声明一个空数组,用来存储价差序列 +var bars = [ ] +- 声明一个记录历史数据时间戳变量 +var oldTime = 0 + +第2步:配置策略的外部参数。 +[发明者量化(www.fmz.com)]( https://dn-filebox.qbox.me/9feef4532dda92b1e37686dbed489e632d918901.jpg ) + +第3步:定义数据处理函数 +**基础数据函数**:Data ( ) +创建一个构造函数 Data,并定义它的内部属性。包括:账户数据、持仓数据、K线数据时间戳、套利A/B合约的买/卖一价、正/反套价差。 +[发明者量化(www.fmz.com)]( https://dn-filebox.qbox.me/25258da6f6aa0469ba5b0ffddc813c578e7bfc7b.jpg ) +**获取持仓函数**:mp ( ) +遍历整个持仓数组,返回指定合约、指定方向的持仓数量,如果没有就返回 false +[]( https://dn-filebox.qbox.me/e366fea7a0552d80123f0f3eba614071f2dba348.jpg ) +**K线和指标函数**:boll ( ) +根据正/反套价差数据,合成新的K线序列。并返回由boll指标计算的上轨、中轨、下轨数据。 +[]( https://dn-filebox.qbox.me/3aea8fcbd0e4e4e0dfdff28b0cb13aec79b3547e.jpg ) +**下单函数**:trade ( ) +传入下单合约名称和下单类型,然后以对价下单,并返回下单后的结果。由于需要同时下两个不同方向的单子,所以在函数内部根据下单合约名称对买/卖一价做了转换。 +[]( https://dn-filebox.qbox.me/857d21ada91345aa6c0aa260a934c53fd85a51dc.jpg ) +**取消订单函数**:cancelOrders ( ) +获取所有未成交订单数组,并逐个取消。并且如果有未成交的订单就返回false,如果没有未成交的订单就返回true。 +[]( https://dn-filebox.qbox.me/d69b810e42b8826747c43505c3d0fe3e4fc10984.jpg ) +**处理持有单个合约**:isEven ( ) +在处理套利交易中出现单腿情况,这里直接用简单的平掉所有仓位处理。当然,也可以改为追单方式。 +[]( https://dn-filebox.qbox.me/7eb8fef77840dc3ba1a1e99aaa1c7492542fcdde.jpg ) +**画图函数**:drawingChart ( ) +调用 ObjChart.add ( ) 方法,在图表中画出必要的行情数据和指标数据:上轨、中轨、下轨、正/反套价差。 +[]( https://dn-filebox.qbox.me/12d6b96d0e1666c7f6dd54a7f25c48e7e991a0ac.jpg ) +第4步:在入口函数 main ( ) 里面,执行交易前预处理代码,这些代码在程序启动后,只运行一次。包括: +- 过滤控制台中不是很重要的信息 SetErrorFilter ( ) +- 设置要交易的数字货币币种 exchange.IO ( ) +- 程序启动前清空之前绘制的图表 ObjChart.reset ( ) +- 程序启动前清空之前的状态栏信息 LogProfitReset ( ) +[]( https://dn-filebox.qbox.me/2061c1225d3c94ceda5372a4bfa3cdb98aa485c4.jpg ) + + + +### NO.7 +定义完上述的交易前预处理,紧接着就要进入下一个步骤,进入轮询模式,重复执行 onTick ( ) 函数。 +并设置 Sleep ( ) 轮询时的休眠时间,因为部分数字货币交易所的 API 对一定时间内内置了访问次数限制。 +[]( https://dn-filebox.qbox.me/c8365eb8140a2fc1de9d884ba45f6030aa546921.jpg ) +##### 二、获取并计算数据 +第1步:获取基础数据对象、账户余额、boll 指标数据,以供交易逻辑使用。 +[]( https://dn-filebox.qbox.me/5b54a0456b4dde1d6cb4e4098a3ccc68156c1e53.jpg ) +##### 三、下单并对后续处理 +第1步:根据上述的策略逻辑,执行买卖操作。首先会判断价格和指标条件是否成立,然后再判断持仓条件是否成立,最后执行 trade ( ) 下单函数 +[]( https://dn-filebox.qbox.me/03b80df179d4c3b6d23493f1a3bcf198ff16a652.jpg ) +第2步:下单完成后,需要对未成交的订单、持有单个合约等非正常情况做处理。以及绘制图表。 +[]( https://dn-filebox.qbox.me/d5f4100912fdbff321d8bd4c2ca3652590c2dbb6.jpg ) + + + +### NO.8 +以上,我们通过 200 多行,就把一个简单的数字货币跨期套利策略完完整整的创建出来。完整的代码如下: + [](https://dn-filebox.qbox.me/572bfc18fa64b9f124794510da1b7e9ebbcd8826.jpg ) + + + ### NO.9 + 本篇策略只是一个抛砖引玉,真实的实盘可不是这么简单,不过你可以照着例子发挥自己天马行空的想象。 + +需要提醒大家的是,以我有限的经验来看,目前的数字货币市场状况,纯粹的期期套利策略基本上全部不值得跑,不论是无风险的三角套利还是跨市场套利。 +[]( https://dn-filebox.qbox.me/877c11bd2e8512df961f299ab38050bef7a7f6be.jpg ) +原因就在于,无论哪个数字货币交易所的期货市场,其保证金不是法币。现如今几乎所有的数字货币从今年初至今已经下跌了70%左右。也就是说策略始终都是在赚币,但是币价是下跌的。 + +放眼望去,数字货币市场俨然已经脱离了区块链,就像当年的郁金香一样,价格始终来自于人们的预期和信心,信心又来源于价格... + +延伸阅读: +[区块链量化投资系列课程(1) - 简介](https://quant.la/Article/View/818/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%281%29---%E7%AE%80%E4%BB%8B.html) +[区块链量化投资系列课程(2) - 认识数字货币](https://quant.la/Article/View/819/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%282%29---%E8%AE%A4%E8%AF%86%E6%95%B0%E5%AD%97%E8%B4%A7%E5%B8%81.html) +[区块链量化投资系列课程(4) - 动态平衡策略](https://quant.la/Article/View/1573/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%284%29---%E5%8A%A8%E6%80%81%E5%B9%B3%E8%A1%A1%E7%AD%96%E7%95%A5.html) + + + +> 源码 (javascript) + +``` javascript +// 全局变量 +// 声明一个配置图表的 chart 对象 +var chart = { + __isStock: true, + tooltip: { + xDateFormat: '%Y-%m-%d %H:%M:%S, %A' + }, + title: { + text: '交易盈亏曲线图(详细)' + }, + rangeSelector: { + buttons: [{ + type: 'hour', + count: 1, + text: '1h' + }, { + type: 'hour', + count: 2, + text: '3h' + }, { + type: 'hour', + count: 8, + text: '8h' + }, { + type: 'all', + text: 'All' + }], + selected: 0, + inputEnabled: false + }, + xAxis: { + type: 'datetime' + }, + yAxis: { + title: { + text: '价差' + }, + opposite: false, + }, + series: [{ + name: "上轨", + id: "线1,up", + data: [] + }, { + name: "中轨", + id: "线2,middle", + data: [] + }, { + name: "下轨", + id: "线3,down", + data: [] + }, { + name: "basb", + id: "线4,basb", + data: [] + }, { + name: "sabb", + id: "线5,sabb", + data: [] + }] +}; +var ObjChart = Chart(chart); // 画图对象 +var bars = []; // 存储价差序列 +var oldTime = 0; // 记录历史数据时间戳 + +// 参数 +var tradeTypeA = "this_week"; // 套利A合约 +var tradeTypeB = "quarter"; // 套利B合约 +var dataLength = 10; //指标周期长度 +var timeCycle = 1; // K线周期 +var name = "ETC"; // 币种 +var unit = 1; // 下单量 + +// 基础数据 +function Data(tradeTypeA, tradeTypeB) { // 传入套利A合约和套利B合约 + this.accountData = _C(exchange.GetAccount); // 获取账户信息 + this.positionData = _C(exchange.GetPosition); // 获取持仓信息 + var recordsData = _C(exchange.GetRecords); //获取K线数据 + exchange.SetContractType(tradeTypeA); // 订阅套利A合约 + var depthDataA = _C(exchange.GetDepth); // 套利A合约深度数据 + exchange.SetContractType(tradeTypeB); // 订阅套利B合约 + var depthDataB = _C(exchange.GetDepth); // 套利B合约深度数据 + this.time = recordsData[recordsData.length - 1].Time; // 获取最新数据时间 + this.askA = depthDataA.Asks[0].Price; // 套利A合约卖一价 + this.bidA = depthDataA.Bids[0].Price; // 套利A合约买一价 + this.askB = depthDataB.Asks[0].Price; // 套利B合约卖一价 + this.bidB = depthDataB.Bids[0].Price; // 套利B合约买一价 + // 正套价差(合约A卖一价 - 合约B买一价) + this.basb = depthDataA.Asks[0].Price - depthDataB.Bids[0].Price; + // 反套价差(合约A买一价 - 合约B卖一价) + this.sabb = depthDataA.Bids[0].Price - depthDataB.Asks[0].Price; +} + +// 获取持仓 +Data.prototype.mp = function (tradeType, type) { + var positionData = this.positionData; // 获取持仓信息 + for (var i = 0; i < positionData.length; i++) { + if (positionData[i].ContractType == tradeType) { + if (positionData[i].Type == type) { + if (positionData[i].Amount > 0) { + return positionData[i].Amount; + } + } + } + } + return false; +} + +// 合成新K线数据和boll指标数据 +Data.prototype.boll = function (num, timeCycle) { + var self = {}; // 临时对象 + // 正套价差和反套价差中间值 + self.Close = (this.basb + this.sabb) / 2; + if (this.timeA == this.timeB) { + self.Time = this.time; + } // 对比两个深度数据时间戳 + if (this.time - oldTime > timeCycle * 60000) { + bars.push(self); + oldTime = this.time; + } // 根据指定时间周期,在K线数组里面传入价差数据对象 + if (bars.length > num * 2) { + bars.shift(); // 控制K线数组长度 + } else { + return; + } + var boll = TA.BOLL(bars, num, 2); // 调用talib库中的boll指标 + return { + up: boll[0][boll[0].length - 1], // boll指标上轨 + middle: boll[1][boll[1].length - 1], // boll指标中轨 + down: boll[2][boll[2].length - 1] // boll指标下轨 + } // 返回一个处理好的boll指标数据 +} + +// 下单 +Data.prototype.trade = function (tradeType, type) { + exchange.SetContractType(tradeType); // 下单前先重新订阅合约 + var askPrice, bidPrice; + if (tradeType == tradeTypeA) { // 如果是A合约下单 + askPrice = this.askA; // 设置askPrice + bidPrice = this.bidA; // 设置bidPrice + } else if (tradeType == tradeTypeB) { // 如果是B合约下单 + askPrice = this.askB; // 设置askPrice + bidPrice = this.bidB; // 设置bidPrice + } + switch (type) { // 匹配下单模式 + case "buy": + exchange.SetDirection(type); // 设置下单模式 + return exchange.Buy(askPrice, unit); + case "sell": + exchange.SetDirection(type); // 设置下单模式 + return exchange.Sell(bidPrice, unit); + case "closebuy": + exchange.SetDirection(type); // 设置下单模式 + return exchange.Sell(bidPrice, unit); + case "closesell": + exchange.SetDirection(type); // 设置下单模式 + return exchange.Buy(askPrice, unit); + default: + return false; + } +} + +// 取消订单 +Data.prototype.cancelOrders = function () { + Sleep(500); // 撤单前先延时,因为有些交易所你懂的 + var orders = _C(exchange.GetOrders); // 获取未成交订单数组 + if (orders.length > 0) { // 如果有未成交的订单 + for (var i = 0; i < orders.length; i++) { //遍历未成交订单数组 + exchange.CancelOrder(orders[i].Id); //逐个取消未成交的订单 + Sleep(500); //延时0.5秒 + } + return false; // 如果取消了未成交的单子就返回false + } + return true; //如果没有未成交的订单就返回true +} + +// 处理持有单个合约 +Data.prototype.isEven = function () { + var positionData = this.positionData; // 获取持仓信息 + var type = null; // 转换持仓方向 + // 如果持仓数组长度余2不等于0或者持仓数组长度不等于2 + if (positionData.length % 2 != 0 || positionData.length != 2) { + for (var i = 0; i < positionData.length; i++) { // 遍历持仓数组 + if (positionData[i].Type == 0) { // 如果是多单 + type = 10; // 设置下单参数 + } else if (positionData[i].Type == 1) { // 如果是空单 + type = -10; // 设置下单参数 + } + // 平掉所有仓位 + this.trade(positionData[i].ContractType, type, positionData[i].Amount); + } + } +} + +// 画图 +Data.prototype.drawingChart = function (boll) { + var nowTime = new Date().getTime(); + ObjChart.add([0, [nowTime, boll.up]]); + ObjChart.add([1, [nowTime, boll.middle]]); + ObjChart.add([2, [nowTime, boll.down]]); + ObjChart.add([3, [nowTime, this.basb]]); + ObjChart.add([4, [nowTime, this.sabb]]); + ObjChart.update(chart); +} + +// 交易条件 +function onTick() { + var data = new Data(tradeTypeA, tradeTypeB); // 创建一个基础数据对象 + var accountStocks = data.accountData.Stocks; // 账户余额 + var boll = data.boll(dataLength, timeCycle); // 获取boll指标数据 + if (!boll) return; // 如果没有boll数据就返回 + // 价差说明 + // basb = (合约A卖一价 - 合约B买一价) + // sabb = (合约A买一价 - 合约B卖一价) + if (data.sabb > boll.middle && data.sabb < boll.up) { // 如果sabb高于中轨 + if (data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单 + data.trade(tradeTypeA, "closebuy"); // 合约A平多 + } + if (data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单 + data.trade(tradeTypeB, "closesell"); // 合约B平空 + } + } else if (data.basb < boll.middle && data.basb > boll.down) { // 如果basb低于中轨 + if (data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单 + data.trade(tradeTypeA, "closesell"); // 合约A平空 + } + if (data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单 + data.trade(tradeTypeB, "closebuy"); // 合约B平多 + } + } + if (accountStocks * Math.max(data.askA, data.askB) > 1) { // 如果账户有余额 + if (data.basb < boll.down) { // 如果basb价差低于下轨 + if (!data.mp(tradeTypeA, 0)) { // 下单前检测合约A是否有多单 + data.trade(tradeTypeA, "buy"); // 合约A开多 + } + if (!data.mp(tradeTypeB, 1)) { // 下单前检测合约B是否有空单 + data.trade(tradeTypeB, "sell"); // 合约B开空 + } + } else if (data.sabb > boll.up) { // 如果sabb价差高于上轨 + if (!data.mp(tradeTypeA, 1)) { // 下单前检测合约A是否有空单 + data.trade(tradeTypeA, "sell"); // 合约A开空 + } + if (!data.mp(tradeTypeB, 0)) { // 下单前检测合约B是否有多单 + data.trade(tradeTypeB, "buy"); // 合约B开多 + } + } + } + data.cancelOrders(); // 撤单 + data.drawingChart(boll); // 画图 + data.isEven(); // 处理持有单个合约 +} + +//入口函数 +function main() { + // 过滤控制台中不是很重要的信息 + SetErrorFilter("429|GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout|Futures_OP"); + exchange.IO("currency", name + '_USDT'); //设置要交易的数字货币币种 + ObjChart.reset(); //程序启动前清空之前绘制的图表 + LogProfitReset(); //程序启动前清空之前的状态栏信息 + while (true) { // 进入轮询模式 + onTick(); // 执行onTick函数 + Sleep(500); // 休眠0.5秒 + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/104964 + +> 更新时间 + +2018-08-10 15:43:51 diff --git "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" new file mode 100644 index 00000000..82a9b4d8 --- /dev/null +++ "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" @@ -0,0 +1,210 @@ + +> 策略名称 + +区块链量化投资系列课程(4) - 动态平衡策略 + +> 策略作者 + +Hukybo + +> 策略描述 + +阅读原文:[区块链量化投资系列课程(4) - 动态平衡策略](https://quant.la/Article/View/1573/[1-4]%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B---%E5%8A%A8%E6%80%81%E5%B9%B3%E8%A1%A1%E7%AD%96%E7%95%A5.html) + +### 前言 +沃伦 · 巴菲特的导师本杰明 · 格雷厄姆曾经在[《聪明的投资者》](https://quant.la/Download/View/2742/%E8%81%AA%E6%98%8E%E7%9A%84%E6%8A%95%E8%B5%84%E8%80%85%EF%BC%88%E7%AC%AC4%E7%89%88%EF%BC%89.html)一书中,曾经提到过一种股票债券动态平衡的交易模式。 +[]( https://dn-filebox.qbox.me/71666050bcdc809d074f5cfa3499650045306c5d.png ) +这种交易模式非常简单: +- 把手中 50% 的资金投资于股票基金,剩下 50% 投资于债券基金。即股票和债券两者各占一半。 +- 根据固定间隔时间或市场变化进行一次资产再平衡,使股票资产和债券资产的比例恢复到初始的 1:1。 +这就是整个策略的全部逻辑,包含了什么时候买卖,以及买卖多少。够简单吧! + +在这个方法中,债券基金的波动率其实很小,远远低于股票波动率,所以债券在这里被当做『 参照锚 』,也就是说,用债券来衡量股票究竟是涨得太多了,还是涨得太少了。如果,股票价格上涨,会使得股票的市值大于债券的市值,当两者市值比率超过设定的阈值时,则对总仓位进行重新调整,卖出股票,并且买入债券,使股债市值比例恢复至初始的 1:1。 + +反之,股票价格下跌,会使得股票的市值小于债券的市值,当两者市值比率超过设定的阈值时,则对总仓位进行重新调整,买入股票,并且卖出债券,使股债市值比例恢复至初始的 1:1。 +[]( https://dn-filebox.qbox.me/0b155ba7a40dfa853174cbc60ea89a40434b2441.jpg ) + +就这样,在动态平衡股票和债券之间的比例,就够享受到股票成长的果实,并且减少了资产波动率。作为价值投资的先驱,格雷厄姆为我们提供了一个很好的思路。 + +既然这是一个完整的策略,为何我们不把它用在数字货币上呢? + +### 区块链资产 BTC 中的动态平衡策略 +#### 策略逻辑 +- 按照当前的 BTC 的价值,账户余额保留¥5000 现金和 0.1个 BTC,即现金和BTC 市值的初始比例是 1:1。 +- 如果 BTC 的价格上涨至¥6000,即 BTC 市值大于账户余额,并且其之间的差超过设定的阈值,就卖掉(6000-5000)/6000/2个币。说明 BTC 升值了,把钱兑换回来。 +- 如果 BTC 的价格下跌至¥4000,即 BTC市值小于账户余额,并且其之间的差超过设定的阈值,就买入(5000-4000)/4000/2个币。说明 BTC 贬值了,把 BTC 买回来。 + +就这样,不管 BTC 是升值还是贬值,始终动态保持账户余额和 BTC 的市值相等。如果 BTC 贬值了就买一些,等再涨回来,就再卖一些,就好像天平一样。 + +### 那么,如何用代码去实现呢? +我们以发明者量化交易平台为例,首先让我们看一下策略框架: +[]( https://dn-filebox.qbox.me/f0b1866a50126e6ffb3670fefc9cc0a0f5677ab6.png ) + +整个策略框架其实很简单,一个 main 主函数、一个 onTick 下单函数、一个 CancelPendingOrders 函数、以及必要参数。 + +### 下单模块 +[]( https://dn-filebox.qbox.me/fa17c458239f19cab2986f0cf7cd097a521eec4b.png ) + +下单交易逻辑条理清晰,所有的注释都已经写到代码里面了,可以点击图片放大查看。 + +#### 主要流程如下: +- 获取账户信息。 +- 获取 Tick 数据。 +- 计算 Tick 数据买卖价差。 +- 计算账户余额和 BTC 市值价差。 +- 计算买卖条件、下单价格、下单量。 +- 下单,并返回 true。 + +### 撤单模块 +[]( https://dn-filebox.qbox.me/6245854ec66a01bb7ea610da75b9ad46422a4f5d.png ) + +撤单模块就更简单了,步骤如下: +- 撤单前先等待 1 秒,个别交易所,你懂的。 +- 持续获取未成交订单数组,如果返回异常,则继续获取。 +- 如果未成交订单数组为空,即时返回撤单状态。 +- 如果有未成交的订单,则遍历整个数组,并依次根据订单号撤单。 + + +### 策略全部源码 +![]( https://dn-filebox.qbox.me/8df49e36426dfdc05c5d496c73f1300afd79af0f.jpg ) + +借助发明者量化交易平台,短短 80 行代码,一个完整的区块链 BTC 动态平衡策略应运而生。但这么简单的策略,究竟有没有价值呢? + +接下来,让我们测试一下这个简单的动态平衡策略,看看到底有没有效果。以下是在 BTC 的历史数据上的回测,仅供大家参考。 + + +### 回测环境 +[]( https://dn-filebox.qbox.me/e9ffd2a1451dc0c2b31a20cd1a54697567d1e561.png ) + + +### 回测绩效 +[]( https://dn-filebox.qbox.me/2a1e1ff7497de19f707add137debc547a93ca4ba.png ) + + +### 回测曲线 +[]( https://dn-filebox.qbox.me/dcbcd9b31ade9b9ce72b0ed86aa82435d5a11ef5.png ) + + +再来一张,同时期 BTC 价格走势图 +[]( https://dn-filebox.qbox.me/ec84ecde879721f515b9db17200b5fded748fc76.png ) + + +有没有震精到你。 + + +BTC 已经持续了长达 8 个月下跌,甚至最大跌幅超过70%,这造成很多投资者对区块链资产失去信心。本篇策略累计收益高达 160%,年化收益风险比超过 5。对于一个这么简单的投资策略,这个投资回报率已经超过绝大多数梭哈的群众了。 + +本篇动态平衡策略,只有一个核心参数(threshold 阈值),是一个很简单的投资方法,追求的不是超额的收益,而是稳健的收益。与趋势策略相反,动态平衡策略却是逆势而动。在市场热的时候减仓降温,市场冷清的时候加仓蛰伏,有点类似宏观经济调控。其实,动态平衡策略正是秉承了价格不可预测的观念,同时又捕捉价格波动的一门手艺。动态平衡策略的关键核心在设定和调整资产配置比例,还有触发阈值。 + +鉴于篇幅原因,一篇文章没办法做到面面俱到,要知道文字之外,存乎一心。动态平衡策略最重要的是投资思想,你甚至可以把本篇中的单个 BTC 资产换成一篮子区块链资产组合。 +[]( https://dn-filebox.qbox.me/a0d2ff01f4f8ed7ad77eeeecb6650129040f792b.jpg ) + +最后,让我们以本杰明 · 格雷厄姆在《聪明的投资者》一书中的名言来结束本篇:股票市场并非一个能精确衡量价值的『 称重计 』,相反它是一个『 投票机 』,不计其数的人所做出的决定是一种理性和感性的掺杂物,有很多时候这些抉择和理性的价值评判相去甚远。投资的秘诀就是在价格远远低于内在价值时投资,并且相信市场趋势会回升。——本杰明 · 格雷厄姆《聪明的投资者》 + + +延伸阅读: +[区块链量化投资系列课程(1) - 简介](https://quant.la/Article/View/818/Empty.html) +[区块链量化投资系列课程(2) - 认识数字货币](https://quant.la/Article/View/819/Empty.html) +[区块链量化投资系列课程(3) - 跨期套利](https://quant.la/Article/View/816/Empty.html) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|threshold|0.005|阀值| +|Interval|2000|出错重试间隔(毫秒)| +|LoopInterval|60|轮询间隔(秒)| +|MinStock|0.001|最小交易量| +|XPrecision|4|量精度| +|ZPrecision|8|价格精度| + + +> 源码 (javascript) + +``` javascript +// 回测环境 +/*backtest +start: 2018-01-01 00:00:00 +end: 2018-08-01 11:00:00 +period: 1m +exchanges: [{"eid":"OKCoin_EN","currency":"BTC"}] +*/ + + + +// 撤单函数 +function CancelPendingOrders() { + Sleep(1000); // 休眠 1秒 + var ret = false; + while (true) { + var orders = null; + // 持续获取未成交订单数组,如果返回异常,则继续获取 + while (!(orders = exchange.GetOrders())) { + Sleep(1000); // 休眠 1秒 + } + if (orders.length == 0) { // 如果订单数组为空 + return ret; // 返回撤单状态 + } + for (var j = 0; j < orders.length; j++) { // 遍历未成交订单数组 + exchange.CancelOrder(orders[j].Id); // 依次取消未成交订单 + ret = true; + if (j < (orders.length - 1)) { + Sleep(1000); // 休眠 1秒 + } + } + } +} + +// 下单函数 +function onTick() { + var acc = _C(exchange.GetAccount); // 获取账户信息 + var ticker = _C(exchange.GetTicker); // 获取 Tick 数据 + var spread = ticker.Sell - ticker.Buy; // 获取 Tick 数据的买卖价差 + // 账户余额与当前持仓价值的差值的 0.5倍 + var diffAsset = (acc.Balance - (acc.Stocks * ticker.Sell)) / 2; + var ratio = diffAsset / acc.Balance; // diffAsset / 账户余额 + LogStatus('ratio:', ratio, _D()); // 打印 ratio和当前时间 + if (Math.abs(ratio) < threshold) { // 如果 ratio的绝对值小于指定阈值 + return false; // 返回 false + } + if (ratio > 0) { // 如果 ratio大于 0 + var buyPrice = _N(ticker.Sell + spread, ZPrecision); // 计算下单价格 + var buyAmount = _N(diffAsset / buyPrice, XPrecision); // 计算下单量 + if (buyAmount < MinStock) { // 如果下单量小于最小交易量 + return false; // 返回 false + } + exchange.Buy(buyPrice, buyAmount, diffAsset, ratio); // 买入下单 + } else { + var sellPrice = _N(ticker.Buy - spread, ZPrecision); // 计算下单价格 + var sellAmount = _N(-diffAsset / sellPrice, XPrecision); // 计算下单量 + if (sellAmount < MinStock) { // 如果下单量小于最小交易量 + return false; // 返回 false + } + exchange.Sell(sellPrice, sellAmount, diffAsset, ratio); // 卖出下单 + } + return true; // 返回 true +} + +// 主函数 +function main() { + // 过滤非重要信息 + SetErrorFilter("GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout"); + while (true) { // 轮询模式 + if (onTick()) { // 执行 onTick 函数 + CancelPendingOrders(); // 取消未成交的挂单 + Log(_C(exchange.GetAccount)); // 打印当前账户信息 + } + Sleep(LoopInterval * 1000); // 休眠 + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/110545 + +> 更新时间 + +2018-08-10 12:38:55 diff --git "a/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" "b/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" new file mode 100644 index 00000000..f9bc1814 --- /dev/null +++ "b/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" @@ -0,0 +1,108 @@ + +> 策略名称 + +升级版恒温器策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略名称:升级版恒温器策略 +- 数据周期:1H +- 支持:商品期货 +- 官方网站:WWW.QUANT.LA + + /upload/asset/bcf664987bac1aaff72110b1e3679d10.png + +- 主图: + 上轨,公式:TOP^^MAC+N_TMP*TMP;//布林通道上轨 + 下轨,公式:BOTTOM^^MAC-N_TMP*TMP;//布林通道下轨 + +- 副图: + CMI,公式 : CMI:ABS(C-REF(C,N_CMI-1))/(HHV(H,N_CMI)-LLV(L,N_CMI))*100;//0-100 取值越大,说明趋势越强,CMI<20震荡模式,CMI>20为趋势 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|STOPLOSS|true|止损价格百分比| +|N|50|布林线指标参数1| +|N_TMP|2|布林线指标参数2| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-11-06 00:00:00 +end: 2018-12-04 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +*) + +MAC:=MA(CLOSE,N); +TMP:=STD(CLOSE,N); +TOP^^MAC+N_TMP*TMP;//布林通道上轨 +BOTTOM^^MAC-N_TMP*TMP;//布林通道下轨 +BBOLL:=C>MAC; +SBOLL:=C20为趋势 + +N_KD:=9; +M1:=3; +M2:=3; +RSV:=(CLOSE-LLV(LOW,N_KD))/(HHV(HIGH,N_KD)-LLV(LOW,N_KD))*100;//收盘价与N周期最低值做差,N周期最高值与N周期最低值做差,两差之间做比值。 +K:=SMA(RSV,M1,1);//RSV的移动平均值 +D:=SMA(K,M2,1);//K的移动平均值 +MIND:=30; +BKD:=K>D AND D100-MIND; + +//震荡模式 +BUYPK1:=CMI < 20 AND BKD;//震荡多单买平开 +SELLPK1:=CMI < 20 AND SKD;//震荡空单卖平开 + +//趋势模式下原有震荡持仓的处理 +SELLY1:=REF(CMI,BARSBK) < 20 AND C>BKPRICE*(1+0.01*STOPLOSS*3) AND KD;//震荡空单止盈 + +//趋势模式 +BUYPK2:=CMI >= 20 AND C > TOP;//趋势多单买平开 +SELLPK2:=CMI >= 20 AND C < BOTTOM;//趋势空单卖平开 + +//趋势模式下原有震荡持仓的处理 +SELLY2:=REF(CMI,BARSBK) >= 20 AND C>BKPRICE*(1+0.01*STOPLOSS*3) AND SBOLL;//趋势多单止盈 +BUYY2:=REF(CMI,BARSSK) >= 20 AND C= 20 AND C= 20 AND C>SKPRICE*(1+0.01*STOPLOSS) AND BBOLL;//趋势空单止损 + +IF BARPOS>N THEN BEGIN + BUYPK1,BPK; + SELLPK1,SPK; + BUYPK2,BPK; + SELLPK2,SPK; +END +BUYY1,BP(SKVOL); +BUYY2,BP(SKVOL); +BUYS2,BP(SKVOL); +SELLY1,SP(BKVOL); +SELLY2,SP(BKVOL); +SELLS2,SP(BKVOL); + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/129086 + +> 更新时间 + +2018-12-06 13:39:54 diff --git "a/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.js" "b/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.js" deleted file mode 100644 index 70f36188..00000000 --- "a/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.js" +++ /dev/null @@ -1,111 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/345 -策略名称: 单平台均衡策略 -策略作者: Zero -策略描述: - -这个需要建仓,比如账户有5000块钱,跟1个币,如果币的价值大于账户的余额5000了并且差价超过阀值,比如币现在值6000块钱,就卖掉(6000-5000)/6000/2个币,说明币升值了,把钱兑换回来,如果币贬值了,比如4000块钱了,就买入(5000-4000)/4000/2个币, 币跌的时候买一些回来,如果再涨了,就再卖掉,好像天平一样,两边不同的对冲,所以我命名为均衡策略 - - -参数 默认值 描述 ------------- ----- ---------- -threshold 10 阀值 -Interval 2000 出错重试间隔(毫秒) -LoopInterval 60 轮询间隔(秒) -*/ - -function adjustFloat(v) { - return Math.floor(v*1000)/1000; -} - -function GetTicker() { - var ticker; - while (!(ticker = exchange.GetTicker())) { - Sleep(Interval); - } - return ticker; -} - -function GetAccount() { - var account; - while (!(account = exchange.GetAccount())) { - Sleep(Interval); - } - return account; -} - -function CancelPendingOrders() { - var ret = false; - while (true) { - var orders = null; - while (!(orders = exchange.GetOrders())) { - Sleep(Interval); - } - - if (orders.length == 0) { - return ret; - } - - for (var j = 0; j < orders.length; j++) { - exchange.CancelOrder(orders[j].Id); - ret = true; - if (j < (orders.length-1)) { - Sleep(Interval); - } - } - } - return ret; -} - -function updateProft(accountInit, accountNow, ticker) { - LogProfit(accountNow.Balance + accountNow.FrozenBalance + ((accountNow.Stocks + accountNow.FrozenStocks - accountInit.Stocks - accountInit.FrozenStocks) * ticker.Buy) - accountInit.Balance - accountInit.FrozenBalance); -} - -var STATE_WAIT_IDLE = 0; -var STATE_WAIT_BUY = 1; -var STATE_WAIT_SELL = 2; - -var State = STATE_WAIT_IDLE; -var InitAccount = null; - -function onTick() { - var opSuccess = false; - if (State != STATE_WAIT_IDLE) { - opSuccess = !CancelPendingOrders(); - State = STATE_WAIT_IDLE; - } - - var portfolio = GetAccount(); - var ticker = GetTicker(); - - if (opSuccess) { - updateProft(InitAccount, portfolio, ticker); - } - - var diff = portfolio.Balance - (portfolio.Stocks * ticker.Sell); - - if (diff > threshold) { - var amount = adjustFloat(diff / 2 / ticker.Buy); - if (amount < 0.001) { - return; - } - exchange.Buy(ticker.Buy*1.1, amount); - State = STATE_WAIT_BUY; - } else if (diff <= -threshold) { - var amount = adjustFloat(Math.abs(diff) / 2 / ticker.Sell); - if (amount < 0.001) { - return; - } - exchange.Sell(ticker.Sell*0.9, amount); - State = STATE_WAIT_SELL; - } -} - -function main() { - InitAccount = GetAccount(); - LoopInterval = Math.max(LoopInterval, 1); - while (1) { - onTick(); - Sleep(LoopInterval * 1000); - } -} diff --git "a/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.md" "b/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.md" new file mode 100644 index 00000000..e15b733e --- /dev/null +++ "b/\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245.md" @@ -0,0 +1,111 @@ + +> 策略名称 + +单平台均衡策略 + +> 策略作者 + +Zero + +> 策略描述 + +这个需要建仓,比如账户有5000块钱,跟1个币,如果币的价值大于账户的余额5000了并且差价超过阀值,比如币现在值6000块钱,就卖掉(6000-5000)/6000/2个币,说明币升值了,把钱兑换回来,如果币贬值了,比如4000块钱了,就买入(5000-4000)/4000/2个币, 币跌的时候买一些回来,如果再涨了,就再卖掉,好像天平一样,两边不同的对冲,所以我命名为均衡策略 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|threshold|0.05|阀值| +|Interval|2000|出错重试间隔(毫秒)| +|LoopInterval|60|轮询间隔(秒)| +|MinStock|0.001|最小交易量| +|XPrecision|4|量精度| +|ZPrecision|8|价格精度| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2018-03-01 00:00:00 +end: 2018-08-01 11:00:00 +period: 15m +exchanges: [{"eid":"OKCoin_EN","currency":"BTC"}] +*/ + +function CancelPendingOrders() { + var ret = false; + while (true) { + var orders = null; + while (!(orders = exchange.GetOrders())) { + Sleep(Interval); + } + + if (orders.length == 0) { + return ret; + } + + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id); + ret = true; + if (j < (orders.length-1)) { + Sleep(Interval); + } + } + } + return ret; +} + +var InitAccount = null; + +function onTick() { + var acc = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + var spread = ticker.Sell - ticker.Buy; + var diffAsset = (acc.Balance - (acc.Stocks * ticker.Sell)) / 2; + var ratio = diffAsset / acc.Balance; + LogStatus('ratio:', ratio, _D()); + if (Math.abs(ratio) < threshold) { + return false; + } + if (ratio > 0) { + var buyPrice = _N(ticker.Sell + spread, ZPrecision); + var buyAmount = _N(diffAsset / buyPrice, XPrecision); + if (buyAmount < MinStock) { + return false; + } + exchange.Buy(buyPrice, buyAmount, diffAsset, ratio); + } else { + var sellPrice = _N(ticker.Buy - spread, ZPrecision); + var sellAmount = _N(-diffAsset / sellPrice, XPrecision); + if (sellAmount < MinStock) { + return false; + } + exchange.Sell(sellPrice, sellAmount, diffAsset, ratio); + } + return true; +} + +function main() { + InitAccount = _C(exchange.GetAccount); + LoopInterval = Math.max(LoopInterval, 1); + while (1) { + if (onTick()) { + Sleep(1000); + CancelPendingOrders(); + Log(_C(exchange.GetAccount)); + } + Sleep(LoopInterval * 1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/345 + +> 更新时间 + +2018-08-09 12:22:08 diff --git "a/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.js" "b/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.md" similarity index 94% rename from "\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.js" rename to "\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.md" index 10855a79..f22fa10a 100644 --- "a/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.js" +++ "b/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/2406 -策略名称: 单点狙击高频加仓自动反手解套算法 V1.2 -策略作者: Zero -策略描述: + +> 策略名称 + +单点狙击高频加仓自动反手解套算法 V1.2 + +> 策略作者 + +Zero + +> 策略描述 先开仓,指定一个盈利点平仓,如果平不了,超过止损点,就再加仓拉低成本价, 一直加到盈利出场,如果加仓加到没钱或者币再加了,就开始反手做,原来是做空的,就反手做多,这样一直反复. 也可以不让自动反手,让程序一直等着解套. @@ -28,30 +33,36 @@ V1.1 解决了OKCoin冻结0.0001个币导致程序卡住的bug 更详细的说明, 移步: https://www.botvs.com/#!/bbs-topic/38 +> 策略参数 + + -参数 默认值 描述 -------------- ----- ------------- -OpType 0 首次开仓方向: 做多|做空 -OpAmount 0.1 开仓数量 -OpMode 0 开仓方式: 吃单|挂单 -MaxSpace 0.5 挂单失效距离 -SlidePrice 0.1 下单滑动价(元) -MaxAmount 0.3 开仓最大单次下单量 -AddGoal true 加仓间距(元) -AddLine 0.8 加仓均价目标(元) -ProfitGoal 0.5 平仓目标(元) -Interval true 轮询间隔(秒) -RestoreIt false 恢复进度 -RestoreType 0 持仓方向: 做多|做空 -RestorePrice false 持仓均价 -RestoreAmount false 持仓数量 -RestoreProfit false 上次盈利 -SaveLocal false 保存本地日志 -AutoReverse true 自动反手 -MinStock 0.01 最小交易币数 -*/ +|参数|默认值|描述| +|----|----|----| +|OpType|0|首次开仓方向: 做多|做空| +|OpAmount|0.1|开仓数量| +|OpMode|0|开仓方式: 吃单|挂单| +|MaxSpace|0.5|挂单失效距离| +|SlidePrice|0.1|下单滑动价(元)| +|MaxAmount|0.3|开仓最大单次下单量| +|AddGoal|true|加仓间距(元)| +|AddLine|0.8|加仓均价目标(元)| +|ProfitGoal|0.5|平仓目标(元)| +|Interval|true|轮询间隔(秒)| +|RestoreIt|false|恢复进度| +|RestoreType|0|持仓方向: 做多|做空| +|RestorePrice|false|持仓均价| +|RestoreAmount|false|持仓数量| +|RestoreProfit|false|上次盈利| +|SaveLocal|false|保存本地日志| +|AutoReverse|true|自动反手| +|MinStock|0.01|最小交易币数| +> 源码 (javascript) + +``` javascript + var TradeType = OpType == 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; var OrgAccount = null; var Counter = {s : 0, f: 0}; @@ -454,3 +465,12 @@ function main() { Sleep(Interval); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/2406 + +> 更新时间 + +2018-06-05 16:27:50 diff --git "a/\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).js" "b/\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).md" similarity index 83% rename from "\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).js" rename to "\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).md" index a0603a72..44706ff1 100644 --- "a/\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).js" +++ "b/\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).md" @@ -1,14 +1,22 @@ -/* -策略出处: https://www.fmz.com/strategy/1084 -策略名称: 单独计算收益(代码来自zero) -策略作者: botvsing -策略描述: + +> 策略名称 + +单独计算收益(代码来自zero) + +> 策略作者 + +botvsing + +> 策略描述 收益可以和策略放在一起,但还是独立出来更好。原因:1、交易策略更改中断时,收益不会被重置。2、收益计算本身会调用API函数,经常造成策略API网络错误,影响交易运行,独立出来减少这种可能性。3、可以自定义循环间隔。 -*/ +> 源码 (javascript) + +``` javascript + function adjustFloat(v) { return Math.floor(v*1000)/1000; @@ -45,3 +53,12 @@ function main() { Sleep(5000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/1084 + +> 更新时间 + +2016-05-10 20:05:02 diff --git "a/\345\215\225\350\276\271\347\275\221\346\240\274.js" "b/\345\215\225\350\276\271\347\275\221\346\240\274.md" similarity index 88% rename from "\345\215\225\350\276\271\347\275\221\346\240\274.js" rename to "\345\215\225\350\276\271\347\275\221\346\240\274.md" index 66e798f5..8d9c57c6 100644 --- "a/\345\215\225\350\276\271\347\275\221\346\240\274.js" +++ "b/\345\215\225\350\276\271\347\275\221\346\240\274.md" @@ -1,26 +1,37 @@ -/* -策略出处: https://www.fmz.com/strategy/88472 -策略名称: 单边网格 -策略作者: 6821281 -策略描述: + +> 策略名称 + +单边网格 + +> 策略作者 + +6821281 + +> 策略描述 测试的时候填写起始价格来测试是否正常 起始价格不填写为现价买入+价格区间买入 微信173970984 +> 策略参数 + -参数 默认值 描述 ------------ ----- ------- -buyjingdu 2 下单价格精度 -buymount 3 下单数量精度 -buypersent true 下单百分比 -buylimit 0.01 最小交易量 -reffertime 3000 刷新时间间隔 -moneybt 100 网格的价格间距 -startpricex false 起始价格 -liruncha 0.1 利润差价 -*/ +|参数|默认值|描述| +|----|----|----| +|buyjingdu|2|下单价格精度| +|buymount|3|下单数量精度| +|buypersent|true|下单百分比| +|buylimit|0.01|最小交易量| +|reffertime|3000|刷新时间间隔| +|moneybt|100|网格的价格间距| +|startpricex|false|起始价格| +|liruncha|0.1|利润差价| + + +> 源码 (javascript) + +``` javascript //获取账户余额 var startPrice= 0; function getBalancex(){ @@ -168,3 +179,12 @@ function main(){ Sleep(reffertime); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/88472 + +> 更新时间 + +2018-04-26 23:14:14 diff --git "a/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245.md" "b/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245.md" new file mode 100644 index 00000000..c5de956b --- /dev/null +++ "b/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245.md" @@ -0,0 +1,96 @@ + +> 策略名称 + +双均线DDI策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略思路:双均线确定方向,用DDI指标,确定进场时点,比例止损和回撤止盈 +- 数据周期:15M +- 数据合约:指数合约 +- 交易合约:主力合约 +- 适合品种:沪银/沪镍/热卷/铁矿石/焦煤/焦炭/鸡蛋/郑醇/PP/螺纹/橡胶/锰硅/郑煤等 +- 官方网站:www.quant.la + +- 主图指标线: + VAR2^^MA(C,PARAM2); + VAR3^^MA(VAR2,PARAM1); + +- 副图指标线: + VAR9:MA(VAR8,2*PARAM1); + VAR10:MA(VAR9,PARAM1); + VAR8:VAR6-VAR7; + +/upload/asset/e83641b0567b242687792b105de8e211.png + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|PARAM1|60|均线2的参数| +|PARAM2|300|均线1的参数| +|PARAM3|true|价格系数| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2017-01-01 00:00:00 +end: 2017-02-20 00:00:00 +period: 15m +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","balance":20000}] +*) + +VAR1:=MAX(1,INTPART(MONEYTOT/(O*UNIT*0.1))); + +VAR2^^MA(C,PARAM2); +VAR3^^MA(VAR2,PARAM1); + +VAR4:=IFELSE((HIGH+LOW)<=(REF(HIGH,1)+REF(LOW,1)),0,MAX(ABS(HIGH-REF(HIGH,1)),ABS(LOW-REF(LOW,1)))),NODRAW; +VAR5:=IFELSE((HIGH+LOW)>=(REF(HIGH,1)+REF(LOW,1)),0,MAX(ABS(HIGH-REF(HIGH,1)),ABS(LOW-REF(LOW,1)))),NODRAW; +VAR6:=SUM(VAR4,PARAM1)/(SUM(VAR4,PARAM1)+SUM(VAR5,PARAM1)),NODRAW; +VAR7:=SUM(VAR5,PARAM1)/(SUM(VAR5,PARAM1)+SUM(VAR4,PARAM1)),NODRAW; +VAR8:VAR6-VAR7; +VAR9:MA(VAR8,2*PARAM1); +VAR10:MA(VAR9,PARAM1); + +BUYK:=BARPOS>PARAM2 AND C>VAR2 AND VAR2>VAR3 AND VAR8>0 AND VAR9>VAR10; +SELLK:=BARPOS>PARAM2 AND CBKPRICE*(1+0.01*PARAM3); +BUYY:=C>VAR2 AND CSKPRICE*(1+PARAM3*0.01); + +BKVOL=0 AND BUYK,BK(VAR1); +SKVOL=0 AND SELLK,SK(VAR1); + +SELLS,SP(BKVOL); +BUYS,BP(SKVOL); + +SELLY,SP(BKVOL); +BUYY,BP(SKVOL); + +// DRAWCOLORKLINE(BKVOL=0 AND SKVOL=0,COLORWHITE,0); +// DRAWCOLORKLINE(SKVOL>0,COLORGREEN,0); +// DRAWCOLORKLINE(BKVOL>0,COLORRED,0); +// 累计盈亏..OFFSETPROFIT1,COLORWHITE,BOLD; +// PROFITSUM..OFFSETPROFIT1,COLORWHITE,BOLD; +//TRVAR10E_OTHER('AUTO'); +``` + +> 策略出处 + +https://www.fmz.com/strategy/128133 + +> 更新时间 + +2018-12-05 11:47:14 diff --git "a/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210.md" "b/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210.md" new file mode 100644 index 00000000..a80e5a55 --- /dev/null +++ "b/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210.md" @@ -0,0 +1,76 @@ + +> 策略名称 + +双均线策略与相对强弱RSI指标组合 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略名称:双均线策略与相对强弱RSI指标组合 +- 数据周期:15M,30M等 +- 支持:商品期货 +- 官方网站:www.quant.la + +/upload/asset/9955a36cca1be0e9d73f99fa8bdb4ac8.png + +- 主图: + 均线1,公式:MA1^^EMA(C,N1); + 均线2,公式:MA2^^EMA(C,N2); + +- 副图: + RSI,公式:RSIVALUE:SMA(MAX(CLOSE-REF(CLOSE,1),0),LENGTH,1)/SMA(ABS(CLOSE-REF(CLOSE,1)),LENGTH,1)*100; + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|SLOSS|true|止损百分比| +|N1|50|均线1参数| +|N2|300|均线2参数| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-11-05 00:00:00 +end: 2018-12-05 00:00:00 +period: 15m +exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}] +args: [["ContractType","this_week",126961]] +*) + +MA1^^EMA(C,N1); +MA2^^EMA(C,N2); + +LENGTH:=9; +OVERBOUGHT:=70; +OVERSOLD:=100-OVERBOUGHT; +RSIVALUE:SMA(MAX(CLOSE-REF(CLOSE,1),0),LENGTH,1)/SMA(ABS(CLOSE-REF(CLOSE,1)),LENGTH,1)*100; +BUYK:=BKVOL=0 AND BARPOS>N2 AND MA1>MA2 AND C>MAX(MA1,MA2) AND CROSSUP(RSIVALUE,OVERBOUGHT); +SELLK:=SKVOL=0 AND BARPOS>N2 AND MA1BKPRICE*(1+SLOSS*0.01); +BUYY:=MA1>MA2 AND CSKPRICE*(1+SLOSS*0.01); + +BUYK,BK; +SELLK,SK; +SELLY,SP(BKVOL); +BUYY,BP(SKVOL); +SELLS,SP(BKVOL); +BUYS,BP(SKVOL); +``` + +> 策略出处 + +https://www.fmz.com/strategy/128250 + +> 更新时间 + +2018-12-05 18:20:59 diff --git "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.py" "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.md" similarity index 95% rename from "\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.py" rename to "\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.md" index cd181163..577ac12b 100644 --- "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.py" +++ "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262 \347\273\203\344\271\240\347\224\250 \346\261\202\344\272\244\346\265\201\346\261\202\346\214\207\347\202\271.md" @@ -1,21 +1,32 @@ -''' -策略出处: https://www.fmz.com/strategy/53512 -策略名称: 双平台对冲 练习用 求交流求指点 -策略作者: perseus -策略描述: + +> 策略名称 + +双平台对冲 练习用 求交流求指点 + +> 策略作者 + +perseus + +> 策略描述 Python 双平台对冲策略 +> 策略参数 + + -参数 默认值 描述 ------------- ----- ------------------------------- -LoopInterval 200 轮询周期(ms) -waitinterval 200 等待交易周期(ms) -r 0.95 balance decider -p true coefficient of arbitrage profit -q 0.2 balance trigger -''' +|参数|默认值|描述| +|----|----|----| +|LoopInterval|200|轮询周期(ms)| +|waitinterval|200|等待交易周期(ms)| +|r|0.95|balance decider| +|p|true|coefficient of arbitrage profit| +|q|0.2|balance trigger| + +> 源码 (python) + +``` python import time import numpy as np @@ -249,3 +260,12 @@ def main(): +``` + +> 策略出处 + +https://www.fmz.com/strategy/53512 + +> 更新时间 + +2017-09-07 05:28:11 diff --git "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS) (Copy).js" "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS) (Copy).js" deleted file mode 100644 index d5dbda3b..00000000 --- "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS) (Copy).js" +++ /dev/null @@ -1,225 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/61405 -策略名称: 双平台对冲js版本(two platforms hedging-JS) (Copy) -策略作者: ellajella-0378 -策略描述: - - - - -参数 默认值 描述 ------------- ------ -------- -MinSpreadA 0.51 A->B差价 -MinSpreadB 0.52 B->A差价 -MaxAmount 0.3 最大操作量 -BalanceTime 10 平衡周期(秒) -LoopInterval 200 轮询周期(ms) - -按钮 默认值 描述 ----- ----- ---------- -A->B 0.51 更改价差(A->B) -B->A 0.52 更改价差(B->A) -*/ - -function cancelAll(){ - var ref = false; - for(var e in exchanges){ - while(true){ - var n = 0; - var my_orders = _C(exchanges[e].GetOrders); - for(var order1 in my_orders){ - ref = true; - e.CancelOrder(my_orders[order1].Id); - n += 1; - } - if(n==0){ - break; - } - } - } - return ret -} - -function main(){ - if(exchanges.length != 2){ - throw("Only two exchanges are supported"); - } - - LogReset(); - LogProfitReset(); - cancelAll(); - - var initStocks = 0.0; - var initBalance = 0.0; - var minAmount = 0.1; - var lastTradeTime = 0; - var lastTradeErrExchange = ''; - var accountsCache = []; - var hedgeNum = [0, 0]; - var names = []; - var baseCurrency = exchange.GetCurrency(); - for(var e in exchanges){ - if(exchanges[e].GetCurrency() != baseCurrency){ - throw("It has to be the same currency to hedge:"+baseCurrency); - } - names.push(exchanges[e].GetName()); - var account = _C(exchanges[e].GetAccount); - accountsCache.push(account); - initStocks += account.Stocks; - initBalance += account.Balance; - } - if(baseCurrency == "BTC"){ - minAmount = 0.01 - } else { - minAmount = 0.1 - } - - Log("all balance:", _N(initBalance), "all stocks", _N(initStocks)) - while(true){ - if(accountsCache.length <= 0){ - for(var e in exchanges){ - var account1 = _C(exchanges[e].GetAccount); - accountsCache.push(account1); - } - } - Sleep(LoopInterval); - cmd = GetCommand(); - if(cmd){ - Log("CMD", cmd); - var arr = cmd.split(":"); - if(arr[0]=="A->B"){ - MinSpreadA = parseFloat(arr[1]); - } else if(arr[0]=="B->A"){ - MinSpreadB = parseFloat(arr[1]); - } - } - var depthA = exchanges[0].GetDepth(); - if (!depthA){ - continue; - } - var depthB = exchanges[1].GetDepth(); - if (!depthB){ - continue; - } - var time = new Date(); - if(lastTradeTime > 0 && time.getTime() - lastTradeTime > BalanceTime){ - var needUpdate = cancelAll(); - if (!needUpdate){ - for(var account2 in accountsCache){ - if(accountsCache[account2].FrozenBalance >= 0.1 || accountsCache[account2].FrozenStocks >= 0.001){ - needUpdate = true; - break; - } - } - } - if (needUpdate){ - for(var k in exchanges){ - account3 = _C(exchanges[k].GetAccount); - accountsCache.push(account3); - } - } - var nowStocks = 0.0; - var nowBalance = 0.0; - for(var account4 in accountsCache){ - nowBalance += accountsCache[account4].Balance; - nowStocks += accountsCache[account4].Stocks; - } - var diff = _N(nowStocks-initStocks, 5); - var isReverse; - if(Math.abs(diff) < minAmount){ - LogProfit(_N(nowBalance-initBalance, 3), "all balance", _N(nowBalance), "all stocks", _N(nowStocks), "stock offset:", diff); - lastTradeTime = 0; - } else if(diff > minAmount){ - isReverse = depthA.Bids[0].Price < depthB.Bids[0].Price; - } else if(-diff > minAmount){ - isReverse = depthA.Asks[0].Price > depthB.Asks[0].Price; - } - if(isReverse != null){ - var depths = [depthA, depthB]; - var opAmount; - var kk; - if(isReverse){ - kk = [1, 0]; - } else{ - kk = [0, 1]; - } - for(var pos in kk){ - if(diff > minAmount){ - opAmount = Math.min(diff, accountsCache[pos].Stocks, depths[pos].Bids[0].Amount + depths[pos].Bids[1].Amount); - diff = -opAmount; - if(opAmount >= minAmount){ - exchanges[pos].Sell(depths[pos].Bids[1].Price, opAmount); - } - } else if(-diff >= minAmount){ - opAmount = Math.min(-diff, _N(accountsCache[pos].Balance / depths[pos].Asks[1].Price, 3), depths[pos].Asks[0].Amount + depths[pos].Asks[1].Amount); - diff += opAmount; - if (opAmount >= minAmount){ - exchanges[pos].Buy(depths[pos].Asks[1].Price, opAmount); - } - } - } - if (opAmount != undefined){ - var time1 = new Date(); - lastTradeTime = time1.getTime(); - accountsCache = []; - } - } - continue; - } - var diffA = _N(depthA.Bids[0].Price - depthB.Asks[0].Price, 3) - var diffB = _N(depthB.Bids[0].Price - depthA.Asks[0].Price, 3) - LogStatus(JSON.stringify({type: 'table', title: 'status', cols: ['name', 'money', 'frozenmoney', 'stock', 'frozenstock', 'buyone', 'sellone', 'threshold', 'offset', 'num of times'], rows: [[names[0], accountsCache[0].Balance, accountsCache[0].FrozenBalance, accountsCache[0].Stocks, accountsCache[0].FrozenStocks, depthA.Bids[0].Price, depthA.Asks[0].Price, MinSpreadA, diffA, hedgeNum[0]], [names[1], accountsCache[1].Balance, accountsCache[1].FrozenBalance, accountsCache[1].Stocks, accountsCache[1].FrozenStocks, depthB.Bids[0].Price, depthB.Asks[0].Price, MinSpreadB, diffB, hedgeNum[0]]]})); - HPos = 0; - if (diffA >= MinSpreadA){ - orderH = depthA.Bids[0]; - orderL = depthB.Asks[0]; - exchangeH = 0; - exchangeL = 1; - accountH = accountsCache[0]; - accountL = accountsCache[1]; - } - else if (diffB >= MinSpreadB){ - HPos = 1; - orderH = depthB.Bids[0]; - orderL = depthA.Asks[0]; - exchangeH = 1; - exchangeL = 0; - accountH = accountsCache[1]; - accountL = accountsCache[0]; - } - else{ - continue; - } - - var opPrice = _N((orderH.Price + orderL.Price) / 2.0, 2); - var opAmount = Math.min(MaxAmount, orderH.Amount, orderL.Amount, accountH.Stocks, _N(accountL.Balance / opPrice, 3)); - if(opAmount >= minAmount){ - var tasks = [[exchangeH, "H"], [exchangeL, "L"]]; - if(lastTradeErrExchange == "L"){ - tasks.reverse(); - } - lastTradeErrExchange = ""; - for(var task in tasks){ - if(tasks[task][1] == "H"){ - var id = exchanges[tasks[task][0]].Sell(opPrice, opAmount); - if(id == undefined){ - lastTradeErrExchange = tasks[task][1]; - break; - } - } - if(tasks[task][1] == "L"){ - var id = exchanges[tasks[task][0]].Buy(opPrice, opAmount); - if(id == undefined){ - lastTradeErrExchange = tasks[task][1]; - break; - } - } - } - - var time = new Date(); - lastTradeTime = time.getTime(); - accountsCache = [] - hedgeNum[HPos] += 1 - } - } -} diff --git "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).md" similarity index 93% rename from "\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" rename to "\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).md" index 3de68802..3ee26459 100644 --- "a/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).js" +++ "b/\345\217\214\345\271\263\345\217\260\345\257\271\345\206\262js\347\211\210\346\234\254(two platforms hedging-JS).md" @@ -1,26 +1,38 @@ -/* -策略出处: https://www.fmz.com/strategy/57556 -策略名称: 双平台对冲js版本(two platforms hedging-JS) -策略作者: 7meter -策略描述: +> 策略名称 +双平台对冲js版本(two platforms hedging-JS) +> 策略作者 -参数 默认值 描述 ------------- ------ -------- -MinSpreadA 0.51 A->B差价 -MinSpreadB 0.52 B->A差价 -MaxAmount 0.3 最大操作量 -BalanceTime 10 平衡周期(秒) -LoopInterval 200 轮询周期(ms) +7meter -按钮 默认值 描述 ----- ----- ---------- -A->B 0.51 更改价差(A->B) -B->A 0.52 更改价差(B->A) -*/ + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|MinSpreadA|0.51|A->B差价| +|MinSpreadB|0.52|B->A差价| +|MaxAmount|0.3|最大操作量| +|BalanceTime|10|平衡周期(秒)| +|LoopInterval|200|轮询周期(ms)| + + + + +|按钮|默认值|描述| +|----|----|----| +|A->B|0.51|更改价差(A->B)| +|B->A|0.52|更改价差(B->A)| + + +> 源码 (javascript) + +``` javascript function cancelAll(){ var ref = false; for(var e in exchanges){ @@ -223,3 +235,12 @@ function main(){ } } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/57556 + +> 更新时间 + +2018-01-22 17:42:27 diff --git "a/\345\217\226\346\266\210\346\211\200\346\234\211\350\256\242\345\215\225.js" "b/\345\217\226\346\266\210\346\211\200\346\234\211\350\256\242\345\215\225.md" similarity index 84% rename from "\345\217\226\346\266\210\346\211\200\346\234\211\350\256\242\345\215\225.js" rename to "\345\217\226\346\266\210\346\211\200\346\234\211\350\256\242\345\215\225.md" index 0f397fcf..ae24cfa4 100644 --- "a/\345\217\226\346\266\210\346\211\200\346\234\211\350\256\242\345\215\225.js" +++ "b/\345\217\226\346\266\210\346\211\200\346\234\211\350\256\242\345\215\225.md" @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/280 -策略名称: 取消所有订单 -策略作者: Zero -策略描述: + +> 策略名称 + +取消所有订单 + +> 策略作者 + +Zero + +> 策略描述 取消所有订单 -*/ + +> 源码 (javascript) + +``` javascript var Interval = 1000; function GetAccount(e) { @@ -55,3 +63,12 @@ function main() { cancelPending(exchanges[i]); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/280 + +> 更新时间 + +2014-10-07 21:11:05 diff --git "a/\345\220\204\345\244\247\345\271\263\345\217\260API\345\217\257\347\224\250\347\216\207\347\273\237\350\256\241.js" "b/\345\220\204\345\244\247\345\271\263\345\217\260API\345\217\257\347\224\250\347\216\207\347\273\237\350\256\241.md" similarity index 94% rename from "\345\220\204\345\244\247\345\271\263\345\217\260API\345\217\257\347\224\250\347\216\207\347\273\237\350\256\241.js" rename to "\345\220\204\345\244\247\345\271\263\345\217\260API\345\217\257\347\224\250\347\216\207\347\273\237\350\256\241.md" index 0bf880b6..a70965c7 100644 --- "a/\345\220\204\345\244\247\345\271\263\345\217\260API\345\217\257\347\224\250\347\216\207\347\273\237\350\256\241.js" +++ "b/\345\220\204\345\244\247\345\271\263\345\217\260API\345\217\257\347\224\250\347\216\207\347\273\237\350\256\241.md" @@ -1,23 +1,37 @@ -/* -策略出处: https://www.fmz.com/strategy/4404 -策略名称: 各大平台API可用率统计 -策略作者: Zero -策略描述: + +> 策略名称 + +各大平台API可用率统计 + +> 策略作者 + +Zero + +> 策略描述 支持多个交易所, 多线程, 想学习多线程或者图表的可以学习下这个策略 +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Interval|10|检测频率(秒)| +|TickCount|200|采样数量| -参数 默认值 描述 ---------- ----- ------- -Interval 10 检测频率(秒) -TickCount 200 采样数量 -按钮 默认值 描述 ----- ---------- ---- -清空日志 __button__ 清空日志 -*/ +|按钮|默认值|描述| +|----|----|----| +|清空日志|__button__|清空日志| + + +> 源码 (javascript) + +``` javascript + function _D(t) { if (typeof(t) == 'undefined') { t = new Date(); @@ -248,3 +262,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/4404 + +> 更新时间 + +2016-09-26 09:01:12 diff --git "a/\345\220\210\346\210\220\344\273\273\346\204\217\345\221\250\346\234\237K\347\272\277 \344\275\277\347\224\250\350\257\267\347\234\213\346\272\220\347\240\201\346\234\200\344\270\213\351\235\242.md" "b/\345\220\210\346\210\220\344\273\273\346\204\217\345\221\250\346\234\237K\347\272\277 \344\275\277\347\224\250\350\257\267\347\234\213\346\272\220\347\240\201\346\234\200\344\270\213\351\235\242.md" new file mode 100644 index 00000000..7a6670c3 --- /dev/null +++ "b/\345\220\210\346\210\220\344\273\273\346\204\217\345\221\250\346\234\237K\347\272\277 \344\275\277\347\224\250\350\257\267\347\234\213\346\272\220\347\240\201\346\234\200\344\270\213\351\235\242.md" @@ -0,0 +1,126 @@ + +> 策略名称 + +合成任意周期K线 使用请看源码最下面 + +> 策略作者 + +FawkesPan + + + + + +> 源码 (python) + +``` python +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# encoding: utf-8 +# +# Candlestick merger. +# +# Copyright 2018 FawkesPan +# Contact : i@fawkex.me / Telegram@FawkesPan +# +# Do What the Fuck You Want To Public License +# + +from math import * +from datetime import datetime + +def timeFilter(records, since, to=1000000000000000): + bars = [] + for i in records: + if i['Time'] >= since and i['Time'] <= to: + bars.append(i) + + return bars + +def calcRecords(records, period=30, start=None): + try: + records[0] + except IndexError: + return [] + + period_ms = period * 60000 # 以毫秒记的K线周期 + end_in = records[len(records)-1]['Time'] # K线的结束时间 + start_at = records[0]['Time'] # K线的开始时间 + + # 获得可以用于计算目标K线的开始时间 + r_offest = start_at % period_ms + start_at = start_at - r_offest + period_ms + if start is not None: + start_at = start + + target_count = ceil((end_in-start_at)/period_ms) # 目标K线的数量 + + n_records = [] + + for i in range(0, target_count): + bars = timeFilter(records, start_at+i*period_ms, start_at+(i+1)*period_ms-1000) + try: + bars[0] + except IndexError: + continue + # 初始化新的Bar + Time = bars[0]['Time'] + Open = bars[0]['Open'] + High = bars[0]['High'] + Low = bars[0]['Low'] + Close = bars[0]['Close'] + Volume = 0 + for item in bars: + High = max(High, item['High']) + Low = min(Low, item['Low']) + Close = item['Close'] + Volume+=item['Volume'] + + # 将Bar添加添加到新的K线中 + n_records.append(dict({ + 'Time' : Time, + 'Open' : Open, + 'High' : High, + 'Low' : Low, + 'Close' : Close, + 'Volume' : Volume + })) + + return n_records + +def getRecords(exchange, period=30): + records = exchange.GetRecords(PERIOD_M1) + + return calcRecords(records, period) + +def calcRecordsWithOldRecords(records, old_records, period=30): + try: + start = old_records[len(old_records)-1]['Time'] + del old_records[len(old_records)-1] + except IndexError: + old_records = [] + start = None + + return old_records + calcRecords(records=records, period=period, start=start) + +ext.calcRecords = calcRecords +ext.getRecords = getRecords +ext.calcRecordsWithOldRecords = calcRecordsWithOldRecords + +# Function Test +def main(): + LogReset() + M1 = exchange.GetRecords(PERIOD_M1) + M15 = exchange.GetRecords(PERIOD_M15) + M15_GEN = ext.calcRecords(M1, 15) # 使用ext.calcRecords函数 按照1分钟K线 计算出15分钟K线 + Log(M15[len(M15)-50:]) + Log(M15_GEN[len(M15_GEN)-50:]) +``` + +> 策略出处 + +https://www.fmz.com/strategy/117473 + +> 更新时间 + +2018-09-21 13:24:55 diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247 - \345\275\242\346\200\201\347\255\226\347\225\245\357\274\210\345\242\236\345\274\272\345\236\213\351\224\244\345\255\220\357\274\211.md" "b/\345\225\206\345\223\201\346\234\237\350\264\247 - \345\275\242\346\200\201\347\255\226\347\225\245\357\274\210\345\242\236\345\274\272\345\236\213\351\224\244\345\255\220\357\274\211.md" new file mode 100644 index 00000000..506a3fef --- /dev/null +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247 - \345\275\242\346\200\201\347\255\226\347\225\245\357\274\210\345\242\236\345\274\272\345\236\213\351\224\244\345\255\220\357\274\211.md" @@ -0,0 +1,88 @@ + +> 策略名称 + +商品期货 - 形态策略(增强型锤子) + +> 策略作者 + +Hukybo + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|contractType|rb000/rb888/10,ru000/ru888/1,ZC000/ZC888/5|合约类型| +|maLen|100|指标周期| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2015-06-26 09:00:00 +end: 2018-06-01 15:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","minfee":10,"fee":[0,0]}] +*/ + +function main() { // 主程序 + var contractTypeDic = {}; // 新建一个合约品种对象 + var contractTypeArr1 = contractType.split(","); // 处理合约类型 + var contractTypeArr2 = []; // 新建一个空数组 + for (var i = 0; i < contractTypeArr1.length; i++) { + contractTypeArr2.push(contractTypeArr1[i].split('/')); + } // 批量处理 + for (var key = 0; key < contractTypeArr2.length; key++) { + for (var kay = 0; kay < contractTypeArr2[key].length; kay++) { + contractTypeDic[contractTypeArr2[key][1]] = { + unit: Number(contractTypeArr2[key][2]), + falsePosition: 0 + } + } + } // 批量处理,给合约品种对象添加属性 + var re = /\/\d{1,3}/gm // 正则表达式 + var name = contractType.replace(re, ""); // 处理下单合约名称字符串 + // 调用商品期货交易类库中的CTA框架。参数1:用每个品种的指数数据产生信号,用每个品种的当前主力合约下单。参数2:策略逻辑的回调函数。 + $.CTA(name, function(st) { + var bars = st.records; // 获取K线数组 + if (!bars || bars.length < maLen + 1) { + return; + } // 检测K线数据的长度。如果K线数据过短,则继续等待数据 + var ma = TA.MA(bars, maLen); // 获取移动平均线数组 + var ma1 = ma[ma.length - 2]; // 获取上根K线的移动平均线数据 + var close1 = bars[bars.length - 2].Close; // 获取上根K线的数据 + var longArr = talib.CDLHAMMER(bars) // 调用talib库中的锤子线形态,返回数组 + var shortArr = talib.CDLINVERTEDHAMMER(bars) // 调用talib库中的倒锤子线形态,返回数组 + var long = longArr[longArr.length - 2] // 获取上根K线锤子线形态数据 + var short = shortArr[shortArr.length - 2] // 获取上根K线倒锤子线形态数据 + if (contractTypeDic[st.symbol].falsePosition > 0 && (close1 < ma1 || short > 0)) { + contractTypeDic[st.symbol].falsePosition = 0; + return -contractTypeDic[st.symbol].unit; + } // 平多单 + if (contractTypeDic[st.symbol].falsePosition < 0 && (close1 > ma1 || long > 0)) { + contractTypeDic[st.symbol].falsePosition = 0; + return contractTypeDic[st.symbol].unit; + } // 平空单 + if (contractTypeDic[st.symbol].falsePosition == 0 && close1 > ma1 && long > 0) { + contractTypeDic[st.symbol].falsePosition = 1; + return contractTypeDic[st.symbol].unit; + } // 开多单 + if (contractTypeDic[st.symbol].falsePosition == 0 && close1 < ma1 && short > 0) { + contractTypeDic[st.symbol].falsePosition = -1; + return -contractTypeDic[st.symbol].unit; + } // 开空单 + }); +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/97130 + +> 更新时间 + +2018-06-09 13:00:14 diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\270\273\345\212\233\345\220\210\347\272\246\350\277\207\346\273\244.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\270\273\345\212\233\345\220\210\347\272\246\350\277\207\346\273\244.js" deleted file mode 100644 index dd82415b..00000000 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\270\273\345\212\233\345\220\210\347\272\246\350\277\207\346\273\244.js" +++ /dev/null @@ -1,71 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/9837 -策略名称: 商品期货主力合约过滤 -策略作者: Zero -策略描述: - -可参考API文档里的商品期货扩展函数 - -效果如下: - https://dn-filebox.qbox.me/bb2c0a8754481751eb966b4b08d7564b4dca70f6.png - -*/ - -function main() { - var filter = ['au', 'CF', 'MA']; - var products = []; - Log("等待连接到交易服务器"); - while (!exchange.IO("status")) Sleep(1000); - Log("开始获取所有合约"); - var instruments = _C(exchange.IO, "instruments"); - Log("合约列表获取成功"); - var len = 0; - for (var instrumentId in instruments) { - len++; - } - Log("合约列表长度为:", len); - for (var instrumentId in instruments) { - if (instruments[instrumentId].IsTrading) { - var found = false; - for (var i = 0; i < filter.length; i++) { - if (instruments[instrumentId].ProductID == filter[i]) { - found = true; - } - } - if (!found) { - continue; - } - if (typeof(products[instruments[instrumentId].ProductID]) === 'undefined') { - products[instruments[instrumentId].ProductID] = []; - } - products[instruments[instrumentId].ProductID].push(instrumentId); - } - } - for (var product in products) { - var ss = products[product]; - Log("订阅", product, "的", ss.length, "种合约, 以识别主力合约"); - var vol = 0, - volIdx = 0; - for (var i = 0; i < ss.length; i++) { - _C(exchange.SetContractType, ss[i]); - } - Sleep(5000); - for (var i = 0; i < ss.length; i++) { - _C(exchange.SetContractType, ss[i]); - var ticker = exchange.GetTicker(); - - if (ticker) { - var obj = JSON.parse(exchange.GetRawJSON()); - if (obj.OpenInterest > vol) { - vol = obj.OpenInterest; - volIdx = i; - } - } - } - // 取消订阅行情(之后此合约K线将停止收集), 当然也可以不取消, 这里演示用 - for (var i = 0; i < ss.length; i++) { - _C(exchange.SetContractType, "-" + ss[i]); - } - Log("主力合约为", ss[volIdx], "持仓", vol, '#ff0000'); - } -} diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223(\345\242\236\345\212\240\344\270\213\351\231\220\344\273\267\345\215\225\345\212\237\350\203\275).js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223(\345\242\236\345\212\240\344\270\213\351\231\220\344\273\267\345\215\225\345\212\237\350\203\275).md" similarity index 95% rename from "\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223(\345\242\236\345\212\240\344\270\213\351\231\220\344\273\267\345\215\225\345\212\237\350\203\275).js" rename to "\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223(\345\242\236\345\212\240\344\270\213\351\231\220\344\273\267\345\215\225\345\212\237\350\203\275).md" index 5360a05d..aa5fdc86 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223(\345\242\236\345\212\240\344\270\213\351\231\220\344\273\267\345\215\225\345\212\237\350\203\275).js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223(\345\242\236\345\212\240\344\270\213\351\231\220\344\273\267\345\215\225\345\212\237\350\203\275).md" @@ -1,22 +1,33 @@ -/* -策略出处: https://www.fmz.com/strategy/14198 -策略名称: 商品期货交易类库(增加下限价单功能) -策略作者: edwardgyw -策略描述: + +> 策略名称 + +商品期货交易类库(增加下限价单功能) + +> 策略作者 + +edwardgyw + +> 策略描述 6.24更新,完善了4种夜盘时间类型,周六凌晨的夜盘时间计入交易时段 在原zero提供版本基础上,增加了下限价单和平限价单的功能,方便埋单 增加了判断当前是否是交易时段的功能,同时提供自定义节假日的功能 +> 策略参数 + + -参数 默认值 描述 ------------- ------- ---------- -Interval 500 失败重试间隔(毫秒) -SlidePrice false 下单滑价(元) -nightType true 商品夜盘情况 -holidaysList 5.1,5.2 节假日情况 -*/ +|参数|默认值|描述| +|----|----|----| +|Interval|500|失败重试间隔(毫秒)| +|SlidePrice|false|下单滑价(元)| +|nightType|true|商品夜盘情况| +|holidaysList|5.1,5.2|节假日情况| + +> 源码 (javascript) + +``` javascript function GetPosition(e, contractType, direction) { var allCost = 0; var allAmount = 0; @@ -296,3 +307,12 @@ function main() { LogProfit(p.Profit()); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/14198 + +> 更新时间 + +2016-06-24 16:28:23 diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\227\247\347\211\210\357\274\211.md" similarity index 72% rename from "\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" rename to "\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\227\247\347\211\210\357\274\211.md" index 4cc38b1b..5801867c 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223\357\274\210\346\227\247\347\211\210\357\274\211.md" @@ -1,81 +1,62 @@ -/* -策略出处: https://www.fmz.com/strategy/12961 -策略名称: 商品期货交易类库 -策略作者: Zero -策略描述: -商品期货交易类库 +> 策略名称 +商品期货交易类库(旧版) -> CTA库 -* 实盘会自动把指数映射到主力连续 -* 会自动处理移仓 -* 回测可以指定映射比如 rb000/rb888 就是把rb指数交易映射到主力连续 -* 也可以映射到别的合约, 比如rb000/MA888 就是看rb指数的K线来交易MA主力连续 +> 策略作者 -``` -function main() { - $.CTA("rb000,M000", function(r, mp) { - if (r.length < 20) { - return - } - var emaSlow = TA.EMA(r, 20) - var emaFast = TA.EMA(r, 5) - var cross = $.Cross(emaFast, emaSlow); - if (mp <= 0 && cross > 2) { - Log("金叉周期", cross, "当前持仓", mp); - return 1 - } else if (mp >= 0 && cross < -2) { - Log("死叉周期", cross, "当前持仓", mp); - return -1 - } - }); -} -``` +小小梦 -> 类库调用举例 -``` -function main() { - var p = $.NewPositionManager(); - p.OpenShort("MA609", 1); - p.OpenShort("MA701", 1); - Log(p.GetPosition("MA609", PD_SHORT)); - Log(p.GetAccount()); - Log(p.Account()); - Sleep(60000 * 10); - p.CoverAll("MA609"); - LogProfit(p.Profit()); - Log($.IsTrading("MA609")); - // 多品种时使用交易队列来完成非阻塞的交易任务 - var q = $.NewTaskQueue(); - q.pushTask(exchange, "MA701", "buy", 3, function(task, ret) { - Log(task.desc, ret) - }) - while (true) { - // 在空闲时调用poll来完成未完成的任务 - q.poll() - Sleep(1000) - } -} -``` +> 策略描述 +商品期货交易类库 +``` +function main() { + var p = $.NewPositionManager(); + p.OpenShort("MA609", 1); + p.OpenShort("MA701", 1); + Log(p.GetPosition("MA609", PD_SHORT)); + Log(p.GetAccount()); + Log(p.Account()); + Sleep(60000 * 10); + p.CoverAll("MA609"); + LogProfit(p.Profit()); + Log($.IsTrading("MA609")); + // 多品种时使用交易队列来完成非阻塞的交易任务 + var q = $.NewTaskQueue(); + q.pushTask(exchange, "MA701", "buy", 3, function(task, ret) { + Log(task.desc, ret) + }) + while (true) { + // 在空闲时调用poll来完成未完成的任务 + q.poll() + Sleep(1000) + } +} +``` + +`不断完善中...` + +> 策略参数 -参数 默认值 描述 ---------------- ----- ------------ -Interval 500 失败重试间隔(毫秒) -SlideTick true 滑价点数(整数) -RiskControl false 开启风控 -MaxTrade 100 工作日最多交易交易次数 -MaxTradeAmount 1000 单笔最多下单量 -CTAShowPosition true 在状态栏显示持仓信息 -SyncInterval 5 账户与持仓同步周期(秒) -*/ + +|参数|默认值|描述| +|----|----|----| +|Interval|500|失败重试间隔(毫秒)| +|SlideTick|true|滑价点数(整数)| +|RiskControl|false|开启风控| +|MaxTrade|100|工作日最多交易交易次数| +|MaxTradeAmount|1000|单笔最多下单量| + + +> 源码 (javascript) + +``` javascript /*backtest -start: 2018-01-15 09:00:00 -end: 2018-01-30 00:00:00 +start: 2017-08-01 00:00:00 +end: 2017-10-10 00:00:00 period: 1d -exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] */ var __orderCount = 0 @@ -242,7 +223,7 @@ function Cover(e, contractType, lots) { if (typeof(lots) == 'number' && amountChange >= lots) { break; } - + for (var i = 0; i < positions.length; i++) { if (positions[i].ContractType != contractType) { continue; @@ -360,10 +341,7 @@ function AccountToTable(jsStr, title) { rows: [] }; try { - var files = null; - if (typeof(jsStr) === 'string') { - fields = JSON.parse(jsStr); - } + var fields = JSON.parse(jsStr); for (var k in fields) { if (k == 'AccountID' || k == 'BrokerID') { continue @@ -443,14 +421,14 @@ var PositionManager = (function() { if (positions[i].ContractType.indexOf('&') != -1) { Log("开始平掉", positions[i]); Cover(this.e, positions[i].ContractType) - Sleep(Interval) + Sleep(1000) } } for (var i = 0; i < positions.length; i++) { if (positions[i].ContractType.indexOf('&') == -1) { Log("开始平掉", positions[i]); Cover(this.e, positions[i].ContractType) - Sleep(Interval) + Sleep(1000) } } } @@ -467,19 +445,6 @@ $.NewPositionManager = function(e) { return new PositionManager(e); }; -function ins2product(symbol) { - symbol = symbol.replace('SPD ', '').replace('SP ', ''); - var shortName = ""; - for (var i = 0; i < symbol.length; i++) { - var ch = symbol.charCodeAt(i); - if (ch >= 48 && ch <= 57) { - break; - } - shortName += symbol[i].toUpperCase(); - } - return shortName -} - // Via: http://mt.sohu.com/20160429/n446860150.shtml $.IsTrading = function(symbol) { var now = new Date(); @@ -490,8 +455,15 @@ $.IsTrading = function(symbol) { if (day === 0 || (day === 6 && (hour > 2 || hour == 2 && minute > 30))) { return false; } - var shortName = ins2product(symbol); - var p = null; + symbol = symbol.replace('SPD ', '').replace('SP ', ''); + var p, i, shortName = ""; + for (i = 0; i < symbol.length; i++) { + var ch = symbol.charCodeAt(i); + if (ch >= 48 && ch <= 57) { + break; + } + shortName += symbol[i].toUpperCase(); + } var period = [ [9, 0, 10, 15], @@ -522,7 +494,7 @@ $.IsTrading = function(symbol) { var nperiod = [ [ - ['AU', 'AG', 'sc'], + ['AU', 'AG'], [21, 0, 02, 30] ], [ @@ -538,7 +510,7 @@ $.IsTrading = function(symbol) { [21, 0, 23, 30] ], [ - ['SR', 'CF', 'RM', 'MA', 'TA', 'ZC', 'FG', 'OI'], + ['SR', 'CF', 'RM', 'MA', 'TA', 'ZC', 'FG', 'IO'], [21, 0, 23, 30] ], ]; @@ -596,7 +568,7 @@ $.NewTaskQueue = function(onTaskFinish) { arg: typeof(onFinish) !== 'undefined' ? arg : undefined, onFinish: typeof(onFinish) == 'undefined' ? arg : onFinish } - + switch (task.action) { case "buy": task.desc = task.symbol + " 开多仓, 数量 " + task.amount @@ -693,11 +665,7 @@ $.NewTaskQueue = function(onTaskFinish) { } var remain = task.amount; if (isCover && !pos) { - pos = { - Amount: 0, - Cost: 0, - Price: 0 - } + pos = {Amount:0, Cost: 0, Price: 0} } if (pos) { task.dealAmount = pos.Amount - task.preAmount; @@ -743,13 +711,13 @@ $.NewTaskQueue = function(onTaskFinish) { task.e.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy"); amount = Math.min(amount, depth.Bids[0].Amount) orderId = task.e.Sell(_N(depth.Bids[0].Price - slidePrice, 2), amount, task.symbol, positions[i].Type == PD_LONG ? "平今" : "平昨", 'Bid', depth.Bids[0]); - remain -= amount; } else if (task.action == "closesell" && (positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD)) { task.e.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell"); amount = Math.min(amount, depth.Asks[0].Amount) orderId = task.e.Buy(_N(depth.Asks[0].Price + slidePrice, 2), amount, task.symbol, positions[i].Type == PD_SHORT ? "平今" : "平昨", 'Ask', depth.Asks[0]); - remain -= amount; } + // assume order is success insert + remain -= amount; } } else { if (task.action == "buy") { @@ -780,25 +748,19 @@ $.NewTaskQueue = function(onTaskFinish) { self.poll = function() { var processed = 0 - if (self.tasks.length > 0) { - _.each(self.tasks, function(task) { - if (!task.finished) { - processed++ - self.pollTask(task) - } - }) - if (processed == 0) { - self.tasks = [] + _.each(self.tasks, function(task) { + if (!task.finished) { + processed++ + self.pollTask(task) } + }) + if (processed == 0) { + self.tasks = [] } return processed } self.hasTask = function(symbol) { - if (typeof(symbol) !== 'string') { - return self.tasks.length > 0 - } - for (var i = 0; i < self.tasks.length; i++) { if (self.tasks[i].symbol == symbol && !self.tasks[i].finished) { return true @@ -806,7 +768,7 @@ $.NewTaskQueue = function(onTaskFinish) { } return false } - + self.size = function() { return self.tasks.length } @@ -822,7 +784,7 @@ $.Cross = function(arr1, arr2) { throw "array length not equal"; } var n = 0; - for (var i = arr1.length - 1; i >= 0; i--) { + for (var i = arr1.length-1; i >= 0; i--) { if (typeof(arr1[i]) !== 'number' || typeof(arr2[i]) !== 'number') { break; } @@ -847,132 +809,56 @@ $.Cross = function(arr1, arr2) { onTick(r, mp, symbol): r为K线, mp为当前品种持仓数量, 正数指多仓, 负数指空仓, 0则不持仓, symbol指品种名称 返回值如为n: - n = 0 : 指全部平仓(不管当前持多持空) - n > 0 : 如果当前持多仓,则加n个多仓, 如果当前为空仓则平n个空仓,如果n大于当前持仓, 则反手开多仓 - n < 0 : 如果当前持空仓,则加n个空仓, 如果当前为多仓则平n个多仓,如果-n大于当前持仓, 则反手开空仓 - 无返回值表示什么也不做 + n = 0 : 指全部平仓 + n > 0 : 如果当前持多仓,则加n个多仓, 如果当前为空仓则平n个空仓 + n < 0 : 如果当前持空仓,则加n个空仓, 如果当前为多仓则平n个多仓 */ $.CTA = function(contractType, onTick, interval) { - SetErrorFilter("login|ready|初始化") if (typeof(interval) !== 'number') { interval = 500 } - exchange.IO("mode", 0) - var lastUpdate = 0 var e = exchange var symbols = contractType.split(','); var holds = {} - var tblAccount = {}; - var findChartSymbol = function(ct) { - var product = ins2product(ct) - for (var i = 0; i < symbols.length; i++) { - var tmp = symbols[i].split('/') - if (ins2product(tmp[tmp.length - 1]) == product) { - return tmp[0] - } - } - return null - } - var refreshHold = function(qSize) { - if (typeof(qSize) === 'undefined') { - qSize = 0 - } + var refreshHold = function() { while (!e.IO("status")) { - LogStatus(_D(), "Not connect") - Sleep(1000) + Sleep(5000) } - _.each(symbols, function(ins) { - var tmp = ins.split('/') - if (tmp.length == 2) { - holds[tmp[0]] = { - price: 0, - value: 0, - amount: 0, - profit: 0, - symbol: tmp[1] - } - } else { - holds[ins] = { - price: 0, - value: 0, - amount: 0, - profit: 0, - symbol: ins - } - } + holds[ins] = 0 }); + var total = 0 var positions = _C(e.GetPosition); _.each(positions, function(pos) { - var mapCT = findChartSymbol(pos.ContractType) - if (!mapCT) { - return - } - var hold = holds[mapCT] + var hold = holds[pos.ContractType]; if (typeof(hold) == 'undefined') { return } if (pos.Type == PD_LONG || pos.Type == PD_LONG_YD) { - if (hold.amount < 0 && qSize == 0) { + if (hold < 0) { throw "不能同时持有多仓空仓" } - hold.amount += pos.Amount + hold += pos.Amount } else { - if (hold.amount > 0 && qSize == 0) { + if (hold > 0) { throw "不能同时持有多仓空仓" } - hold.amount -= pos.Amount - } - hold.value += pos.Price * pos.Amount - hold.profit += pos.Profit - if (hold.amount != 0) { - hold.price = _N(hold.value / Math.abs(hold.amount)) + hold -= pos.Amount } + total += pos.Amount + holds[pos.ContractType] = hold }) - var account = _C(exchange.GetAccount) - if (CTAShowPosition) { - var tblPosition = { - type: 'table', - title: '持仓状态', - cols: ['品种', '方向', '均价', '数量', '浮动盈亏'], - rows: [] - }; - _.each(positions, function(pos) { - tblPosition.rows.push([pos.ContractType, ((pos.Type == PD_LONG || pos.Type == PD_LONG_YD) ? '多#0000ff' : '空#ff0000'), pos.Price, pos.Amount, pos.Profit]) - }); - tblAccount = $.AccountToTable(exchange.GetRawJSON(), "资金信息") - LogStatus('`' + JSON.stringify([tblPosition, tblAccount]) + '`\n', '更新于: ' + _D()) - } - lastUpdate = new Date().getTime() - return account + return total } - var account = refreshHold(0) - var q = $.NewTaskQueue(function(task, ret) { - Log("任务结束", task.desc) - account = refreshHold(q.size()) - }) - var mainCache = [] + refreshHold() + var q = $.NewTaskQueue(refreshHold) while (true) { - var ts = new Date().getTime() _.each(symbols, function(ins) { - var ctChart = ins - var ctTrade = ins - var tmp = ins.split('/') - if (tmp.length == 2) { - ctChart = tmp[0] - ctTrade = tmp[1] - } - if (!e.IO("status") || !$.IsTrading(ctChart) || !$.IsTrading(ctTrade) || q.hasTask(ctTrade)) { - return - } - if (typeof(mainCache[ctTrade]) !== 'undefined' && (q.hasTask(mainCache[ctTrade][0]) || q.hasTask(mainCache[ctTrade][0]))) { - // 正在移仓 + if (!e.IO("status") || !$.IsTrading(ins) || q.hasTask(ins)) { return } - - // 先获取行情 - var c = e.SetContractType(ctChart) + var c = e.SetContractType(ins); if (!c) { return } @@ -980,133 +866,49 @@ $.CTA = function(contractType, onTick, interval) { if (!r || r.length == 0) { return } - - // 切换到需要交易的合约上来 - var insDetail = e.SetContractType(ctTrade) - if (!insDetail) { - return - } - var tradeSymbol = insDetail.InstrumentID - // 处理主力合约切换, 指数合约在交易时也默认映射到主力合约上 - if (ctTrade.indexOf('888') !== -1 || ctTrade.indexOf('000') !== -1) { - var preMain = '' - var isSwitch = false - var positions = null; - if (typeof(mainCache[ctTrade]) === 'undefined') { - if (!IsVirtual()) { - Log(ctTrade, "当前主力合约为:", tradeSymbol) - } - positions = e.GetPosition() - if (!positions) { - return - } - var product = ins2product(ctTrade); - _.each(positions, function(p) { - if (ins2product(p.ContractType) == product) { - mainCache[ctTrade] = [p.ContractType, p.ContractType]; - } - }); - } - if (typeof(mainCache[ctTrade]) !== 'undefined' && mainCache[ctTrade][0] != tradeSymbol) { - preMain = mainCache[ctTrade][0] - Log(ctTrade, "主力合约切换为:", tradeSymbol, "之前为:", preMain, "#ff0000") - // 开始切换 - if (!positions) { - positions = e.GetPosition() - if (!positions) { - return - } - } - _.each(positions, function(p) { - if (p.ContractType == preMain) { - var isLong = p.Type == PD_LONG || p.Type == PD_LONG_YD - q.pushTask(e, p.ContractType, (isLong ? "closebuy" : "closesell"), p.Amount, function(task, ret) { - Log("切换合约平仓成功", task.desc, ret) - }) - q.pushTask(e, tradeSymbol, (isLong ? "buy" : "sell"), p.Amount, function(task, ret) { - Log("切换合约开仓成功", task.desc, ret) - }) - isSwitch = true - } - }) - } - mainCache[ctTrade] = [tradeSymbol, preMain] - if (isSwitch) { - // Wait switch compeleted - Log("开始移仓", preMain, "移到", tradeSymbol) - return - } - } - - var hold = holds[ctChart]; - var n = onTick({ - records: r, - symbol: tradeSymbol, - detail: insDetail, - account: account, - position: hold, - positions: holds - }) - var callBack = null - if (typeof(n) == 'object' && typeof(n.length) == 'number' && n.length > 1) { - if (typeof(n[1]) == 'function') { - callBack = n[1] - } - n = n[0] - } + var hold = holds[ins]; + var n = onTick(r, hold, ins) if (typeof(n) !== 'number') { return } var ret = null if (n > 0) { - if (hold.amount < 0) { - q.pushTask(e, tradeSymbol, 'closesell', Math.min(-hold.amount, n), callBack) - n += hold.amount - } - if (n > 0) { - q.pushTask(e, tradeSymbol, 'buy', n, callBack) + if (hold < 0) { + q.pushTask(e, ins, 'closesell', n) + } else { + q.pushTask(e, ins, 'buy', n) } } else if (n < 0) { - if (hold.amount > 0) { - q.pushTask(e, tradeSymbol, 'closebuy', Math.min(hold.amount, -n), callBack) - n += hold.amount - } - if (n < 0) { - q.pushTask(e, tradeSymbol, 'sell', -n, callBack) + if (hold > 0) { + q.pushTask(e, ins, 'closebuy', -n) + } else { + q.pushTask(e, ins, 'sell', -n) } - } else if (n == 0 && hold.amount != 0) { - q.pushTask(e, tradeSymbol, (hold.amount > 0 ? 'closebuy' : 'closesell'), Math.abs(hold.amount), callBack) + } else if (n == 0 && hold != 0) { + q.pushTask(e, ins, (hold > 0 ? 'closebuy' : 'closesell'), Math.abs(hold)) } }) q.poll() - - var now = new Date().getTime() - if ((now - lastUpdate) > (SyncInterval * 1000)) { - account = refreshHold(q.size()) - } - var delay = interval - (now - ts) - if (delay > 0) { - Sleep(delay) - } + Sleep(interval) } } + function main() { - // CTA策略框架例子 MA000/rb888 指K线信息看MA000, 下单映射到MA888主力连续上 - $.CTA("MA000/MA888", function(st) { - if (st.records.length < 20) { + // CTA策略框架例子 + $.CTA("rb1801,MA801", function(r, mp, symbol) { + if (r.length < 20) { return } - var emaSlow = TA.EMA(st.records, 20) - var emaFast = TA.EMA(st.records, 5) + var emaSlow = TA.EMA(r, 20) + var emaFast = TA.EMA(r, 5) var cross = $.Cross(emaFast, emaSlow); - LogStatus('可用保证金:', st.account.Balance) - if (st.position.amount <= 0 && cross > 2) { - Log("金叉周期", cross, "当前持仓", st.position); - return st.position.amount < 0 ? 2 : 1 - } else if (st.position.amount >= 0 && cross < -2) { - Log("死叉周期", cross, "当前持仓", st.position); - return st.position.amount > 0 ? -2 : -1 + if (mp <= 0 && cross > 2) { + Log(symbol, "金叉周期", cross, "当前持仓", mp); + return 1 + } else if (mp >= 0 && cross < -2) { + Log(symbol, "死叉周期", cross, "当前持仓", mp); + return -1 } }); @@ -1138,3 +940,12 @@ function main() { } */ } +``` + +> 策略出处 + +https://www.fmz.com/strategy/127341 + +> 更新时间 + +2018-11-24 18:10:21 diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.md" similarity index 93% rename from "\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.js" rename to "\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.md" index 14b154c6..a7c73526 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\346\237\245\347\234\213\350\264\246\346\210\267\350\257\246\347\273\206\344\277\241\346\201\257.md" @@ -1,13 +1,19 @@ -/* -策略出处: https://www.fmz.com/strategy/37793 -策略名称: 商品期货查看账户详细信息 -策略作者: Zero -策略描述: +> 策略名称 +商品期货查看账户详细信息 -*/ +> 策略作者 +Zero + + + + + +> 源码 (javascript) + +``` javascript var trans = { "AccountID": "投资者帐号", "Available": "可用资金", @@ -96,3 +102,12 @@ function main() { Log("已经在状态栏以表格形式显示", rights) } +``` + +> 策略出处 + +https://www.fmz.com/strategy/37793 + +> 更新时间 + +2017-04-25 11:08:57 diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\347\273\223\347\256\227\345\215\225\345\271\263\344\273\223\347\233\210\344\272\217\345\216\206\345\217\262\346\237\245\350\257\242.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\347\273\223\347\256\227\345\215\225\345\271\263\344\273\223\347\233\210\344\272\217\345\216\206\345\217\262\346\237\245\350\257\242.md" similarity index 84% rename from "\345\225\206\345\223\201\346\234\237\350\264\247\347\273\223\347\256\227\345\215\225\345\271\263\344\273\223\347\233\210\344\272\217\345\216\206\345\217\262\346\237\245\350\257\242.js" rename to "\345\225\206\345\223\201\346\234\237\350\264\247\347\273\223\347\256\227\345\215\225\345\271\263\344\273\223\347\233\210\344\272\217\345\216\206\345\217\262\346\237\245\350\257\242.md" index e5726895..0677dd28 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\347\273\223\347\256\227\345\215\225\345\271\263\344\273\223\347\233\210\344\272\217\345\216\206\345\217\262\346\237\245\350\257\242.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\347\273\223\347\256\227\345\215\225\345\271\263\344\273\223\347\233\210\344\272\217\345\216\206\345\217\262\346\237\245\350\257\242.md" @@ -1,18 +1,29 @@ -/* -策略出处: https://www.fmz.com/strategy/38083 -策略名称: 商品期货结算单平仓盈亏历史查询 -策略作者: Zero -策略描述: + +> 策略名称 + +商品期货结算单平仓盈亏历史查询 + +> 策略作者 + +Zero + +> 策略描述 需要更新最新的托管者, 不支持回测, 只支持实盘 +> 策略参数 + + -参数 默认值 描述 ---------- ---------- ---- -StartDate 2017-03-15 开始日期 -EndDate 2017-03-17 结束日期 -*/ +|参数|默认值|描述| +|----|----|----| +|StartDate|2017-03-15|开始日期| +|EndDate|2017-03-17|结束日期| + +> 源码 (javascript) + +``` javascript function main() { var cfg = { tooltip: { @@ -74,3 +85,12 @@ function main() { } Log("查询完成, 总平仓盈亏:", _N(AllProfit), "总手续费:", _N(AllCommission)); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/38083 + +> 更新时间 + +2017-03-17 13:28:18 diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" similarity index 95% rename from "\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.js" rename to "\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" index e960e0ff..3cae1a53 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" @@ -1,13 +1,19 @@ -/* -策略出处: https://www.fmz.com/strategy/79351 -策略名称: 商品期货跟单系统 -策略作者: Hukybo -策略描述: +> 策略名称 +商品期货跟单系统 -*/ +> 策略作者 +Hukybo + + + + + +> 源码 (javascript) + +``` javascript var arr = []; //下单 @@ -136,3 +142,12 @@ function main() { Sleep(100); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/79351 + +> 更新时间 + +2018-07-02 20:59:56 diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \345\215\225\345\223\201\347\247\215\345\245\227\345\210\251\345\220\210\347\272\246.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \345\215\225\345\223\201\347\247\215\345\245\227\345\210\251\345\220\210\347\272\246.md" similarity index 80% rename from "\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \345\215\225\345\223\201\347\247\215\345\245\227\345\210\251\345\220\210\347\272\246.js" rename to "\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \345\215\225\345\223\201\347\247\215\345\245\227\345\210\251\345\220\210\347\272\246.md" index cb424231..66e71a67 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \345\215\225\345\223\201\347\247\215\345\245\227\345\210\251\345\220\210\347\272\246.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \345\215\225\345\223\201\347\247\215\345\245\227\345\210\251\345\220\210\347\272\246.md" @@ -1,30 +1,44 @@ -/* -策略出处: https://www.fmz.com/strategy/27122 -策略名称: 商品期货跨期对冲 - 单品种套利合约 -策略作者: Zero -策略描述: + +> 策略名称 + +商品期货跨期对冲 - 单品种套利合约 + +> 策略作者 + +Zero + +> 策略描述 使用套利合约进行对冲优点是双向开仓速度快, 滑点少, 策略实盘测试通过. +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Symbol|SPD MA705&MA709|套利合约| +|HedgeSpread|15|正溢价开仓价差| +|CoverSpread|5|正溢价平仓价差| +|RHedgeSpread|2|负溢价开仓价差| +|RCoverSpread|10|负溢价平仓价差| +|OpAmount|true|开仓手数| +|CoverAll|false|启动时平掉所有仓位| +|Reset|false|启动时重置所有信息| +|AutoRestore|true|启动时自动恢复仓位| -参数 默认值 描述 ------------- --------------- --------- -Symbol SPD MA705&MA709 套利合约 -HedgeSpread 15 正溢价开仓价差 -CoverSpread 5 正溢价平仓价差 -RHedgeSpread 2 负溢价开仓价差 -RCoverSpread 10 负溢价平仓价差 -OpAmount true 开仓手数 -CoverAll false 启动时平掉所有仓位 -Reset false 启动时重置所有信息 -AutoRestore true 启动时自动恢复仓位 -按钮 默认值 描述 --------- ---------- ------ -CoverALL __button__ 平掉所有仓位 -*/ +|按钮|默认值|描述| +|----|----|----| +|CoverALL|__button__|平掉所有仓位| + + +> 源码 (javascript) + +``` javascript + function Hedge(q, e, initAccount, symbol, hedgeSpread, coverSpread, rHedgeSpread, rCoverSpread) { var self = {} self.q = q @@ -86,17 +100,17 @@ function Hedge(q, e, initAccount, symbol, hedgeSpread, coverSpread, rHedgeSpread var action = 0; // 1: A sell B buy 2: A buy B sell if (self.status == 0) { - if (ticker.Sell >= self.hedgeSpread) { + if (ticker.Buy >= self.hedgeSpread) { Log("开仓 ", self.pairA, "卖", self.pairB, "买", ticker.Buy, '#ff0000') action = 2 - } else if (ticker.Buy <= self.rHedgeSpread) { - Log("开仓 ", self.pairA, "买", self.pairB, "卖", ticker.Buy, '#ff0000') + } else if (ticker.Sell <= self.rHedgeSpread) { + Log("开仓 ", self.pairA, "买", self.pairB, "卖", ticker.Sell, '#ff0000') action = 1 } - } else if (self.status == 2 && ticker.Buy <= self.coverSpread) { + } else if (self.status == 2 && ticker.Sell <= self.coverSpread) { Log("平仓", self.pairA, "买", self.pairB, "卖", ticker.Sell, '#ff0000') action = 2 - } else if (self.status == 1 && ticker.Sell >= self.rCoverSpread) { + } else if (self.status == 1 && ticker.Buy >= self.rCoverSpread) { Log("平仓", self.pairA, "卖", self.pairB, "买",ticker.Buy, '#ff0000') action = 1 } @@ -152,7 +166,7 @@ function main() { $.NewPositionManager().CoverAll(); Log("操作完成"); } - var t = Hedge(q, exchanges[0], initAccount, Symbol, HedgeSpread, CoverSpread) + var t = Hedge(q, exchanges[0], initAccount, Symbol, HedgeSpread, CoverSpread, RHedgeSpread, RCoverSpread) if (AutoRestore) { t.init(); } @@ -167,3 +181,12 @@ function main() { t.poll() } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/27122 + +> 更新时间 + +2018-07-17 19:08:40 diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \347\231\276\350\241\214\344\273\243\347\240\201\345\256\236\347\216\260.js" "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \347\231\276\350\241\214\344\273\243\347\240\201\345\256\236\347\216\260.md" similarity index 88% rename from "\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \347\231\276\350\241\214\344\273\243\347\240\201\345\256\236\347\216\260.js" rename to "\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \347\231\276\350\241\214\344\273\243\347\240\201\345\256\236\347\216\260.md" index 63236e70..3919c63d 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \347\231\276\350\241\214\344\273\243\347\240\201\345\256\236\347\216\260.js" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262 - \347\231\276\350\241\214\344\273\243\347\240\201\345\256\236\347\216\260.md" @@ -1,24 +1,35 @@ -/* -策略出处: https://www.fmz.com/strategy/23896 -策略名称: 商品期货跨期对冲 - 百行代码实现 -策略作者: Zero -策略描述: + +> 策略名称 + +商品期货跨期对冲 - 百行代码实现 + +> 策略作者 + +Zero + +> 策略描述 简单的跨期对冲, 抛砖引玉, 细节还需要处理, 轮训间隔可以缩小到1秒或者删除Sleep那行策略就可以随时响应价格变化 +> 策略参数 + + -参数 默认值 描述 ------------- ----- --------- -SA MA701 合约A -SB MA705 合约B -HedgeSpread 30 开仓价差 -CoverSpread 10 平仓价差 -LoopInterval 6 轮询间隔(秒) -OpAmount true 开仓手数 -CoverAll false 启动时平掉所有仓位 -*/ +|参数|默认值|描述| +|----|----|----| +|SA|MA701|合约A| +|SB|MA705|合约B| +|HedgeSpread|30|开仓价差| +|CoverSpread|10|平仓价差| +|LoopInterval|6|轮询间隔(秒)| +|OpAmount|true|开仓手数| +|CoverAll|false|启动时平掉所有仓位| +> 源码 (javascript) + +``` javascript + function Hedge(q, e, initAccount, symbolA, symbolB, hedgeSpread, coverSpread) { var self = {} self.q = q @@ -126,3 +137,12 @@ function main() { t.poll() } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/23896 + +> 更新时间 + +2016-12-09 16:56:24 diff --git "a/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.py" "b/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.md" similarity index 84% rename from "\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.py" rename to "\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.md" index 169ae26c..a9ad7d32 100644 --- "a/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.py" +++ "b/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.md" @@ -1,13 +1,19 @@ -''' -策略出处: https://www.fmz.com/strategy/61867 -策略名称: 回测保存K线到本地CSV -策略作者: botvsing -策略描述: + +> 策略名称 + +回测保存K线到本地CSV + +> 策略作者 + +botvsing -''' + +> 源码 (python) + +``` python ''' /*backtest start: 2017-10-01 @@ -44,3 +50,12 @@ def main(): #休眠时间是选择周期 Sleep(15*60*1000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/61867 + +> 更新时间 + +2017-12-15 13:31:31 diff --git "a/\345\233\276\350\241\250\346\250\241\346\235\277\357\274\210\345\242\236\345\212\240\347\212\266\346\200\201\346\240\217\350\241\250\346\240\274\357\274\211.md" "b/\345\233\276\350\241\250\346\250\241\346\235\277\357\274\210\345\242\236\345\212\240\347\212\266\346\200\201\346\240\217\350\241\250\346\240\274\357\274\211.md" new file mode 100644 index 00000000..3f5b4ad8 --- /dev/null +++ "b/\345\233\276\350\241\250\346\250\241\346\235\277\357\274\210\345\242\236\345\212\240\347\212\266\346\200\201\346\240\217\350\241\250\346\240\274\357\274\211.md" @@ -0,0 +1,368 @@ + +> 策略名称 + +图表模板(增加状态栏表格) + +> 策略作者 + +小小梦 + +> 策略描述 + +图表模板 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|indicatorsName|指标轴1|指标轴| +|indicators_1|指标1|指标1| +|indicators_2|指标2|指标2| +|indicators_3|指标3|指标3| +|Interval|500|间隔(毫秒)| +|isOpenRightY|true|是否开启右边Y轴| +|lineType|line|指标线类型| + + +> 源码 (javascript) + +``` javascript +/* +这个是一个图表模板,详细用法见广场帖子。 +*/ +//----------------------------------图表模块---------------------------------------------------------------- +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: isOpenRightY //生成右边Y轴 ceshi + } + ], + series: [//系列 + {type:'candlestick',yAxis:0,name:'K',id:'KLine',data:[]}, + {type:'flags',onSeries:'KLine',data:[]}, + {name:indicators_1,type:lineType,yAxis:isOpenRightY?1:0,data:[]}, + {name:indicators_2,type:lineType,yAxis:isOpenRightY?1:0,data:[]}, + {name:indicators_3,type:lineType,yAxis:isOpenRightY?1:0,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 lastRecordsTime = 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,message){ + var msg = ""; + var fcolor = ""; // ceshi + var strState = "";//ceshi + msg = "均价:"+price+"币数:"+amount; + switch(state){ + case 3:strState = "自定义信息";fcolor = "black";msg = message;break; + 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}); +} +//----------------------------------图表模块over------------------------------------------------------------ +//----------------------------------状态栏表格模块----------------------------------------------------------- +var TV = null; //表格对象,控制表格内容。 +var objTable = null;//用于显示表格的对象。 +function CreateObjectString(cols,rows){ + var i = cols;// column 列 + var j = rows;// row 行 + var firstCols = 'a'; + var charValue = 0; + var firstName = ""; //对象字符串成员的字母部分 + var lastName = ""; //对象字符串成员的数字部分 + var strMember = ""; //对象字符串成员 + var objStr = "";//返回的字符串 + if(i > 26){ + throw "ERROR column must less 26"; + } + var strHead = '{'; + var strEnd = '}'; + for(var n = 0 ; n < j; n++){ + //处理行 + for(var m = 0 ; m < i; m++){ + //处理列 处理 abc , 数字=n + charValue = firstCols.charCodeAt();//取字符的编码 + firstName = String.fromCharCode(charValue + m); + lastName = n; + if(n === j - 1 && m === i - 1 ){ + strMember = '"' + firstName + lastName + '"' + ':' + '""'; + }else{ + strMember = '"' + firstName + lastName + '"' + ':' + '""' + ','; + } + objStr += strMember; + } + } + objStr = strHead + objStr + strEnd; + return objStr; +} + +var g_cols = 0; +var g_rows = 0; +$.TableInit = function(cols,rows){ + g_cols = cols; + g_rows = rows; + var str = CreateObjectString(cols,rows);//生成 TV对象 字符串 + TV = JSON.parse(str); // 解析字符串生成 TV对象 + var tableString = CreateTableString(cols,rows);//生成表格对象字符串 + objTable = JSON.parse(tableString);//解析表格对象字符串 + LogStatus("当前时间:" + (new Date()) + "\n" + "`" + JSON.stringify(objTable) + "`");//初次显示 表格对象到 状态栏 + //ConnectDate(cols,rows);//初次链接数据 + return TV;//返回 TV对象 +}; +function ConnectDate(cols,rows){//关联函数 + //处理cols + var i = 0;//控制 objTable.cols + for(var unit1 in TV){ + if(i < cols){ + objTable.cols[i] = TV[unit1]; + }else{ + break; + } + i++; + } + //处理rows + var m = 0;//m控制 第几行 + var n = 0;//n控制 第几个 + var o = 1;//跳过cols 部分的计数 + for(var unit2 in TV){ + if( o <= cols){ + o++; + continue; + } + if(n >= cols){ + n = 0; + m++; + } + objTable.rows[m][n] = TV[unit2]; + n++; + } +} +function CreateTableString(cols,rows){ + var strHead = '{'; + var strEnd = '}'; + var srtTable_type = ' "type": "table",'; + var strTable_title = ' "title": "运行信息",'; + var strTable_cols_begin = ' "cols" : ['; + var strTable_cols_end = '],'; + var strTable_rows_begin = ' "rows" : ['; + var strTable_rows_end = ']'; + var strCols = ""; + + var length = 0; + for(var y in TV){// 获得 TV对象的 成员个数 + length++; + } + + var i = 1; + for(var x in TV){// 初始化 strCols + if(i >= cols){ + strCols += '"' + "TV." + x + '"' ; + break; + }else{ + strCols += '"' + "TV." + x + '"' + ','; + } + i++; + } + + i = 1;//控制循环 一行cols 后重置的计数 + var n = 1; //用于最后一次 不加 都好的 计数 + var m = 1; //用于跳过cols 部分的计数 + var strRowsUnit = ""; + var strRows = ""; + length = length - cols; + for(var z in TV){ + if(m <= cols){//跳过 表格cols 部分 + m++; + continue; + } + + if(i >= cols){ + strRowsUnit += '"' + "TV." + z + '"' ; + i = 1;//重置i + if(n < length){ + strRowsUnit = '[' + strRowsUnit + ']' + ','; + }else if(n === length){ + strRowsUnit = '[' + strRowsUnit + ']'; + } + strRows += strRowsUnit; + strRowsUnit = "";//重置 + }else{ + strRowsUnit += '"' + "TV." + z + '"' + ','; + i++; + } + n++; + } + var tableString = strHead + srtTable_type + strTable_title + strTable_cols_begin + strCols + strTable_cols_end + strTable_rows_begin + strRows + strTable_rows_end + strEnd; + return tableString; +} +$.UpDateLogStatus = function(msg) { //更新状态栏 + //列用ABC表示,行用0123表示 + ConnectDate(g_cols,g_rows);//链接数据 + LogStatus("当前时间:" + (new Date()) + "msg:" + msg + "\n" + "`" + JSON.stringify(objTable) + "`");//更新状态栏 +}; +//----------------------------------状态栏表格模块over------------------------------------------------------- +//----------------------------------导出函数---------------------------------------------------------------- +$.SignOP = function(time,price,amount,state,message){//该函数作用是在策略运行时,在K线图表上标记“开多仓”,“开空仓”,“平仓” 的位置。 + //参数time: 在策略中使用此函数的时间,一般用(new Date()).getTime() , price:这个参数是在标签上显示 价格(多空平), amount:这个参数是在标签上显示 数量(成交) ,state: 这个参数是用来控制标记的类型,state = 1开多 ,2开空 ,0 平仓 + if(arguments.length < 4){ + Log("SignOP 函数 必须传入4个参数 : time、price、amount、state"); + return; + } + if(typeof(message) === "undefined"){ + message = ""; + } + SignOP(time,price,amount,state,message); +}; +$.Draw = function(records){ + Draw(records); +}; +$.AddZhiBiao = function(zhibiao_Array,records,index){//该函数是在图表上添加指标线,zhibiao_Array:这个参数是指标数据(数组),records:产生指标数据的 原始K线数据,index:指标线的编号,从1开始递增 + if(records[records.length - 1].Time === lastRecordsTime){ + chart.add([index+1,[records[records.length - 1].Time,zhibiao_Array[zhibiao_Array.length - 1]],-1]); + }else{ + chart.add([index+1,[records[records.length - 2].Time,zhibiao_Array[zhibiao_Array.length - 2]],-1]); + chart.add([index+1,[records[records.length - 1].Time,zhibiao_Array[zhibiao_Array.length - 1]]]); + //lastRecordsTime = records[records.length - 1].Time; //测试 取消 + } + //chart.update(ChartObj); //测试取消 +}; +$.UpDateChart = function(records){//更新图表,每次添加指标线,添加标签 后需要更新 才有效。 records: K线原始数据 + if(records[records.length - 1].Time !== lastRecordsTime){ + lastRecordsTime = records[records.length - 1].Time; + } + chart.update(ChartObj); + chart.reset(500);//默认 保留500个K线 +}; +//----------------------------------导出函数over----------------------------------------------------------- +//测试 +function main(){ + ///*测试图表功能 + var i = 0; + var records = exchange.GetRecords(); + while(!records || records.length < 5){ + records = exchange.GetRecords(); + Sleep(500); + } + var zhibiao = [1,2,3,5,6,4,1,21,5];//ceshi + var zhibiao2 = [11,22,44,57,8,77,5]; + + //$.SignOP((new Date()).getTime(),null,null,3,"自定义信息标记到图表上");// 测试标记 自定义信息 到图表上 + while(i < 500){ + Draw(records); + if(i===20){ + //Sleep(60*60*1000); + SignOP((new Date()).getTime(),2900,1,1); + $.SignOP((new Date()).getTime(),null,null,3,"自定义信息标记到图表上");// 测试标记 自定义信息 到图表上 + } + //zhibiao.shift(); + //zhibiao.push(zhibiao[zhibiao.length - 1] + 1);//ceshi + //Log("ceshi"); //ceshi + $.AddZhiBiao(zhibiao,records,1); + //$.AddZhiBiao(zhibiao2,records,2); + //Log("ceshi"); //ceshi + + //Draw(records); + //Log("ceshi1"); //ceshi + Sleep(200); + records = exchange.GetRecords(); + $.UpDateChart(records);//更新图表 + i++; + } + //*/ + /*测试状态栏表格功能*/ + var cols = 6;//列 设置一个变量 代表 列 + var rows = 4;//行 设置一个变量 代表 行 + $.TableInit(cols,rows); //初始化 状态栏 会显示 各个单元格的 坐标 + ///* + for(var x in TV){ + TV[x] = "lalala";// 全部单元格写成 lalala + } + //更新表格 显示 lalala, 表头 数据不能重复 ,否则显示不出来。 + /* + TV.a0 = "a0"; + TV.b0 = "b0"; + TV.c0 = "c0"; + TV.d0 = "d0"; + TV.e0 = "e0"; + TV.f0 = "f0";//先把 表头数据写成不一样的 + */ + $.UpDateLogStatus(cols,rows);//更新 状态栏表格 + + ///* + //怎么在 表格里面写入数据呢? + var num = 100; + var text = "文本:测试表格文本"; + var obj = {name:"对象",age:"19",sex:"girl"}; + var array = ["数组",22,33,54]; + TV.a1 = num; + TV.c2 = text; + TV.b3 = obj; + TV.b0 = array; + + $.UpDateLogStatus(cols,rows);//再次更新 状态栏表格 + //*/ +} +/*修改 +1、增加了是否开启右边坐标轴 +2、增加参数 lineType : spline / line +*/ +``` + +> 策略出处 + +https://www.fmz.com/strategy/20967 + +> 更新时间 + +2018-06-05 11:52:32 diff --git "a/\345\233\276\350\241\250\347\225\214\351\235\242\344\277\241\346\201\257\345\261\225\347\244\272\345\256\236\344\276\2131.js" "b/\345\233\276\350\241\250\347\225\214\351\235\242\344\277\241\346\201\257\345\261\225\347\244\272\345\256\236\344\276\2131.md" similarity index 93% rename from "\345\233\276\350\241\250\347\225\214\351\235\242\344\277\241\346\201\257\345\261\225\347\244\272\345\256\236\344\276\2131.js" rename to "\345\233\276\350\241\250\347\225\214\351\235\242\344\277\241\346\201\257\345\261\225\347\244\272\345\256\236\344\276\2131.md" index acbaabfb..20b7d381 100644 --- "a/\345\233\276\350\241\250\347\225\214\351\235\242\344\277\241\346\201\257\345\261\225\347\244\272\345\256\236\344\276\2131.js" +++ "b/\345\233\276\350\241\250\347\225\214\351\235\242\344\277\241\346\201\257\345\261\225\347\244\272\345\256\236\344\276\2131.md" @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/36026 -策略名称: 图表界面信息展示实例1 -策略作者: 太极 -策略描述: + +> 策略名称 + +图表界面信息展示实例1 + +> 策略作者 + +太极 + +> 策略描述 11111111 -*/ + +> 源码 (javascript) + +``` javascript //========================================== //API: Chart 函数使用的简单例子(画图功能) var chart = { // 这个 chart 在JS 语言中 是对象, 在使用Chart 函数之前我们需要声明一个配置图表的对象变量chart。 @@ -70,3 +78,12 @@ function main() { } +``` + +> 策略出处 + +https://www.fmz.com/strategy/36026 + +> 更新时间 + +2017-02-18 15:29:31 diff --git "a/\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2.py" "b/\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2.md" similarity index 82% rename from "\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2.py" rename to "\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2.md" index 7cf46c82..08808119 100644 --- "a/\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2.py" +++ "b/\345\235\207\347\272\277-\350\266\213\345\212\277_\346\225\260\345\255\227\350\264\247\345\270\201\347\255\226\347\225\245V0.2.md" @@ -1,31 +1,42 @@ -''' -策略出处: https://www.fmz.com/strategy/21369 -策略名称: 均线-趋势_数字货币策略V0.2 -策略作者: 太极 -策略描述: + +> 策略名称 + +均线-趋势_数字货币策略V0.2 + +> 策略作者 + +太极 + +> 策略描述 @太极 QQ7650371 #均线/趋势 策略 #通过判断 在死叉下底后回弹多少买入 #在金叉上扬至顶后下降多少卖出 +> 策略参数 + + -参数 默认值 描述 --------------- ------------------------------------------------------------------------------ ------------------ -FastPeriod 2 开仓快线周期 -SlowPeriod 4 开仓慢线周期 -EnterPeriod true 开仓观察期 -x ------------------------------------------------------------------------------ 分割符号 -ExitFastPeriod 2 平仓快线周期 -ExitSlowPeriod 4 平仓慢线周期 -ExitPeriod 2 平仓观察期 -xx ------------------------------------------------------------------------------ 分割符号 -PositionRatio 0.5 仓位比例 -Interval 10 轮询周期(秒) -xxx ------------------------------------------------------------------------------ 分割符号 -MAType 0 均线类型: TA.EMA|TA.MA -''' +|参数|默认值|描述| +|----|----|----| +|FastPeriod|2|开仓快线周期| +|SlowPeriod|4|开仓慢线周期| +|EnterPeriod|true|开仓观察期| +|x|------------------------------------------------------------------------------|分割符号| +|ExitFastPeriod|2|平仓快线周期| +|ExitSlowPeriod|4|平仓慢线周期| +|ExitPeriod|2|平仓观察期| +|xx|------------------------------------------------------------------------------|分割符号| +|PositionRatio|0.5|仓位比例| +|Interval|10|轮询周期(秒)| +|xxx|------------------------------------------------------------------------------|分割符号| +|MAType|0|均线类型: TA.EMA|TA.MA| + +> 源码 (python) + +``` python #!/usr/local/bin/python #-*- coding: UTF-8 -*- #均线/趋势 策略 @@ -234,3 +245,12 @@ def main(): Sleep(Interval * 1000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/21369 + +> 更新时间 + +2016-09-19 18:05:01 diff --git "a/\345\235\207\347\272\277\347\255\226\347\225\245 30 \350\241\214\346\220\236\345\256\232.js" "b/\345\235\207\347\272\277\347\255\226\347\225\245 30 \350\241\214\346\220\236\345\256\232.js" deleted file mode 100644 index f8d7145b..00000000 --- "a/\345\235\207\347\272\277\347\255\226\347\225\245 30 \350\241\214\346\220\236\345\256\232.js" +++ /dev/null @@ -1,60 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/12348 -策略名称: 均线策略 30 行搞定 -策略作者: Zero -策略描述: - -"Talk is cheap. Show me the code" - -教学性质, 实盘慎用. - - -注: ` 策略使用了交易模板类库` - -`希望新手从此策略入门, 一步步学习编写策略, 并体验到模拟与真实环境对交易系统的影响` - -https://dn-filebox.qbox.me/fb4d0c7d773ca83e9d0230927705d419dc0bbeaa.png - - -参数 默认值 描述 --------------- ----- ------- -FastPeriod 5 入市快线周期 -SlowPeriod 15 入市慢线周期 -EnterPeriod 2 入市观察期 -ExitFastPeriod 7 离市快线周期 -ExitSlowPeriod 15 离市慢线周期 -ExitPeriod true 离市观察期 -PositionRatio 0.8 仓位比例 -Interval 10 轮询周期(秒) -*/ - -function main() { - var STATE_IDLE = -1; - var state = STATE_IDLE; - var initAccount = $.GetAccount(); - Log(initAccount); - while (true) { - if (state === STATE_IDLE) { - var n = $.Cross(FastPeriod, SlowPeriod); - if (Math.abs(n) >= EnterPeriod) { - var opAmount = parseFloat((initAccount.Stocks * PositionRatio).toFixed(3)); - var obj = n > 0 ? $.Buy(opAmount) : $.Sell(opAmount); - if (obj) { - opAmount = obj.amount; - state = n > 0 ? PD_LONG : PD_SHORT; - Log("开仓详情", obj, "交叉周期", n); - } - } - } else { - var n = $.Cross(ExitFastPeriod, ExitSlowPeriod); - if (Math.abs(n) >= ExitPeriod && ((state === PD_LONG && n < 0) || (state === PD_SHORT && n > 0))) { - var nowAccount = $.GetAccount(); - var obj = state === PD_LONG ? $.Sell(nowAccount.Stocks - initAccount.Stocks) : $.Buy(initAccount.Stocks - nowAccount.Stocks); - state = STATE_IDLE; - nowAccount = $.GetAccount(); - LogProfit(nowAccount.Balance - initAccount.Balance, '钱:', nowAccount.Balance, '币:', nowAccount.Stocks, '平仓详情:', obj, "交叉周期", n); - } - } - Sleep(Interval*1000); - } -} diff --git "a/\345\235\207\347\272\277\347\255\226\347\225\245\357\274\210python\347\211\210\357\274\211.py" "b/\345\235\207\347\272\277\347\255\226\347\225\245\357\274\210python\347\211\210\357\274\211.md" similarity index 71% rename from "\345\235\207\347\272\277\347\255\226\347\225\245\357\274\210python\347\211\210\357\274\211.py" rename to "\345\235\207\347\272\277\347\255\226\347\225\245\357\274\210python\347\211\210\357\274\211.md" index 4e5c4745..ec8e6641 100644 --- "a/\345\235\207\347\272\277\347\255\226\347\225\245\357\274\210python\347\211\210\357\274\211.py" +++ "b/\345\235\207\347\272\277\347\255\226\347\225\245\357\274\210python\347\211\210\357\274\211.md" @@ -1,24 +1,35 @@ -''' -策略出处: https://www.fmz.com/strategy/21157 -策略名称: 均线策略(python版) -策略作者: 小小梦 -策略描述: + +> 策略名称 + +均线策略(python版) + +> 策略作者 + +小小梦 + +> 策略描述 均线策略(python版)教学性质,实盘慎用。 +> 策略参数 + + -参数 默认值 描述 --------------- ----- ------ -FastPeriod 3 入市快线周期 -SlowPeriod 7 入市慢线周期 -EnterPeriod 3 入市观察期 -ExitFastPeriod 3 离市快线周期 -ExitSlowPeriod 7 离市慢线周期 -ExitPeriod true 离市观察期 -PositionRatio 0.8 仓位比例 -Interval 10 轮询周期 -''' +|参数|默认值|描述| +|----|----|----| +|FastPeriod|3|入市快线周期| +|SlowPeriod|7|入市慢线周期| +|EnterPeriod|3|入市观察期| +|ExitFastPeriod|3|离市快线周期| +|ExitSlowPeriod|7|离市慢线周期| +|ExitPeriod|true|离市观察期| +|PositionRatio|0.8|仓位比例| +|Interval|10|轮询周期| + +> 源码 (python) + +``` python import types def main(): STATE_IDLE = -1 @@ -45,3 +56,12 @@ def main(): Sleep(Interval * 1000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/21157 + +> 更新时间 + +2016-09-30 23:25:18 diff --git "a/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245.md" "b/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245.md" new file mode 100644 index 00000000..e6e4c5f1 --- /dev/null +++ "b/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245.md" @@ -0,0 +1,56 @@ + +> 策略名称 + +基于ATR波动率指标构建的通道策略 + +> 策略作者 + +Zero + +> 策略描述 + +思路:通道自适应策略,固定止损+浮动止盈 +适用软件:发明者最最化/文华财经 +数据周期:多周期 +数据合约:指数合约 +交易合约:商品期货/数字货币 + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-11-01 00:00:00 +end: 2018-12-01 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}] +args: [["ContractType","this_week",126961]] +*) + +SLOSS:=2; +N:=200; +M:=4; +X:UNIT; +TR1:=MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW)); +ATR:=MA(TR1,N); +MAC:=MA(C,N); +UBAND:=MAC+M*ATR; +DBAND:=MAC-M*ATR; +H>=HHV(H,N),BPK; +L<=LLV(L,N),SPK; +(H>=HHV(H,M*N) OR C<=UBAND) AND BKHIGH>=BKPRICE*(1+M*SLOSS*0.01),SP; +(L<=LLV(L,M*N) OR C>=DBAND) AND SKLOW<=SKPRICE*(1-M*SLOSS*0.01),BP; +//止损 +C>=SKPRICE*(1+SLOSS*0.01),BP; +C<=BKPRICE*(1-SLOSS*0.01),SP; +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/127691 + +> 更新时间 + +2018-12-01 15:13:23 diff --git "a/\345\237\272\344\272\216CCI\345\221\250\346\234\237\346\200\247\345\214\272\351\227\264\344\272\244\346\230\223\347\255\226\347\225\245.js" "b/\345\237\272\344\272\216CCI\345\221\250\346\234\237\346\200\247\345\214\272\351\227\264\344\272\244\346\230\223\347\255\226\347\225\245.md" similarity index 86% rename from "\345\237\272\344\272\216CCI\345\221\250\346\234\237\346\200\247\345\214\272\351\227\264\344\272\244\346\230\223\347\255\226\347\225\245.js" rename to "\345\237\272\344\272\216CCI\345\221\250\346\234\237\346\200\247\345\214\272\351\227\264\344\272\244\346\230\223\347\255\226\347\225\245.md" index 18ac7bc0..0c15d319 100644 --- "a/\345\237\272\344\272\216CCI\345\221\250\346\234\237\346\200\247\345\214\272\351\227\264\344\272\244\346\230\223\347\255\226\347\225\245.js" +++ "b/\345\237\272\344\272\216CCI\345\221\250\346\234\237\346\200\247\345\214\272\351\227\264\344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -1,20 +1,29 @@ -/* -策略出处: https://www.fmz.com/strategy/60287 -策略名称: 基于CCI周期性区间交易策略 -策略作者: 深蓝 -策略描述: +> 策略名称 +基于CCI周期性区间交易策略 +> 策略作者 -参数 默认值 描述 ---------- ------ ----- -Diff 40 周期区间 -Length 100 周期长度 -AvgLength 10 CCI均值 -Name rb1810 合约代码 -*/ +深蓝 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Diff|40|周期区间| +|Length|100|周期长度| +|AvgLength|10|CCI均值| +|Name|rb1810|合约代码| + +> 源码 (javascript) + +``` javascript /*backtest start: 2015-01-01 09:00:00 end: 2018-04-22 15:00:00 @@ -71,3 +80,12 @@ function main() { } }); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/60287 + +> 更新时间 + +2018-04-23 17:42:32 diff --git "a/\345\237\272\344\272\216\345\233\236\345\275\222\345\271\205\345\272\246\347\232\204\345\217\215\350\275\254\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/\345\237\272\344\272\216\345\233\236\345\275\222\345\271\205\345\272\246\347\232\204\345\217\215\350\275\254\344\272\244\346\230\223\347\255\226\347\225\245.md" new file mode 100644 index 00000000..05234505 --- /dev/null +++ "b/\345\237\272\344\272\216\345\233\236\345\275\222\345\271\205\345\272\246\347\232\204\345\217\215\350\275\254\344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -0,0 +1,101 @@ + +> 策略名称 + +基于回归幅度的反转交易策略 + +> 策略作者 + +Hukybo + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|cycleLength|50|周期长度| +|backRatio|true|回撤比率| +|contractType|rb000/rb888,ru000/ru888|合约类型| +|unit|true|单位| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2010-01-11 09:00:00 +end: 2018-01-03 15:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","minfee":10,"fee":[0,0]}] +*/ + +function main() { + var contractType_Dic = {}; + var contractType_Array1 = contractType.split(","); + var contractType_Array2 = []; + for (var i = 0; i < contractType_Array1.length; i++) { + contractType_Array2.push(contractType_Array1[i].split('/')[1]); + } + contractType_Array2.toString(); + for (var key in contractType_Array2) { + contractType_Dic[contractType_Array2[key]] = { + falsePosition: 0 + } + } + $.CTA(contractType, function(st) { + var bars = st.records; //获取K线数组 + var j = bars[bars.length - 2].Close; + //计算N日内的最高价 + var high = TA.Highest(bars, cycleLength, 'High'); + + //计算N日内的最低价 + var low = TA.Lowest(bars, cycleLength, 'Low'); + + //计算N日内的最高价的回撤1%的值 + var highBack = high * (1 - backRatio / 100); + + //计算N日内的最低价的回撤1%的值 + var lowBack = low * (1 + backRatio / 100); + + if (!bars || bars.length < cycleLength + 1) { + return; + } + + + //多头平仓 + if (contractType_Dic[st.symbol].falsePosition > 0 && j < (lowBack + highBack) / 2) { + contractType_Dic[st.symbol].falsePosition = 0; + return -unit; + } + + //空头平仓 + if (contractType_Dic[st.symbol].falsePosition < 0 && j > (lowBack + highBack) / 2) { + contractType_Dic[st.symbol].falsePosition = 0; + return unit; + } + + //多头开仓 + if (contractType_Dic[st.symbol].falsePosition == 0 && j > lowBack && j > highBack) { + contractType_Dic[st.symbol].falsePosition = 1; + return unit; + } + + //空头开仓 + if (contractType_Dic[st.symbol].falsePosition == 0 && j < lowBack && j < highBack) { + contractType_Dic[st.symbol].falsePosition = -1; + return -unit; + } + + }); +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/69937 + +> 更新时间 + +2018-05-02 20:56:31 diff --git "a/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" "b/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" new file mode 100644 index 00000000..b3f42d06 --- /dev/null +++ "b/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" @@ -0,0 +1,263 @@ + +> 策略名称 + +多交易所集合行情-下单 策略 范例 + +> 策略作者 + +小小梦 + +> 策略描述 + +/upload/asset/20dd683abc5a0e70f84c5f2ae37c1753.png + +> 策略参数 + + + + + +|按钮|默认值|描述| +|----|----|----| +|UpdateAmount|0.1|修改下单量| + + +> 源码 (javascript) + +``` javascript +// 参数,可设置到界面。 +var Interval = 100 +var TickerInterval = 1000 +var RecordsInterval = 1000 + +// 全局变量 +var Amount = 0.1 + +function CreateExchanges(){ + var exs = { + // 交易所对象 + ex_objs : [], + + // exs 的属性 + table : null, + tickerInterval : 0, + recordsInterval : 0, + runCount : 0, + } + // 初始化 + exs.tickerInterval = TickerInterval + exs.recordsInterval = RecordsInterval + + var funcDict = { + "GetTicker" : ["routine_ticker", "ticker", "tickerPreTime"], + "GetRecords" : ["routine_records", "records", "recordsPreTime"], + "Trade" : ["routine_trade", "trade", "tradePreTime"], // 可扩展挂单,多线程发单等功能 + } + + // 初始化 + var timeStamp = new Date().getTime() + for(var i = 0 ; i < exchanges.length ; i++){ + var obj = { + name : exchanges[i].GetName(), + currency : exchanges[i].GetCurrency(), + index : i, + routine_ticker : null, + ticker : null, + tickerPre : null, + tickerPreTime : timeStamp, + routine_trade : null, + trade : null, + tradePreTime : timeStamp, + routine_records : null, + records : null, + recordsPre : null, + recordsPreTime : timeStamp, + recordsPreBarTime : 0, + rows : null, + + } + + exs.ex_objs.push(obj) + } + + exs.Go = function(func, interval){ + var self = this + if(typeof(func) == "undefined"){ + throw "error, no param func" + } + + _.each(self.ex_objs, function(obj){ + if(typeof(obj[funcDict[func][1]]) !== "undefined"){ + obj[funcDict[func][0]] = exchanges[obj.index].Go(func) + obj[funcDict[func][2]] = new Date().getTime() + } + }) + + Sleep(interval) + + _.each(self.ex_objs, function(obj){ + obj[funcDict[func][1]] = obj[funcDict[func][0]].wait(10) + }) + } + + exs.TableUpdate = function(){ + var self = this + + self.table = { + type : "table", + title : "交易所行情", + cols : ["名称", "交易对", "卖一价", "买一价", "最新成交价", "操作A", "操作B", "最近一次请求耗时"], + rows : [], + } + + _.each(self.ex_objs, function(obj){ + var ticker = obj.ticker + if(typeof(ticker) == "undefined" || !ticker){ + ticker = obj.tickerPre ? obj.tickerPre : {Buy : "Nan", Sell : "Nan", Last : "Nan", High : "Nan", Low : "Nan"} + } + self.table.rows.push([ + obj.name, + obj.currency, + ticker.Sell, + ticker.Buy, + ticker.Last, + { + 'type': 'button', + 'cmd': "LogStatus" + "_" + obj.index + "_" + "Buy", + 'name': '买入' + }, + { + 'type': 'button', + 'cmd': "LogStatus" + "_" + obj.index + "_" + "Sell", + 'class': 'btn btn-xs btn-danger', + 'name': '卖出' + }, + (new Date().getTime() - obj.tickerPreTime), + ]) + }) + + self.runCount++ + LogStatus("时间:", _D(), "运行次数:", self.runCount, " ", "\n", '`' + JSON.stringify(self.table) + '`') + } + + exs.Chart = function(chartObj, chartCfg){ + var self = this + + _.each(self.ex_objs, function(obj){ + if(typeof(obj.records) !== "undefined" && obj.records){ + if(obj.recordsPreBarTime == 0){ // 初始化 + for(var i = 0; i < obj.records.length; i++){ + chartObj.add(obj.index, [obj.records[i].Time, obj.records[i].Open, obj.records[i].High, obj.records[i].Low, obj.records[i].Close]) + } + obj.recordsPreBarTime = obj.records[obj.records.length - 1].Time + } else { + if(obj.records[obj.records.length - 1].Time !== obj.recordsPreBarTime){ + chartObj.add(obj.index, [obj.records[obj.records.length - 1].Time, obj.records[obj.records.length - 1].Open, obj.records[obj.records.length - 1].High, obj.records[obj.records.length - 1].Low, obj.records[obj.records.length - 1].Close]) + obj.recordsPreBarTime = obj.records[obj.records.length - 1].Time + } else { + chartObj.add(obj.index, [obj.records[obj.records.length - 1].Time, obj.records[obj.records.length - 1].Open, obj.records[obj.records.length - 1].High, obj.records[obj.records.length - 1].Low, obj.records[obj.records.length - 1].Close], -1) + } + } + } + }) + chartObj.update(chartCfg) + } + + exs.Trade = function(){ + + } + + exs.GetTicker = function(){ + var self = this + self.Go("GetTicker", self.tickerInterval) + _.each(self.ex_objs, function(obj){ + if(typeof(obj.ticker) !== "undefined" && obj.ticker){ + obj.tickerPre = obj.ticker + } + }) + } + + exs.GetRecords = function(){ + var self = this + self.Go("GetRecords", self.recordsInterval) + _.each(self.ex_objs, function(obj){ + if(typeof(obj.records) !== "undefined" && obj.records){ + obj.recordsPre = obj.records + } + }) + } + + + return exs +} + +function main(){ + // 初始化 交易所集合对象 + var exs = CreateExchanges() + + // 图表初始化 + var arrCfg = [] + for(var i = 0 ; i < exchanges.length ; i++){ + var cfg = { + title: { + text: exchanges[i].GetName() + "-" + exchanges[i].GetCurrency() + }, + xAxis: { + type: 'datetime' + }, + series: [{ + type: 'candlestick', + name: 'K线', + id: "" + i, + data: [] + }] + } + arrCfg.push(cfg) + } + var chart = Chart(arrCfg) + chart.reset() + + while(true){ + // 处理交互 + var cmd = GetCommand() + if(cmd){ + var arr = cmd.split("_") + if(arr.length == 3){ + var idx = parseInt(arr[1]) + var type = arr[2] + if(type == "Buy"){ + $.Buy(exchanges[idx], Amount) + } else if(type == "Sell"){ + $.Sell(exchanges[idx], Amount) + } else { + Log("错误的 命令,type:", type, "#FF0000") + } + } else if(arr.length == 1) { + var amount = arr[0].split(":")[1] + Amount = parseInt(amount) + }else { + Log("错误的 命令", "#FF0000") + } + } + + // 获取 records 数据 + exs.GetRecords() + // 获取 ticker 数据 + exs.GetTicker() + + // 处理界面 + exs.TableUpdate() + exs.Chart(chart, arrCfg) + + Sleep(Interval) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/125569 + +> 更新时间 + +2018-11-12 12:34:34 diff --git "a/\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.js" "b/\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.md" similarity index 92% rename from "\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.js" rename to "\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.md" index 4baa2e57..a17920c0 100644 --- "a/\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.js" +++ "b/\345\244\232\345\235\207\347\272\277\347\255\226\347\225\245.md" @@ -1,19 +1,28 @@ -/* -策略出处: https://www.fmz.com/strategy/47144 -策略名称: 多均线策略 -策略作者: 小小梦 -策略描述: +> 策略名称 +多均线策略 +> 策略作者 -参数 默认值 描述 ----- ----- ----- -ma60 60 60日均线 -ma10 10 10日均线 -ma5 5 5日均线 -*/ +小小梦 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|ma60|60|60日均线| +|ma10|10|10日均线| +|ma5|5|5日均线| + +> 源码 (javascript) + +``` javascript // 以下是测试代码 /*- 状态 在使用 模板时需要在 主策略内声明 var TASK_IDLE = 0; @@ -118,3 +127,12 @@ function main() { $.Relation_Exchange_onTick(exchanges[0], onTick1); $.Trend(); // 不用传参数。 } +``` + +> 策略出处 + +https://www.fmz.com/strategy/47144 + +> 更新时间 + +2017-07-20 11:07:24 diff --git "a/\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).js" "b/\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).md" similarity index 77% rename from "\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).js" rename to "\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).md" index 3d917027..68c76ff4 100644 --- "a/\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).js" +++ "b/\345\244\232\345\271\263\345\217\260\345\274\272\345\210\266\346\273\221\345\212\250\345\271\263\344\273\223(\344\271\260\344\270\200\344\273\267).md" @@ -1,19 +1,30 @@ -/* -策略出处: https://www.fmz.com/strategy/99 -策略名称: 多平台强制滑动平仓(买一价) -策略作者: Zero -策略描述: + +> 策略名称 + +多平台强制滑动平仓(买一价) + +> 策略作者 + +Zero + +> 策略描述 支持多平台一块平仓, 有多少币卖多少币 +> 策略参数 + + -参数 默认值 描述 -------------- ----- ------- -RetryInterval 5 尝试间隔(秒) -SlidePrice 0.3 滑动值 -KeepStock false 保留币数 -*/ +|参数|默认值|描述| +|----|----|----| +|RetryInterval|5|尝试间隔(秒)| +|SlidePrice|0.3|滑动值| +|KeepStock|false|保留币数| + +> 源码 (javascript) + +``` javascript function cancelAllOrders() { var orders = null; while (!(orders = exchange.GetOrders())) { @@ -60,3 +71,12 @@ function main() { } +``` + +> 策略出处 + +https://www.fmz.com/strategy/99 + +> 更新时间 + +2018-03-27 15:55:26 diff --git "a/\345\244\232\345\271\263\345\217\260\350\264\246\346\210\267\347\273\237\350\256\241.js" "b/\345\244\232\345\271\263\345\217\260\350\264\246\346\210\267\347\273\237\350\256\241.md" similarity index 80% rename from "\345\244\232\345\271\263\345\217\260\350\264\246\346\210\267\347\273\237\350\256\241.js" rename to "\345\244\232\345\271\263\345\217\260\350\264\246\346\210\267\347\273\237\350\256\241.md" index 8400cfbd..b2127de9 100644 --- "a/\345\244\232\345\271\263\345\217\260\350\264\246\346\210\267\347\273\237\350\256\241.js" +++ "b/\345\244\232\345\271\263\345\217\260\350\264\246\346\210\267\347\273\237\350\256\241.md" @@ -1,20 +1,31 @@ -/* -策略出处: https://www.fmz.com/strategy/7827 -策略名称: 多平台账户统计 -策略作者: 数·狂 -策略描述: + +> 策略名称 多平台账户统计 +> 策略作者 + +数·狂 + +> 策略描述 + +多平台账户统计 + +> 策略参数 + -参数 默认值 描述 ------------ ----- --------------------- -Interval 20 检测间隔(秒) -Type 0 显示类型: 总资产|净资产|总钱数|总币数 -coverStocks false 平仓总币数 -Thr 0.1 报告阈值 -*/ +|参数|默认值|描述| +|----|----|----| +|Interval|20|检测间隔(秒)| +|Type|0|显示类型: 总资产|净资产|总钱数|总币数| +|coverStocks|false|平仓总币数| +|Thr|0.1|报告阈值| + + +> 源码 (javascript) + +``` javascript function EnsureCall(e, method) { var r; while (!(r = e[method].apply(this, Array.prototype.slice.call(arguments).slice(2)))) { @@ -66,3 +77,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/7827 + +> 更新时间 + +2015-12-08 12:17:13 diff --git "a/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245.md" "b/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245.md" new file mode 100644 index 00000000..cd0619ec --- /dev/null +++ "b/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245.md" @@ -0,0 +1,110 @@ + +> 策略名称 + +多级止盈趋势策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略名称: 多级止盈趋势策略 +- 数据周期:多周期 +- 支持:商品期货、数字货币 +- 官方网站:www.quant.la + +/upload/asset/b8d89a704605b72bc44a56575a570bf6.png + +- 主图: + 上线,公式 :UPPERLINE^^今开+BAND; + 下线,公式 :LOWERLINE^^今开-BAND; + 均线,公式 :均线^^MA(CLOSE,LENGTH); + +- 副图: + 无 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|LENGTH|200|均线指标参数| +|STOPRANGE|3|止损幅度| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-01-01 00:00:00 +end: 2018-04-09 00:00:00 +period: 1d +exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] +args: [["LENGTH",80]] +*) + +STARTPER1:=5; //1级跟踪止盈,盈利5%启动 +STOPPER1:=100; //1级跟踪止盈,盈利回撤100%触发 +STARTPER2:=10; //2级跟踪止盈,盈利10%启动 +STOPPER2:=50; //2级跟踪止盈,盈利回撤50%触发 +STARTPER3:=20; //3级跟踪止盈,盈利20%启动 +STOPPER3:=20; //3级跟踪止盈,盈利回撤20%触发 + +//上下区间 +NN:=BARSLAST(DATE<>REF(DATE,1))+1;//今天开盘到目前为止的周期数 +今开:=VALUEWHEN(NN=1,O);//当天的开盘价 +今高:=HHV(H,NN);//今天全天的最高价 +今低:=LLV(L,NN);//今天全天的最低价 +昨高:=REF(今高,NN);//昨天全天的最高价 +昨低:=REF(今低,NN);//昨天全天的最低价 + +BAND:=昨高-昨低; +UPPERLINE^^今开+BAND; +LOWERLINE^^今开-BAND; + +//均线 +均线^^MA(CLOSE,LENGTH); + +//开平仓条件 +卖开条件: = CUPPERLINE AND UPPERLINE>均线; +买平空单: = C>UPPERLINE OR C>均线; +卖平多单: = C=SKLOW+(SKPRICE-SKLOW)*0.01*STOPPER3,BP;//最大盈利达到"STARTPER3"%之后盈利回撤"STOPPER3"%,平空 +BKHIGH>=BKPRICE*(1+0.01*STARTPER3) AND LOW<=BKHIGH-(BKHIGH-BKPRICE)*0.01*STOPPER3,SP;//最大盈利达到"STARTPER3"%之后盈利回撤"STOPPER3"%,平多 +SKLOW<=SKPRICE*(1-0.01*STARTPER2) AND HIGH>=SKLOW+(SKPRICE-SKLOW)*0.01*STOPPER2,BP;//最大盈利达到"STARTPER2"%之后盈利回撤"STOPPER2"%,平空 +BKHIGH>=BKPRICE*(1+0.01*STARTPER2) AND LOW<=BKHIGH-(BKHIGH-BKPRICE)*0.01*STOPPER2,SP;//最大盈利达到"STARTPER2"%之后盈利回撤"STOPPER2"%,平多 +SKLOW<=SKPRICE*(1-0.01*STARTPER1) AND HIGH>=SKLOW+(SKPRICE-SKLOW)*0.01*STOPPER1,BP;//最大盈利达到"STARTPER1"%之后盈利回撤"STOPPER1"%,平空 +BKHIGH>=BKPRICE*(1+0.01*STARTPER1) AND LOW<=BKHIGH-(BKHIGH-BKPRICE)*0.01*STOPPER1,SP;//最大盈利达到"STARTPER1"%之后盈利回撤"STOPPER1"%,平多 + +//止损 +C>=SKPRICE*(1+STOPRANGE*0.01),BP;//空头止损 +C<=BKPRICE*(1-STOPRANGE*0.01),SP;//多头止损 + +SETSIGPRICETYPE(BK,NEW_ORDER); +SETSIGPRICETYPE(SK,NEW_ORDER); +SETSIGPRICETYPE(BP,NEW_ORDER); +SETSIGPRICETYPE(SP,NEW_ORDER); + +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/128122 + +> 更新时间 + +2018-12-03 11:41:22 diff --git "a/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\346\267\261\345\272\246\344\277\241\346\201\257.js" "b/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\346\267\261\345\272\246\344\277\241\346\201\257.md" similarity index 80% rename from "\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\346\267\261\345\272\246\344\277\241\346\201\257.js" rename to "\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\346\267\261\345\272\246\344\277\241\346\201\257.md" index 9e7099af..97d13463 100644 --- "a/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\346\267\261\345\272\246\344\277\241\346\201\257.js" +++ "b/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\346\267\261\345\272\246\344\277\241\346\201\257.md" @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/3651 -策略名称: 多线程获取多个交易的深度信息 -策略作者: Zero -策略描述: + +> 策略名称 + +多线程获取多个交易的深度信息 + +> 策略作者 + +Zero + +> 策略描述 多线程获取多个交易的深度信息 -*/ + +> 源码 (javascript) + +``` javascript function main() { var depths = []; while (true) { @@ -40,3 +48,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/3651 + +> 更新时间 + +2015-01-02 17:18:36 diff --git "a/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\350\264\246\346\210\267\344\277\241\346\201\257.js" "b/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\350\264\246\346\210\267\344\277\241\346\201\257.md" similarity index 80% rename from "\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\350\264\246\346\210\267\344\277\241\346\201\257.js" rename to "\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\350\264\246\346\210\267\344\277\241\346\201\257.md" index 741b2786..64a1670a 100644 --- "a/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\350\264\246\346\210\267\344\277\241\346\201\257.js" +++ "b/\345\244\232\347\272\277\347\250\213\350\216\267\345\217\226\345\244\232\344\270\252\344\272\244\346\230\223\347\232\204\350\264\246\346\210\267\344\277\241\346\201\257.md" @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/3297 -策略名称: 多线程获取多个交易的账户信息 -策略作者: Zero -策略描述: + +> 策略名称 + +多线程获取多个交易的账户信息 + +> 策略作者 + +Zero + +> 策略描述 多线程获取多个交易的账户信息 -*/ + +> 源码 (javascript) + +``` javascript function main() { var accounts = []; while (true) { @@ -39,3 +47,12 @@ function main() { } } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/3297 + +> 更新时间 + +2014-12-11 03:56:53 diff --git "a/\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.js" "b/\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.md" similarity index 90% rename from "\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.js" rename to "\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.md" index 584033cf..f6c5ec88 100644 --- "a/\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.js" +++ "b/\345\246\202\344\275\225\346\211\276\345\207\272\344\270\200\345\256\232Bar\346\225\260\351\207\217\347\232\204 K\347\272\277\345\211\215\346\234\237\351\253\230\347\202\271\343\200\201\344\275\216\347\202\271 \345\217\212 Demo \347\250\213\345\272\217.md" @@ -1,13 +1,19 @@ -/* -策略出处: https://www.fmz.com/strategy/58179 -策略名称: 如何找出一定Bar数量的 K线前期高点、低点 及 Demo 程序 -策略作者: 小小梦 -策略描述: +> 策略名称 +如何找出一定Bar数量的 K线前期高点、低点 及 Demo 程序 -*/ +> 策略作者 +小小梦 + + + + + +> 源码 (javascript) + +``` javascript function FindLastHighestPoint(Records, NumOfBars){ var RecordsLen = Records.length if(RecordsLen < 2){ @@ -104,3 +110,12 @@ function main(){ Sleep(1000) } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/58179 + +> 更新时间 + +2017-10-28 15:16:43 diff --git "a/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.js" "b/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.md" similarity index 84% rename from "\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.js" rename to "\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.md" index 1791a637..1c2061d5 100644 --- "a/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.js" +++ "b/\345\256\232\346\212\225\347\256\200\345\215\225\347\211\210.md" @@ -1,17 +1,26 @@ -/* -策略出处: https://www.fmz.com/strategy/67098 -策略名称: 定投简单版 -策略作者: 小码哥 -策略描述: +> 策略名称 +定投简单版 +> 策略作者 -参数 默认值 描述 ------------------- ----- ----- -singleInvestAmount 0.1 单次买入量 -*/ +小码哥 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|singleInvestAmount|0.1|单次买入量| + +> 源码 (javascript) + +``` javascript // botvs@620e5a1b33965b615ef40e1d29cd2c44 /*backtest @@ -74,3 +83,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/67098 + +> 更新时间 + +2018-01-04 13:37:56 diff --git "a/\345\256\232\346\234\237\345\256\232\351\242\235\346\212\225\350\265\204BTC\347\233\210\345\210\251\351\252\214\350\257\201.js" "b/\345\256\232\346\234\237\345\256\232\351\242\235\346\212\225\350\265\204BTC\347\233\210\345\210\251\351\252\214\350\257\201.md" similarity index 81% rename from "\345\256\232\346\234\237\345\256\232\351\242\235\346\212\225\350\265\204BTC\347\233\210\345\210\251\351\252\214\350\257\201.js" rename to "\345\256\232\346\234\237\345\256\232\351\242\235\346\212\225\350\265\204BTC\347\233\210\345\210\251\351\252\214\350\257\201.md" index e8ce8c3b..518a9afd 100644 --- "a/\345\256\232\346\234\237\345\256\232\351\242\235\346\212\225\350\265\204BTC\347\233\210\345\210\251\351\252\214\350\257\201.js" +++ "b/\345\256\232\346\234\237\345\256\232\351\242\235\346\212\225\350\265\204BTC\347\233\210\345\210\251\351\252\214\350\257\201.md" @@ -1,19 +1,30 @@ -/* -策略出处: https://www.fmz.com/strategy/16845 -策略名称: 定期定额投资BTC盈利验证 -策略作者: 春哥 -策略描述: + +> 策略名称 + +定期定额投资BTC盈利验证 + +> 策略作者 + +春哥 + +> 策略描述 每次按照固定金额购买比特币持有 +> 策略参数 + + -参数 默认值 描述 ------------- ----- -------- -FIXED_AMOUNT 100 每次买多少人民币 -PERIOD 86400 周期(单位秒) -*/ +|参数|默认值|描述| +|----|----|----| +|FIXED_AMOUNT|100|每次买多少人民币| +|PERIOD|86400|周期(单位秒)| +> 源码 (javascript) + +``` javascript + var total_cny = 0; var days = 0; var total_btc = 0; @@ -90,3 +101,12 @@ function createChart() { +``` + +> 策略出处 + +https://www.fmz.com/strategy/16845 + +> 更新时间 + +2016-06-17 01:00:11 diff --git "a/\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.js" "b/\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.md" similarity index 88% rename from "\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.js" rename to "\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.md" index 6abd4653..d76918cb 100644 --- "a/\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.js" +++ "b/\345\256\232\347\202\271\350\277\233\345\234\272\344\270\213\345\215\225\345\256\232\347\202\271\347\246\273\345\234\272\345\215\226\345\215\225.md" @@ -1,27 +1,38 @@ -/* -策略出处: https://www.fmz.com/strategy/64 -策略名称: 定点进场下单定点离场卖单 -策略作者: Zero -策略描述: + +> 策略名称 + +定点进场下单定点离场卖单 + +> 策略作者 + +Zero + +> 策略描述 可以选择在几点进场,几点离场,系统强制建仓,强制平仓,会不停的尝试建仓与平仓, 默认0点进场买,8点出场卖, 设置成进场23,离场8意思就晚上23点进场,第二天8点离场, 如果设置也8.5就是8点半的意思, 设置成8.6就是8点36分,小数点位乘6就是分钟数,止损可以禁止如果勾掉开启止损,止损点如果为0.1表示如果跌0.1%就强制卖出。如果止损价参考最高价,意思就是比如1000买进的,涨到2000了,如果2000跌了0.1%就止损,如果不参考最高价,就是比平均买入价跌了0.1%就止损. +> 策略参数 + + -参数 默认值 描述 ----------------- ----- -------- -EnterHour false 进场时间(小时) -LeaveHour 8 离场时间(小时) -SlidePrice true 滑动值 -UsedFund 1000 建仓金额 -RetryInterval 5 尝试间隔(秒) -StopLoss 0.5 止损点 -EnableStopLoss true 是否开启止损 -RefHigh true 参考最高价止损 -StopProfit 0.5 止赢点 -EnableStopProfit false 是否开启止赢 -*/ +|参数|默认值|描述| +|----|----|----| +|EnterHour|false|进场时间(小时)| +|LeaveHour|8|离场时间(小时)| +|SlidePrice|true|滑动值| +|UsedFund|1000|建仓金额| +|RetryInterval|5|尝试间隔(秒)| +|StopLoss|0.5|止损点| +|EnableStopLoss|true|是否开启止损| +|RefHigh|true|参考最高价止损| +|StopProfit|0.5|止赢点| +|EnableStopProfit|false|是否开启止赢| +> 源码 (javascript) + +``` javascript + // 0 means wait buy, 1 means wait sell var state = 0; var lastBuyAmount = 0; @@ -156,3 +167,12 @@ function main() { } +``` + +> 策略出处 + +https://www.fmz.com/strategy/64 + +> 更新时间 + +2018-03-27 15:53:49 diff --git "a/\345\257\271\345\206\2622.7\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241\347\263\273\347\273\237 \346\224\257\346\214\201\345\244\232\347\273\204\350\264\246\345\217\267\347\273\237\350\256\241.js" "b/\345\257\271\345\206\2622.7\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241\347\263\273\347\273\237 \346\224\257\346\214\201\345\244\232\347\273\204\350\264\246\345\217\267\347\273\237\350\256\241.md" similarity index 90% rename from "\345\257\271\345\206\2622.7\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241\347\263\273\347\273\237 \346\224\257\346\214\201\345\244\232\347\273\204\350\264\246\345\217\267\347\273\237\350\256\241.js" rename to "\345\257\271\345\206\2622.7\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241\347\263\273\347\273\237 \346\224\257\346\214\201\345\244\232\347\273\204\350\264\246\345\217\267\347\273\237\350\256\241.md" index bc068dba..8f2efd7c 100644 --- "a/\345\257\271\345\206\2622.7\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241\347\263\273\347\273\237 \346\224\257\346\214\201\345\244\232\347\273\204\350\264\246\345\217\267\347\273\237\350\256\241.js" +++ "b/\345\257\271\345\206\2622.7\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241\347\263\273\347\273\237 \346\224\257\346\214\201\345\244\232\347\273\204\350\264\246\345\217\267\347\273\237\350\256\241.md" @@ -1,21 +1,32 @@ -/* -策略出处: https://www.fmz.com/strategy/18678 -策略名称: 对冲2.7收益率统计系统 支持多组账号统计 -策略作者: Zero -策略描述: + +> 策略名称 + +对冲2.7收益率统计系统 支持多组账号统计 + +> 策略作者 + +Zero + +> 策略描述 对冲2.7收益率统计系统 支持多组账号统计, 添加偶数长度的交易所即可开始统计, 每两个为一组进行添加 币价会取第一个交易所的买一做为参考值 +> 策略参数 + + -参数 默认值 描述 ------------ ----- -------------------- -Interval 60 统计间隔(秒) -InitMode 0 统计初始资金的模式: 自动统计|手动输入 -InitBalance false 初始总钱 -InitStocks false 初始总币 -*/ +|参数|默认值|描述| +|----|----|----| +|Interval|60|统计间隔(秒)| +|InitMode|0|统计初始资金的模式: 自动统计|手动输入| +|InitBalance|false|初始总钱| +|InitStocks|false|初始总币| + +> 源码 (javascript) + +``` javascript // function main() { @@ -122,3 +133,12 @@ function main() { LogStatus('`' + JSON.stringify(tbl) + '`'); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/18678 + +> 更新时间 + +2016-08-13 18:32:22 diff --git "a/\345\267\256\344\273\267\347\233\221\346\216\247.js" "b/\345\267\256\344\273\267\347\233\221\346\216\247.md" similarity index 85% rename from "\345\267\256\344\273\267\347\233\221\346\216\247.js" rename to "\345\267\256\344\273\267\347\233\221\346\216\247.md" index d0a9115b..14b0b312 100644 --- "a/\345\267\256\344\273\267\347\233\221\346\216\247.js" +++ "b/\345\267\256\344\273\267\347\233\221\346\216\247.md" @@ -1,29 +1,43 @@ -/* -策略出处: https://www.fmz.com/strategy/1340 -策略名称: 差价监控 -策略作者: Zero -策略描述: + +> 策略名称 + +差价监控 + +> 策略作者 + +Zero + +> 策略描述 只支持两个交易所, 可自定义差价的类型, 支持2.77托管者的自定义图表功能 +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|AType|0|主平台价格类型: 上次成交价|买一价|卖一价| +|BType|0|次平台价格类型: 上次成交价|买一价|卖一价| +|Interval|2000|出错重试间隔(毫秒)| +|TickInterval|2000|检测频率(毫秒)| +|EnableCR|false|自定义汇率| +|USDCNY|false|USDCNY| +|NormalDiff|0.1|普通差价| +|HighDiff|0.3|较高差价| -参数 默认值 描述 ------------- ----- ---------------------- -AType 0 主平台价格类型: 上次成交价|买一价|卖一价 -BType 0 次平台价格类型: 上次成交价|买一价|卖一价 -Interval 2000 出错重试间隔(毫秒) -TickInterval 2000 检测频率(毫秒) -EnableCR false 自定义汇率 -USDCNY false USDCNY -NormalDiff 0.1 普通差价 -HighDiff 0.3 较高差价 -按钮 默认值 描述 ----- ---------- ---- -重置数据 __button__ @ -*/ +|按钮|默认值|描述| +|----|----|----| +|重置数据|__button__|@| + + +> 源码 (javascript) + +``` javascript + var __lastDiff = 0; var __AType = ["Last", "Buy", "Sell"][AType]; var __BType = ["Last", "Buy", "Sell"][BType]; @@ -156,3 +170,12 @@ function main() { } } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/1340 + +> 更新时间 + +2017-09-13 22:28:04 diff --git "a/\345\270\201\345\256\211\345\207\272\345\224\256\346\211\200\346\234\211\345\261\261\345\257\250\345\270\201.js" "b/\345\270\201\345\256\211\345\207\272\345\224\256\346\211\200\346\234\211\345\261\261\345\257\250\345\270\201.md" similarity index 83% rename from "\345\270\201\345\256\211\345\207\272\345\224\256\346\211\200\346\234\211\345\261\261\345\257\250\345\270\201.js" rename to "\345\270\201\345\256\211\345\207\272\345\224\256\346\211\200\346\234\211\345\261\261\345\257\250\345\270\201.md" index ce6b8953..00a634a8 100644 --- "a/\345\270\201\345\256\211\345\207\272\345\224\256\346\211\200\346\234\211\345\261\261\345\257\250\345\270\201.js" +++ "b/\345\270\201\345\256\211\345\207\272\345\224\256\346\211\200\346\234\211\345\261\261\345\257\250\345\270\201.md" @@ -1,17 +1,26 @@ -/* -策略出处: https://www.fmz.com/strategy/97629 -策略名称: 币安出售所有山寨币 -策略作者: Zero -策略描述: +> 策略名称 +币安出售所有山寨币 +> 策略作者 -参数 默认值 描述 ---------- ----- --------------------- -quoteZone 0 交易区: BTC|ETH|BNB|USDT -*/ +Zero + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|quoteZone|0|交易区: BTC|ETH|BNB|USDT| + + +> 源码 (javascript) + +``` javascript function main() { var quoteCurrency = ['BTC', 'ETH', 'BNB', 'USDT'][quoteZone]; Log("当前交易区", quoteCurrency); @@ -53,3 +62,12 @@ function main() { }); Log("操作完成, 当前", quoteCurrency, "数量", _C(exchange.GetAccount).Balance); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/97629 + +> 更新时间 + +2018-06-11 17:56:50 diff --git "a/\345\270\201\345\256\211\345\217\226\346\266\210\346\211\200\346\234\211\344\272\244\346\230\223\345\257\271\346\234\252\345\256\214\346\210\220\350\256\242\345\215\225\357\274\210IO\346\211\251\345\261\225\347\244\272\350\214\203\357\274\211|Cancel ALL Binance Orders.md" "b/\345\270\201\345\256\211\345\217\226\346\266\210\346\211\200\346\234\211\344\272\244\346\230\223\345\257\271\346\234\252\345\256\214\346\210\220\350\256\242\345\215\225\357\274\210IO\346\211\251\345\261\225\347\244\272\350\214\203\357\274\211|Cancel ALL Binance Orders.md" new file mode 100644 index 00000000..96a96108 --- /dev/null +++ "b/\345\270\201\345\256\211\345\217\226\346\266\210\346\211\200\346\234\211\344\272\244\346\230\223\345\257\271\346\234\252\345\256\214\346\210\220\350\256\242\345\215\225\357\274\210IO\346\211\251\345\261\225\347\244\272\350\214\203\357\274\211|Cancel ALL Binance Orders.md" @@ -0,0 +1,48 @@ + +> 策略名称 + +币安取消所有交易对未完成订单(IO扩展示范)|Cancel ALL Binance Orders + +> 策略作者 + +botvsing + + + + + +> 源码 (javascript) + +``` javascript +function cancellAll(){ + try{ + var openOrders = exchange.IO('api', 'GET', '/api/v3/openOrders'); + for (var i=0; i 策略出处 + +https://www.fmz.com/strategy/121549 + +> 更新时间 + +2018-10-16 10:58:22 diff --git "a/\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.py" "b/\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.md" similarity index 98% rename from "\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.py" rename to "\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.md" index 6595cfd3..65fb97eb 100644 --- "a/\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.py" +++ "b/\345\270\203\346\236\227\345\235\207\347\272\277\347\252\201\347\240\264_vnpy_botvs\345\256\236\347\216\260\347\211\210.md" @@ -1,8 +1,13 @@ -''' -策略出处: https://www.fmz.com/strategy/52801 -策略名称: 布林均线突破_vnpy_botvs实现版 -策略作者: ipqhjjybj -策略描述: + +> 策略名称 + +布林均线突破_vnpy_botvs实现版 + +> 策略作者 + +ipqhjjybj + +> 策略描述 这是将 botvs的接口用 Vnpy 的写法 方式简单封装掉,便于后期的调用! 这本来是期货的 策略, 直接改参数套在 比特币上。 @@ -13,15 +18,21 @@ bar.minute.hour 代表是小时级别 bar.minute.minute 代表是分钟级别 +> 策略参数 -参数 默认值 描述 ---------------- ----- -------------- -ContractTypeIdx 0 期货类型: 当周|次周|季度 -MarginLevelIdx 0 杠杠大小: 10|20 -LoopInterval true 轮询间隔(秒) -minute_use 12 分钟级别 -''' + +|参数|默认值|描述| +|----|----|----| +|ContractTypeIdx|0|期货类型: 当周|次周|季度| +|MarginLevelIdx|0|杠杠大小: 10|20| +|LoopInterval|true|轮询间隔(秒)| +|minute_use|12|分钟级别| + + +> 源码 (python) + +``` python ''' 策略名称: BollingBreaker趋势策略 策略作者: ipqhjjybj @@ -628,3 +639,12 @@ def main(): for st in objs: st.onCall() Sleep(LoopInterval * 1000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/52801 + +> 更新时间 + +2017-09-10 21:35:41 diff --git "a/\345\271\263\345\217\260\344\273\267\346\240\274\346\214\207\346\240\207\347\233\221\346\216\2471.1.js" "b/\345\271\263\345\217\260\344\273\267\346\240\274\346\214\207\346\240\207\347\233\221\346\216\2471.1.md" similarity index 91% rename from "\345\271\263\345\217\260\344\273\267\346\240\274\346\214\207\346\240\207\347\233\221\346\216\2471.1.js" rename to "\345\271\263\345\217\260\344\273\267\346\240\274\346\214\207\346\240\207\347\233\221\346\216\2471.1.md" index a5f89828..9efcf972 100644 --- "a/\345\271\263\345\217\260\344\273\267\346\240\274\346\214\207\346\240\207\347\233\221\346\216\2471.1.js" +++ "b/\345\271\263\345\217\260\344\273\267\346\240\274\346\214\207\346\240\207\347\233\221\346\216\2471.1.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/12442 -策略名称: 平台价格指标监控1.1 -策略作者: tfboys -策略描述: + +> 策略名称 + +平台价格指标监控1.1 + +> 策略作者 + +tfboys + +> 策略描述 1.5---可以监控ATR,RSI,BOLL,PRICE 1.4---增加告警周期设置 @@ -10,27 +15,36 @@ 1.2---支持期货平台 1.1---稳定版本 +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|CType0|0|所0货币类型: 人民币|美元| +|ContractType0|0|所0合约类型: 当周|下周|当月|季度| +|MLevel0|0|所0杠杆大小: 10倍|20倍| +|LoopInterval|500|轮询间隔(毫秒)| +|MaxVal|2755|值上限| +|MinVal|2730|值下限| +|AlarmPeriod|2|告警周期(单位:轮询时长)| +|Interval|500|函数重试间隔| +|Period|14|周期| +|Index|0|指标类型: ATR|RSI|BOLL|PRICE| +|RecordsHand|false|手动收集K线| +|CleanLog|true|清理日志图表| + -参数 默认值 描述 -------------- ----- ------------------------ -CType0 0 所0货币类型: 人民币|美元 -ContractType0 0 所0合约类型: 当周|下周|当月|季度 -MLevel0 0 所0杠杆大小: 10倍|20倍 -LoopInterval 500 轮询间隔(毫秒) -MaxVal 2755 值上限 -MinVal 2730 值下限 -AlarmPeriod 2 告警周期(单位:轮询时长) -Interval 500 函数重试间隔 -Period 14 周期 -Index 0 指标类型: ATR|RSI|BOLL|PRICE -RecordsHand false 手动收集K线 -CleanLog true 清理日志图表 - -按钮 默认值 描述 ----- ---------- ---- -推送切换 __button__ 微信推送 -*/ + +|按钮|默认值|描述| +|----|----|----| +|推送切换|__button__|微信推送| + + +> 源码 (javascript) + +``` javascript var _ContractType0 = ["this_week", "next_week", "month", "quarter"][ContractType0]; var _MarginLeve0 = [10, 20][MLevel0]; var usdrate0 = 6.35; @@ -358,3 +372,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/12442 + +> 更新时间 + +2016-04-25 12:56:03 diff --git "a/\345\271\263\345\217\260\344\273\267\346\240\274\346\257\224\350\276\2031.0.js" "b/\345\271\263\345\217\260\344\273\267\346\240\274\346\257\224\350\276\2031.0.md" similarity index 84% rename from "\345\271\263\345\217\260\344\273\267\346\240\274\346\257\224\350\276\2031.0.js" rename to "\345\271\263\345\217\260\344\273\267\346\240\274\346\257\224\350\276\2031.0.md" index 184f2884..6be49a75 100644 --- "a/\345\271\263\345\217\260\344\273\267\346\240\274\346\257\224\350\276\2031.0.js" +++ "b/\345\271\263\345\217\260\344\273\267\346\240\274\346\257\224\350\276\2031.0.md" @@ -1,37 +1,51 @@ -/* -策略出处: https://www.fmz.com/strategy/8266 -策略名称: 平台价格比较1.0 -策略作者: tfboys -策略描述: + +> 策略名称 + +平台价格比较1.0 + +> 策略作者 + +tfboys + +> 策略描述 1.4---增加告警周期设置 1.3---增加微信通知 1.2---支持期货平台 1.1---稳定版本 +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|CType0|0|所0货币类型: 人民币|美元| +|ContractType0|0|所0合约类型: 当周|下周|当月|季度| +|MLevel0|0|所0杠杆大小: 10倍|20倍| +|ContractType1|0|所1合约类型: 当周|下周|当月|季度| +|MLevel1|0|所1杠杠大小: 10倍|20倍| +|LoopInterval|5000|轮询间隔(毫秒)| +|MaxVal|105|值上限| +|MinVal|102|值下限| +|AlarmPeriod|20|告警周期(单位:轮询时长)| +|CType1|0|所1货币类型: 人民币|美元| +|Interval|1000|函数重试间隔| +|Price0|0|所0价格类型: Asks[0]|Last|Bids[0]| +|Price1|0|所1价格类型: Asks[0]|Last|Bids[0]| +|Option|0|比较类型: Sub|Dev| + -参数 默认值 描述 -------------- ----- ---------------------------- -CType0 0 所0货币类型: 人民币|美元 -ContractType0 0 所0合约类型: 当周|下周|当月|季度 -MLevel0 0 所0杠杆大小: 10倍|20倍 -ContractType1 0 所1合约类型: 当周|下周|当月|季度 -MLevel1 0 所1杠杠大小: 10倍|20倍 -LoopInterval 5000 轮询间隔(毫秒) -MaxVal 105 值上限 -MinVal 102 值下限 -AlarmPeriod 20 告警周期(单位:轮询时长) -CType1 0 所1货币类型: 人民币|美元 -Interval 1000 函数重试间隔 -Price0 0 所0价格类型: Asks[0]|Last|Bids[0] -Price1 0 所1价格类型: Asks[0]|Last|Bids[0] -Option 0 比较类型: Sub|Dev - -按钮 默认值 描述 ----- ---------- ---- -推送切换 __button__ 微信推送 -*/ + +|按钮|默认值|描述| +|----|----|----| +|推送切换|__button__|微信推送| + + +> 源码 (javascript) + +``` javascript var _ContractType0 = ["this_week", "next_week", "month", "quarter"][ContractType0]; var _MarginLeve0 = [10, 20][MLevel0]; var _ContractType1 = ["this_week", "next_week", "month", "quarter"][ContractType1]; @@ -257,3 +271,12 @@ function main() { } +``` + +> 策略出处 + +https://www.fmz.com/strategy/8266 + +> 更新时间 + +2015-12-10 21:35:13 diff --git "a/\345\271\275\347\201\265\344\272\244\346\230\223\350\200\205\347\255\226\347\225\245 (Share 1512580165).js" "b/\345\271\275\347\201\265\344\272\244\346\230\223\350\200\205\347\255\226\347\225\245 (Share 1512580165).js" deleted file mode 100644 index 2110b7e5..00000000 --- "a/\345\271\275\347\201\265\344\272\244\346\230\223\350\200\205\347\255\226\347\225\245 (Share 1512580165).js" +++ /dev/null @@ -1,181 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/62303 -策略名称: 幽灵交易者策略 (Share 1512580165) -策略作者: ellajella-0378 -策略描述: - -#### 前言 -正如幽灵交易者的名字,该策略的核心思路是,在真实下单交易之前,先虚拟出一个交易,如果这个虚拟的交易是亏损的,那么下一次才启动真实的交易。 - -. - -#### 策略简介 -* 该策略思路源自于交易者的观察,交易者从自己的交易记录中发现,如果上一次交易是盈利的,那么下一次交易亏损的概率比较大。因此在设计策略时,人为的控制了这些可能会亏损的交易。 - -* 具体在策略中,我们将引入虚拟交易和与之对应的真实下单模块。也就是说,虚拟交易一直在运行,而真实下单模块直到上一笔虚拟交易是亏损的,并且达到指定的交易条件的情况下才执行。 - -. - -#### 策略原始需求 -* K线数据 -![此处输入图片的描述][1] - -* 短期指数平均线 -* 长期指数平均线 -![此处输入图片的描述][2] - -* RSI 指标 -![此处输入图片的描述][3] - -* 唐奇安通道 -![此处输入图片的描述][4] - -. - -#### 入场条件 -* 多头开仓:如果当前没有持仓,并且上次虚拟交易时发生过一次亏损,并且短期均线在长期均线之上,并且 RSI 低于超卖值,并且价格创新高。 -* 空头开仓:如果当前没有持仓,并且上次虚拟交易时发生过一次亏损,并且短期均线在长期均线之下,并且 RSI 高于超买值,并且价格创新低。 - -. - -#### 出场条件 -* 多头平仓:如果当前持有多单,并且价格下破唐奇安通道下轨。 -* 空头平仓:如果当前持有空单,并且价格上破唐奇安通道上轨。 - -. - -#### 回测绩效 -![此处输入图片的描述][5] - -. - -#### 策略进阶 -* 改变出场方式 -* 本策略是通过唐奇安通道上下轨进行止损出场的,也可以采用最大浮动亏损百分比进行止损。 -* 改变入场方式 -* 本策略每次真实入场前是基于前一次的虚拟盈亏,也可以考虑设置多次虚拟盈亏结果决定是否入场。 - -. - -#### 策略特点 -* 该策略中的亮点是虚拟交易与实盘交易完全隔离,当虚拟交易亏损后,实盘交易才入场。 - -* 将均线与 RSI 相结合,这是区别以往策略的又一亮点,即当行情进入超卖区不做空,当行情进入超买区不做多。 - -. - -#### 特别提示 -市场唯一不变的就是一直在变,并且未来不可预测,过去的回测结果并不代表未来。 - - - - [1]: https://dn-filebox.qbox.me/75ce917bea3ca3131c13e718539cb45972942565.png - [2]: https://dn-filebox.qbox.me/b70fb37d684b32135ad8e3b6f0827230e5ca3ce7.png - [3]: https://dn-filebox.qbox.me/dfe151d32bd350c5713bf39b7f7940361eee1e40.png - [4]: https://dn-filebox.qbox.me/236fb56dc1ad9119cc38350270710ec6591cb2ba.png - [5]: https://dn-filebox.qbox.me/e5dc7e6c903d0a0b43f04483e0ac0607a1212eb3.png - - -参数 默认值 描述 ------------- ----------- ----- -contractType rb000/rb888 合约类型 -fastLength 25 短期均线 -slowLength 100 长期均线 -rsiLength 15 RSI周期 -Donchian 20 唐奇安周期 -*/ - -/*backtest -start: 2017-01-01 09:00:00 -end: 2017-11-27 15:00:00 -period: 1h -*/ - -var into = 0; // 入场价格 -var out = 0; // 出场价格 -var myPosition = 0; // 虚拟持仓 -var myProfit = 0; // 虚拟利润 -var uu = 30; // 超卖 -var nn = 70; // 超买 - -// 语法固定格式,调用main主函数 -function main() { - // 调用商品期货交易类库中的CTA框架 - $.CTA(contractType, function(st) { - var mp = st.position.amount; - - //获取K线数组 - var j = st.records; - //指标运算参考的最大K线数量 - if (j.length < Math.max(fastLength, slowLength, rsiLength)) { - return - } - var h0 = j[j.length - 1].High; - var h1 = j[j.length - 2].High; - var l0 = j[j.length - 1].Low; - var l1 = j[j.length - 2].Low; - var o0 = j[j.length - 1].Open; - var c0 = j[j.length - 1].Close; - - //短期指数平均线数组和长期指数平均线数组 - var fastMas = talib.MA(j, fastLength); - var slowMas = talib.MA(j, slowLength); - var fastMa1 = fastMas[fastMas.length - 2]; - var slowMa1 = slowMas[slowMas.length - 2]; - - //获取RSI数组 - var rsis = talib.RSI(j, rsiLength); - var rsi1 = rsis[rsis.length - 2]; - - //获取唐奇安通道 - var highest = TA.Highest(j, Donchian, "High"); - var lowest = TA.Lowest(j, Donchian, "Low"); - - // 平多 - if (l0 <= lowest) { - if (myPosition > 0) { - out = Math.min(o0, lowest); - myProfit = into - out; - myPosition = 0; - } - if (mp > 0) { - return -1; - } - } - - // 平空 - if (h0 >= highest) { - if (myPosition < 0) { - out = Math.max(o0, highest); - myProfit = into - out; - myPosition = 0; - } - if (mp < 0) { - return 1; - } - } - - // 开多 - if (fastMa1 > slowMa1 && rsi1 < nn && h0 >= h1) { - if (myPosition === 0) { - into = Math.max(o0, h1); - myPosition = 1; - } - if (myProfit < 0 && mp < 1) { - return 1; - } - } - - // 开空 - if (fastMa1 < slowMa1 && rsi1 > uu && l0 <= l1) { - if (myPosition === 0) { - into = Math.min(o0, l1); - myPosition = -1; - } - if (myProfit < 0 && mp > -1) { - return -1; - } - } - - }); -} diff --git "a/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245.md" "b/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245.md" new file mode 100644 index 00000000..619ed6c8 --- /dev/null +++ "b/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245.md" @@ -0,0 +1,80 @@ + +> 策略名称 + +开收盘均价差ATR策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略进场:开盘价和收盘价均价差决定趋势,与ATR结合,进场点也是反向出场点; +- 策略出场:开仓就定好止损点,趋势转向出场; +- 数据周期:日线 +- 数据合约:指数合约 +- 交易合约:主力合约 +- 适合品种:沪铝、沥青、淀粉、热卷、铁矿石、焦炭、鸡蛋、郑醇、螺纹、橡胶、锰硅、郑煤等 +- 官方网站:[WWW.QUANT.LA](WWW.QUANT.LA) + +- 主图: + 无 + +- 副图: + 显示:ATR,公式 ATR^^MA(TR,N); + 显示 :C_O,公式 C_O:EMA(C,N)-EMA(O,N); + +/upload/asset/ab8d909c6464234b06ef1f116a4de200.png + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N|20|ATR指标参数| +|M|5|BAND系数| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-10-01 00:00:00 +end: 2018-11-30 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","balance":20000}] +*) + +// 变量 +LOTS:=MAX(1,INTPART(MONEYTOT/(O*UNIT*0.1))); +C_O:EMA(C,N)-EMA(O,N); +B:=CROSSUP(C_O,0); +S:=CROSSDOWN(C_O,0); +TR:=MAX(MAX((H-L),ABS(REF(C,1)-H)),ABS(REF(C,1)-L)); +ATR:MA(TR,N); +BAND:=ATR*0.1*M; +PRICE_BPK:=VALUEWHEN(B,H+BAND); +PRICE_SP:=VALUEWHEN(B,L-BAND); +PRICE_SPK:=VALUEWHEN(S,L-BAND); +PRICE_BP:=VALUEWHEN(S,H+BAND); + +// 策略逻辑 +BARPOS>N AND C_O>0 AND C>=PRICE_BPK,BPK(LOTS); +BARPOS>N AND C_O<0 AND C<=PRICE_SPK,SPK(LOTS); + +// 下单 +S,SP(BKVOL); +B,BP(SKVOL); + +C<=PRICE_SP,SP(BKVOL); +C>=PRICE_BP,BP(SKVOL); +``` + +> 策略出处 + +https://www.fmz.com/strategy/128136 + +> 更新时间 + +2018-12-03 11:42:38 diff --git "a/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" "b/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" new file mode 100644 index 00000000..302232f4 --- /dev/null +++ "b/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" @@ -0,0 +1,75 @@ + +> 策略名称 + +抛物线转向SAR与价格高低点策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略名称:SAR和价格高低点策略 +- 数据周期:1H等 +- 策略支持:商品期货、数字货币现货,数字货币期货 +- 官方网站:www.quant.la + +/upload/asset/4d9459b9af47702f7c2c6666212927c7.png + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|SLOSS|2|止损止盈百分比| +|N|60|收盘价高低点周期| +|IsCryptoCurrency|0|选择用于商品期货或者数字货币: 商品期货|数字货币现货|数字货币期货| +|CryptoCurrencyTradeAmount|true|用于数字货币市场时的每次交易下单量| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-01-01 00:00:00 +end: 2018-12-02 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["IsCryptoCurrency",2],["ContractType","rb888",126961]] +*) + +// 参数 +// N:=60; +// SLOSS:=2; +// FUND:=20000; + +LOTS:=IF(IsCryptoCurrency, IF(IsCryptoCurrency=1, CryptoCurrencyTradeAmount, MAX(1, INTPART(CryptoCurrencyTradeAmount))), MAX(1,INTPART(MONEYTOT/(O*UNIT*0.1)))); +SARLINE:=SAR(4,2,20); + +B1:=SARLINE>0; +S1:=SARLINE<0; +B2:=HIGH>=HHV(CLOSE,N); +S2:=LOW<=LLV(CLOSE,N); + +BUYK:=BARPOS>N AND B1 AND B2; +SELLK:=BARPOS>N AND S1 AND S2; +SELLY:=S1 AND S2 AND BKHIGH>BKPRICE*(1+0.01*SLOSS); +BUYY:=B1 AND B2 AND SKLOWSKPRICE*(1+SLOSS*0.01); +BUYK,BK(LOTS); +SELLK,SK(LOTS); +SELLY,SP(BKVOL); +BUYY,BP(SKVOL); +SELLS,SP(BKVOL); +BUYS,BP(SKVOL); +``` + +> 策略出处 + +https://www.fmz.com/strategy/128251 + +> 更新时间 + +2018-12-05 18:14:25 diff --git "a/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.js" "b/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.md" similarity index 88% rename from "\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.js" rename to "\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.md" index 86aeb639..eb5cc3a1 100644 --- "a/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.js" +++ "b/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \345\257\271\346\225\262.md" @@ -1,23 +1,34 @@ -/* -策略出处: https://www.fmz.com/strategy/304 -策略名称: 抢盘口做市策略 - 对敲 -策略作者: Zero -策略描述: + +> 策略名称 + +抢盘口做市策略 - 对敲 + +> 策略作者 + +Zero + +> 策略描述 抢盘口做市策略, 最基础的做市策略,买一卖一抢单抢盘口, 赚买一卖一的差价. +> 策略参数 + + -参数 默认值 描述 ------------- ------ ---------- -Interval 2000 出错重试间隔(毫秒) -LoopInterval true 轮询间隔(秒) -SlidePrice 0.01 滑点 -MaxDiff 0.8 盘口最小差价 -Lot 0.2 手数 -MinStock 0.0001 最小交易量 -*/ +|参数|默认值|描述| +|----|----|----| +|Interval|2000|出错重试间隔(毫秒)| +|LoopInterval|true|轮询间隔(秒)| +|SlidePrice|0.01|滑点| +|MaxDiff|0.8|盘口最小差价| +|Lot|0.2|手数| +|MinStock|0.0001|最小交易量| +> 源码 (javascript) + +``` javascript + function CancelPendingOrders(orderType) { while (true) { var orders = _C(exchange.GetOrders); @@ -133,3 +144,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/304 + +> 更新时间 + +2018-03-27 16:28:46 diff --git "a/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \351\253\230\351\242\221\351\200\274\350\277\221\345\236\213.js" "b/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \351\253\230\351\242\221\351\200\274\350\277\221\345\236\213.md" similarity index 88% rename from "\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \351\253\230\351\242\221\351\200\274\350\277\221\345\236\213.js" rename to "\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \351\253\230\351\242\221\351\200\274\350\277\221\345\236\213.md" index e9a67cd8..7e65fd99 100644 --- "a/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \351\253\230\351\242\221\351\200\274\350\277\221\345\236\213.js" +++ "b/\346\212\242\347\233\230\345\217\243\345\201\232\345\270\202\347\255\226\347\225\245 - \351\253\230\351\242\221\351\200\274\350\277\221\345\236\213.md" @@ -1,25 +1,36 @@ -/* -策略出处: https://www.fmz.com/strategy/348 -策略名称: 抢盘口做市策略 - 高频逼近型 -策略作者: Zero -策略描述: + +> 策略名称 + +抢盘口做市策略 - 高频逼近型 + +> 策略作者 + +Zero + +> 策略描述 抢盘口做市策略, 最基础的做市策略,买一卖一抢单抢盘口, 赚买一卖一的差价. 比如现在卖1是60买1是70, 此策略会以65为中界,65以下布满买单,65以上布满卖单, 因为需要不停的调整订单布局,暂起名为高频逼近型 注意: 模拟测试GetTicker的买一卖一固定差价为1.6, 实际效果需要实盘测试 +> 策略参数 + + -参数 默认值 描述 ------------- ----- ---------- -Interval 2000 出错重试间隔(毫秒) -LoopInterval 60 轮询间隔(秒) -Step 0.1 网格间隔(元) -Lot 0.05 手数 -MaxNets 20 最大网格数 -DisableLog false 关闭订单跟踪 -MinStock 0.01 最小交易币数 -*/ +|参数|默认值|描述| +|----|----|----| +|Interval|2000|出错重试间隔(毫秒)| +|LoopInterval|60|轮询间隔(秒)| +|Step|0.1|网格间隔(元)| +|Lot|0.05|手数| +|MaxNets|20|最大网格数| +|DisableLog|false|关闭订单跟踪| +|MinStock|0.01|最小交易币数| + +> 源码 (javascript) + +``` javascript function adjustFloat(v) { return Math.floor(v*100)/100; } @@ -137,3 +148,12 @@ function main() { Sleep(LoopInterval * 1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/348 + +> 更新时间 + +2018-06-05 16:24:29 diff --git "a/\346\214\207\346\225\260\345\235\207\350\241\241\347\255\226\347\225\245 (\346\225\231\345\255\246).md" "b/\346\214\207\346\225\260\345\235\207\350\241\241\347\255\226\347\225\245 (\346\225\231\345\255\246).md" new file mode 100644 index 00000000..17dead53 --- /dev/null +++ "b/\346\214\207\346\225\260\345\235\207\350\241\241\347\255\226\347\225\245 (\346\225\231\345\255\246).md" @@ -0,0 +1,102 @@ + +> 策略名称 + +指数均衡策略 (教学) + +> 策略作者 + +小小梦 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Ratio|0.25|0.25|0.25|占总资产比例| +|BaseAsset|BTC|基准货币| +|ToBuy|0.1|0.1|0.1|补仓的下跌比例| +|ToSell|0.1|0.1|0.1|减仓的上涨比例| +|Interval|10|检查间隔(s)| +|diff|0.01|滑价| + + +> 源码 (javascript) + +``` javascript +var coinValue = {}; // 声明 全局变量 coinValue ,用一个空对象赋值 +var totalValue = 0; // 总价值 +function updateValue(){ // 更新 价值 + var logString = 'Time: '+ _D() + '\n'; // 声明一个变量 , 日志字符串并且初始化, 初始化记录上 当前时间 + var account = _C(exchanges[0].GetAccount); // 获取 为了给 coinValue的 BaseAsset 属性 (也就是基础币种资产)初始化的账户数据。 + coinValue[BaseAsset] = {amount:account.Balance + account.FrozenBalance, value:account.Balance + account.FrozenBalance}; // amount , value 属性 初始化 均为 总计价币数。BaseAsset 为 基准货币 + totalValue = coinValue[BaseAsset].value; // 更新 总价值 + logString += BaseAsset + ': ' + _N(coinValue[BaseAsset].value,5) + '\n'; // 给日志字符串 添加上 当前 基准货币 总价值 数据 + for(var i=0;i 1){ // 统计 keepPercent 数组中的元素值总和 + throw 'sum of keep percent should be lower than 1'; // 各资产 占比总和 不能超过 100% +} +var buyPercent = ToBuy.split('|').map(Number); // 根据参数处理字符串,构造 买入比例 数组 +var sellPercent = ToSell.split('|').map(Number); // ... 构造 卖出比例 数组 +for(var i=0;i (1+coinValue[symbol].sellPercent)*totalValue*coinValue[symbol].keepPercent){ + var sellAmount = (coinValue[symbol].value - totalValue*coinValue[symbol].keepPercent)/coinValue[symbol].buyPrice + exchanges[i].Sell(coinValue[symbol].buyPrice, sellAmount) + CancelPendingOrders(exchanges[i]); + } + else if(coinValue[symbol].value < (1-coinValue[symbol].buyPercent)*totalValue*coinValue[symbol].keepPercent){ + var buyAmount = (totalValue*coinValue[symbol].keepPercent - coinValue[symbol].value)/coinValue[symbol].sellPrice + exchanges[i].Buy(coinValue[symbol].sellPrice, buyAmount); + CancelPendingOrders(exchanges[i]); + } + } +} +function main() { + while(true){ // 主循环 + onTick(); // 主要逻辑函数 + Sleep(Interval*1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/120581 + +> 更新时间 + +2018-10-17 15:38:21 diff --git "a/\346\214\207\346\225\260\345\271\263\350\241\241\347\255\226\347\225\245|Index Balance Bot.md" "b/\346\214\207\346\225\260\345\271\263\350\241\241\347\255\226\347\225\245|Index Balance Bot.md" new file mode 100644 index 00000000..043ad68f --- /dev/null +++ "b/\346\214\207\346\225\260\345\271\263\350\241\241\347\255\226\347\225\245|Index Balance Bot.md" @@ -0,0 +1,110 @@ + +> 策略名称 + +指数平衡策略|Index Balance Bot + +> 策略作者 + +botvsing + +> 策略描述 + +This bot wuill maintain a specific proportion of each asset value as you set. +If you set ETH value to 25%(0.25) of portfolio, deviation to 0.1, bot will buy to 0.25 when the value ratio is below 0.9*0.25 and sell when it is above 1.1*0.25, thus, the ETH value is kept to a certain ratio. +Balancing more than one asset, you have to add trading pair separately, and ratios is input like "0.25|0.2|0.3". +Remember, the total ratio added up must lower than 1 and has a extra room to buy. + +指数平衡策略。可以将资产按预设比例进行平衡,支持跨交易所平衡。注意同意个交易所要相邻添加。 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Ratio|0.25|0.25|0.25|assets ratio(separate by "|")| +|BaseAsset|BTC|base currency| +|ToBuy|0.1|0.1|0.1|Deviation ratio to buy| +|ToSell|0.1|0.1|0.1|Deviation ratio to sell| +|Interval|60|check interval(second)| + + +> 源码 (javascript) + +``` javascript +var account = _C(exchanges[0].GetAccount); +var coinValue = {}; +var totalValue = 0; +function updateValue(){ + var logString = 'Time: '+ _D() + '\n'; + totalValue = 0; + coinValue[BaseAsset] = 0; + logString += BaseAsset + ': ' + _N(coinValue[BaseAsset].value,5) + '\n'; + for(var i=0;i 0 && exchanges[i].GetLabel != exchanges[i-1].GetLabel){ + coinValue[BaseAsset] += {amount:account.Balance + account.FrozenBalance, value:account.Balance + account.FrozenBalance}; + } + var ticker = _C(exchanges[i].GetTicker); + var symbol = exchanges[i].GetCurrency().split('_')[0]; + coinValue[symbol].amount = account.Stocks + account.FrozenStocks; + coinValue[symbol].value = coinValue[symbol].amount * ticker.Last; + totalValue += coinValue[symbol].value; + coinValue[symbol].buyPrice = ticker.Buy; + coinValue[symbol].sellPrice = ticker.Sell; + logString += symbol + ': ' + _N(coinValue[symbol].value,5) + '\n' + } + totalValue += coinValue[BaseAsset].value; + LogStatus(logString); +} +var keepPercent = Ratio.split('|').map(Number); +if(math.sum(keepPercent) > 1){ + throw 'sum of keep percent should be lower than 1'; +} +var buyPercent = ToBuy.split('|').map(Number); +var sellPercent = ToSell.split('|').map(Number); +for(var i=0;i (1+coinValue[symbol].sellPercent)*totalValue*coinValue[symbol].keepPercent){ + var sellAmount = (coinValue[symbol].value - totalValue*coinValue[symbol].keepPercent)/coinValue[symbol].buyPrice + exchanges[i].Sell(coinValue[symbol].buyPrice, sellAmount) + CancelPendingOrders(exchanges[i]); + } + else if(coinValue[symbol].value < (1-coinValue[symbol].buyPercent)*totalValue*coinValue[symbol].keepPercent){ + var buyAmount = (totalValue*coinValue[symbol].keepPercent - coinValue[symbol].value)/coinValue[symbol].sellPrice + exchanges[i].Buy(coinValue[symbol].sellPrice, buyAmount); + CancelPendingOrders(exchanges[i]); + } + } +} +function main() { + while(true){ + onTick(); + Sleep(Interval*1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/116012 + +> 更新时间 + +2018-10-17 12:09:51 diff --git "a/\346\214\207\346\225\260\351\207\217\345\214\226.js" "b/\346\214\207\346\225\260\351\207\217\345\214\226.md" similarity index 88% rename from "\346\214\207\346\225\260\351\207\217\345\214\226.js" rename to "\346\214\207\346\225\260\351\207\217\345\214\226.md" index 72c0eee9..016206cc 100644 --- "a/\346\214\207\346\225\260\351\207\217\345\214\226.js" +++ "b/\346\214\207\346\225\260\351\207\217\345\214\226.md" @@ -1,30 +1,39 @@ -/* -策略出处: https://www.fmz.com/strategy/91704 -策略名称: 指数量化 -策略作者: 6821281 -策略描述: - - - - -参数 默认值 描述 ----------- ----- -------------------------------- -junxianx true 均线值 -junxiant true 均线天数 -rise_fall 0 当前时间的前一小时或前一日收盘价: 请选择|小时|日 -rise_warn true 涨幅预警值 -fall_warn true 跌幅预警值 -macdwarn 8000 macd提醒值 -macdzhouqi 0 macd周期: 1分钟|5分钟|15分钟|30分钟|1小时|一天 -kdj1 9 周期1值 -kdj2 3 周期2值 -kdj3 3 周期3值 -kdjkwarn true k提醒值 -kdjdwarn true d提醒值 -kdjjwarn true j提醒值 -kdjtp 0 周期均线类型: 1分钟|5分钟|15分钟|30分钟|1小时|一天 -*/ +> 策略名称 + +指数量化 + +> 策略作者 + +6821281 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|junxianx|true|均线值| +|junxiant|true|均线天数| +|rise_fall|0|当前时间的前一小时或前一日收盘价: 请选择|小时|日| +|rise_warn|true|涨幅预警值| +|fall_warn|true|跌幅预警值| +|macdwarn|8000|macd提醒值| +|macdzhouqi|0|macd周期: 1分钟|5分钟|15分钟|30分钟|1小时|一天| +|kdj1|9|周期1值| +|kdj2|3|周期2值| +|kdj3|3|周期3值| +|kdjkwarn|true|k提醒值| +|kdjdwarn|true|d提醒值| +|kdjjwarn|true|j提醒值| +|kdjtp|0|周期均线类型: 1分钟|5分钟|15分钟|30分钟|1小时|一天| + + +> 源码 (javascript) + +``` javascript //均线模块 function juxian(){ @@ -220,3 +229,12 @@ function main() { // Log("第一根k线数据为,Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High, // "Low:", records[0].Close, "Volume:", records[0].Volume); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/91704 + +> 更新时间 + +2018-05-13 11:35:48 diff --git "a/\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241.js" "b/\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241.md" similarity index 94% rename from "\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241.js" rename to "\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241.md" index da310892..dd3ea7f8 100644 --- "a/\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241.js" +++ "b/\346\224\266\347\233\212\347\216\207\347\273\237\350\256\241.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/19329 -策略名称: 收益率统计 -策略作者: 春哥 -策略描述: + +> 策略名称 + +收益率统计 + +> 策略作者 + +春哥 + +> 策略描述 统计收益率 @@ -30,12 +35,18 @@ function main() { 上30日: 收200.12元(1.565%),月化1.567%,年化19.076%,回撤1.521% 总: 收4554.11元(45.541%),最大回撤3.251%,统计时间74天23小时 +> 策略参数 + + -参数 默认值 描述 -------------- ----- --------------------- -SYS_LOGPROFIT true 是否同时记录到系统自带的LogProfit -*/ +|参数|默认值|描述| +|----|----|----| +|SYS_LOGPROFIT|true|是否同时记录到系统自带的LogProfit| + +> 源码 (javascript) + +``` javascript $.LogProfit = function(profit) { var args = Array.prototype.slice.call(arguments); if (SYS_LOGPROFIT) { @@ -191,3 +202,12 @@ function main() { Sleep(3600000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/19329 + +> 更新时间 + +2016-08-11 11:41:36 diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).md" similarity index 95% rename from "\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" rename to "\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).md" index 4a7575f1..ee89f59b 100644 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).js" +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/57267 -策略名称: 数字货币交易类库 (期货支持OKCoin期货-BitVC, 支持$.CTA函数) -策略作者: 小小梦 -策略描述: + +> 策略名称 + +数字货币交易类库 (期货支持OKCoin期货-BitVC, 支持$.CTA函数) + +> 策略作者 + +小小梦 + +> 策略描述 数字货币交易类库 (期货支持OKCoin期货/BitVC) 目前测试阶段,使用请留意,如有问题 ,请联系作者 ,十分感谢! @@ -49,24 +54,30 @@ https://dn-filebox.qbox.me/1671268eba20870c7820542448dc0ef541d65a5b.png // 这样就 1000 美元价格 开多仓 合约 1张 ``` +> 策略参数 + -参数 默认值 描述 --------------- ----- -------------------------- -OpMode 0 现货-下单方式: 吃单|挂单 -MaxSpace 0.5 现货-挂单失效距离 -SlidePrice 0.1 现货-下单滑动价(元) -MaxAmount 0.8 现货-开仓最大单次下单量 -RetryDelay 500 现货-失败重试(毫秒) -MAType 0 现货-均线算法: EMA|MA|AMA(自适应均线) -Interval 300 期货—失败重试间隔(毫秒) -F_SlidePrice 2 期货—下单滑价(元) -lv 0.5 期货—滑价增长率 -max_open_lv true 期货—开仓滑价最大增长率 -max_cover_lv true 期货—平仓滑价最大增长率 -_GetMinStocks 0.01 最小交易数量 -isCTAshowTable false 是否显示 模板生成状态栏表格 -*/ +|参数|默认值|描述| +|----|----|----| +|OpMode|0|现货-下单方式: 吃单|挂单| +|MaxSpace|0.5|现货-挂单失效距离| +|SlidePrice|0.1|现货-下单滑动价(元)| +|MaxAmount|0.8|现货-开仓最大单次下单量| +|RetryDelay|500|现货-失败重试(毫秒)| +|MAType|0|现货-均线算法: EMA|MA|AMA(自适应均线)| +|Interval|300|期货—失败重试间隔(毫秒)| +|F_SlidePrice|2|期货—下单滑价(元)| +|lv|0.5|期货—滑价增长率| +|max_open_lv|true|期货—开仓滑价最大增长率| +|max_cover_lv|true|期货—平仓滑价最大增长率| +|_GetMinStocks|0.01|最小交易数量| +|isCTAshowTable|false|是否显示 模板生成状态栏表格| + + +> 源码 (javascript) + +``` javascript // 现货部分 function CancelPendingOrders(e, orderType) { while (true) { @@ -645,3 +656,12 @@ function main() { }) } +``` + +> 策略出处 + +https://www.fmz.com/strategy/57267 + +> 更新时间 + +2018-03-05 12:56:46 diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.py" "b/\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.md" similarity index 75% rename from "\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.py" rename to "\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.md" index 3a3388a6..40a6c011 100644 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.py" +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\345\256\232\346\212\225.md" @@ -1,8 +1,13 @@ -''' -策略出处: https://www.fmz.com/strategy/54256 -策略名称: 数字货币定投 -策略作者: ankye -策略描述: + +> 策略名称 + +数字货币定投 + +> 策略作者 + +ankye + +> 策略描述 数字货币通用定投策略,支持多交易所同时定投 @@ -16,15 +21,21 @@ maxBidPrice #最大交易价格,超过价格就跳过,等待下次交易机会出现 +> 策略参数 + + -参数 默认值 描述 ------------------ ----- ------------------- -orderAmount true order amount -maxBidPrice false max bid price -accountLimitMoney false account limit money -orderTimeInterval 60 Order Time Interval -''' +|参数|默认值|描述| +|----|----|----| +|orderAmount|true|order amount| +|maxBidPrice|false|max bid price| +|accountLimitMoney|false|account limit money| +|orderTimeInterval|60|Order Time Interval| + +> 源码 (python) + +``` python def onTick(): exchange_count = len(exchanges) @@ -51,3 +62,12 @@ def main() : onTick() time.sleep(orderTimeInterval) +``` + +> 策略出处 + +https://www.fmz.com/strategy/54256 + +> 更新时间 + +2017-09-08 14:43:38 diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" "b/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" deleted file mode 100644 index ddac8b71..00000000 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\347\216\260\350\264\247\344\272\244\346\230\223\347\261\273\345\272\223.js" +++ /dev/null @@ -1,397 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/10989 -策略名称: 数字货币现货交易类库 -策略作者: Zero -策略描述: - -暂时封装了以下几个函数 - -> $.GetAccount(e) - -``` -Log($.GetAccount()); // 获取账户信息, 带容错功能 -Log($.GetAcccount(exchanges[1])); -``` - -> $.Buy/Sell(e, amount) - -``` -$.Buy(0.3); // 主交易所买入0.3个币 -$.Sell(0.2); // 主交易所卖出0.2个币 -$.Sell(exchanges[1], 0.1); // 次交易所卖出0.1个币 -``` -> $.CancelPendingOrders(e, orderType) - -``` -$.CancelPendingOrders(); // 取消主交易所所有委托单 -$.CancelPendingOrders(ORDER_TYPE_BUY); // 取消主交易所所有的买单 -$.CancelPendingOrders(exchanges[1]); // 取消第二个交易所所有订单 -$.CancelPendingOrders(exchanges[1], ORDER_TYPE_SELL); // 取消第二个交易所所有的卖单 -``` - -> $.Cross(periodA, periodB) / $.Cross(arr1, arr2); - -``` -var n = $.Cross(15, 30); -var m = $.Cross([1,2,3,2.8,3.5], [3,1.9,2,5,0.6]) -``` - -``` text -如果 n 等于 0, 指刚好15周期的EMA与30周期的EMA当前价格相等 -如果 n 大于 0, 比如 5, 指15周期的EMA上穿了30周期的EMA 5个周期(Bar) -如果 n 小于 0, 比如 -12, 指15周期的EMA下穿了30周期的EMA 12个周期(Bar) -如果传给Cross不是数组, 则函数自动获取K线进行均线计算 -如果传给Cross的是数组, 则直接进行比较 -``` - -> $.withdraw(e, currency, address, amount, fee, password) 提现函数 - -``` -$.withdraw(exchange, "btc", "0x.........", 1.0, 0.0001, "***") -``` - - -参数 默认值 描述 ----------- ------- ----------------------- -OpMode 0 下单方式: 吃单|挂单 -MaxSpace 0.5 挂单失效距离 -SlidePrice 0.1 下单滑动价(元) -MaxAmount 0.8 开仓最大单次下单量 -RetryDelay 500 失败重试(毫秒) -MAType 0 均线算法: EMA|MA|AMA(自适应均线) -MinStock 0.001 最小交易量 -*/ - -$.withdraw = function(e, currency, address, amount, fee, password) { - var withdraw_id = null; - var ret = null; - currency = currency.toLowerCase() - switch (e.GetName()) { - case "OKCoin_EN": - ret = e.IO("api", "POST", "/api/v1/withdraw.do", "symbol="+currency.toLowerCase()+"_usd&chargefee=" + fee + "&trade_pwd=" + password + "&withdraw_address=" + address + "&withdraw_amount=" + amount); - if (ret && typeof(ret.withdraw_id) !== 'undefined') { - withdraw_id = ret.withdraw_id; - } else { - var err = GetLastError(); - if (err && err.indexOf('10031') !== -1) { - Log("OKCoin_EN 需6个网络确认后方能提现"); - } - } - break; - case "Huobi": - if (currency == "bch") { - currency = "bcc" - } - ret = e.IO("api", "POST", "/v1/dw/withdraw-virtual/create", "currency="+currency+"&fee=" + fee + "&address=" + address + "&amount=" + amount); - if (ret && typeof(ret.withdraw_id) !== 'undefined') { - withdraw_id = ret.data; - } - break; - case "Bithumb": - ret = e.IO("api", "POST", "/trade/btc_withdrawal", "currency="+currency.toUpperCase()+"&address=" + address + "&units=" + amount); - if (ret && parseInt(ret.status) == 0) { - withdraw_id = 9999; - } - break; - case "GateIO": - ret = e.IO("api", "POST", "/api2/1/private/withdraw", "currency="+currency+"&address=" + address + "&amount=" + amount); - if (ret && parseInt(ret.code) == 0) { - withdraw_id = 9999; - } - break; - case "ZB": - ret = e.IO("api", "POST", "/api/withdraw", "method=withdraw&itransfer=0¤cy="+currency+"&receiveAddr=" + address + "&amount=" + amount+"&fees="+fee+"&safePwd="+password); - if (ret && parseInt(ret.code) == 0) { - withdraw_id = ret.id; - } - break; - case "Bitfinex": - var cMap = { - "btc": "bitcoin", - "ltc": "litecoin", - "eth": "ethereum", - "etc": "ethereumc", - "zec": "zcash", - "xmr": "monero", - "omni": "mastercoin", - "usd": "wire", - "dash": "dash", - "xrp": "ripple", - "eos": "eos"}; - if (typeof(cMap[currency]) == 'undefined') { - throw "bitfinex not support " + currency; - } - var withdraw_type = cMap[currency]; - ret = e.IO("api", "POST", "/v1/withdraw", "withdraw_type=" + withdraw_type + "&walletselected=exchange&address=" + address + "&amount='" + amount + "'"); - if (ret && ret.length == 1 && typeof(ret[0].withdrawal_id) !== 'undefined') { - withdraw_id = ret[0].withdrawal_id; - } - break; - case "Poloniex": - var ext = ""; - if (currency == 'xrp') { - //ext = '&paymentId=' + PXRPLabel; - } - if (currency.toLowerCase() == 'bts' && address.indexOf('_') == -1) { - address = "poloniexwallet_" + address; - } - ret = e.IO("api", "POST", "withdraw", "amount=" + amount + "¤cy="+currency.toUpperCase()+"&address=" + address+ext); - if (ret && ret.response.indexOf('With') !== -1) { - withdraw_id = 9999; - } - break - case "Bittrex": - ret = e.IO("api", "GET", "/api/v1.1/account/withdraw", "quantity=" + amount + "¤cy="+currency.toUpperCase()+"&address=" + address); - if (ret && ret.success) { - withdraw_id = ret.result.uuid; - } - break - case "Binance": - ret = e.IO("api", "POST", "/wapi/v1/withdraw.html", "amount=" + amount + "&asset=" + currency + "&address=" + address); - if (ret && ret.success) { - withdraw_id = 9999; - } - break - case "OKEX": - ret = e.IO("api", "POST", "/api/v1/withdraw.do", "target=address&withdraw_amount=" + amount + "&symbol="+currency+"_usd&withdraw_address=" + address+"&chargefee="+fee+"&trade_pwd="+password); - if (ret && ret.result) { - withdraw_id = ret.withdraw_id; - } - break - default: - throw "不支持的操作"; - } - return {info: ret, withdraw_id: withdraw_id} -} - -function CancelPendingOrders(e, orderType) { - while (true) { - var orders = e.GetOrders(); - if (!orders) { - Sleep(RetryDelay); - continue; - } - var processed = 0; - for (var j = 0; j < orders.length; j++) { - if (typeof(orderType) === 'number' && orders[j].Type !== orderType) { - continue; - } - e.CancelOrder(orders[j].Id, orders[j]); - processed++; - if (j < (orders.length - 1)) { - Sleep(RetryDelay); - } - } - if (processed === 0) { - break; - } - } -} - -function GetAccount(e, waitFrozen) { - if (typeof(waitFrozen) == 'undefined') { - waitFrozen = false; - } - var account = null; - var alreadyAlert = false; - while (true) { - account = _C(e.GetAccount); - if (!waitFrozen || (account.FrozenStocks < MinStock && account.FrozenBalance < 0.01)) { - break; - } - if (!alreadyAlert) { - alreadyAlert = true; - Log("发现账户有冻结的钱或币", account); - } - Sleep(RetryDelay); - } - return account; -} - - -function StripOrders(e, orderId) { - var order = null; - if (typeof(orderId) == 'undefined') { - orderId = null; - } - while (true) { - var dropped = 0; - var orders = _C(e.GetOrders); - for (var i = 0; i < orders.length; i++) { - if (orders[i].Id == orderId) { - order = orders[i]; - } else { - var extra = ""; - if (orders[i].DealAmount > 0) { - extra = "成交: " + orders[i].DealAmount; - } else { - extra = "未成交"; - } - e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); - dropped++; - } - } - if (dropped === 0) { - break; - } - Sleep(RetryDelay); - } - return order; -} - -// mode = 0 : direct buy, 1 : buy as buy1 -function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, retryDelay) { - var initAccount = GetAccount(e, true); - var nowAccount = initAccount; - var orderId = null; - var prePrice = 0; - var dealAmount = 0; - var diffMoney = 0; - var isFirst = true; - var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell; - var isBuy = tradeType == ORDER_TYPE_BUY; - while (true) { - var ticker = _C(e.GetTicker); - var tradePrice = 0; - if (isBuy) { - tradePrice = _N((mode === 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4); - } else { - tradePrice = _N((mode === 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4); - } - if (!orderId) { - if (isFirst) { - isFirst = false; - } else { - nowAccount = GetAccount(e, true); - } - var doAmount = 0; - if (isBuy) { - diffMoney = _N(initAccount.Balance - nowAccount.Balance, 4); - dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 4); - doAmount = Math.min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance - 10) / tradePrice, 4)); - } else { - diffMoney = _N(nowAccount.Balance - initAccount.Balance, 4); - dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); - doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); - } - if (doAmount < MinStock) { - break; - } - prePrice = tradePrice; - orderId = tradeFunc(tradePrice, doAmount, ticker); - if (!orderId) { - CancelPendingOrders(e, tradeType); - } - } else { - if (mode === 0 || (Math.abs(tradePrice - prePrice) > maxSpace)) { - orderId = null; - } - var order = StripOrders(e, orderId); - if (!order) { - orderId = null; - } - } - Sleep(retryDelay); - } - - if (dealAmount <= 0) { - return null; - } - - return { - price: _N(diffMoney / dealAmount, 4), - amount: dealAmount - }; -} - -$.Buy = function(e, amount) { - if (typeof(e) === 'number') { - amount = e; - e = exchange; - } - return Trade(e, ORDER_TYPE_BUY, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); -}; - -$.Sell = function(e, amount) { - if (typeof(e) === 'number') { - amount = e; - e = exchange; - } - return Trade(e, ORDER_TYPE_SELL, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); -}; - -$.CancelPendingOrders = function(e, orderType) { - if (typeof(orderType) === 'undefined') { - if (typeof(e) === 'number') { - orderType = e; - e = exchange; - } else if (typeof(e) === 'undefined') { - e = exchange; - } - } - return CancelPendingOrders(e, orderType); -}; - -$.GetAccount = function(e) { - if (typeof(e) === 'undefined') { - e = exchange; - } - return _C(e.GetAccount); -}; - - -// 返回上穿的周期数. 正数为上穿周数, 负数表示下穿的周数, 0指当前价格一样 -$.Cross = function(a, b) { - var pfnMA = [TA.EMA, TA.MA, talib.KAMA][MAType]; - var crossNum = 0; - var arr1 = []; - var arr2 = []; - if (Array.isArray(a)) { - arr1 = a; - arr2 = b; - } else { - var records = null; - while (true) { - records = exchange.GetRecords(); - if (records && records.length > a && records.length > b) { - break; - } - Sleep(RetryDelay); - } - arr1 = pfnMA(records, a); - arr2 = pfnMA(records, b); - } - if (arr1.length !== arr2.length) { - throw "array length not equal"; - } - for (var i = arr1.length-1; i >= 0; i--) { - if (typeof(arr1[i]) !== 'number' || typeof(arr2[i]) !== 'number') { - break; - } - if (arr1[i] < arr2[i]) { - if (crossNum > 0) { - break; - } - crossNum--; - } else if (arr1[i] > arr2[i]) { - if (crossNum < 0) { - break; - } - crossNum++; - } else { - break; - } - } - return crossNum; -}; - -// 仅调试模板策略用 -function main() { - Log($.GetAccount()); - Log($.Buy(0.5)); - Log($.Sell(0.5)); - exchange.Buy(1000, 3); - $.CancelPendingOrders(exchanges[0]); - Log($.Cross(30, 7)); - Log($.Cross([1,2,3,2.8,3.5], [3,1.9,2,5,0.6])); -} diff --git "a/\346\226\260\346\211\213\344\270\212\350\267\257CoinEx\344\272\244\346\230\223 (LTC_USDT).md" "b/\346\226\260\346\211\213\344\270\212\350\267\257CoinEx\344\272\244\346\230\223 (LTC_USDT).md" new file mode 100644 index 00000000..6c063bb1 --- /dev/null +++ "b/\346\226\260\346\211\213\344\270\212\350\267\257CoinEx\344\272\244\346\230\223 (LTC_USDT).md" @@ -0,0 +1,317 @@ + +> 策略名称 + +新手上路CoinEx交易 (LTC_USDT) + +> 策略作者 + +yuehen7 + +> 策略描述 + +新手上路,研究了几天,简单的写了个...... + + +QQ:185772115 +可以交流交流呀~ + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|MinSpace|0.06|最小利润差价| +|MaxSpace|0.03|挂单失效距离| +|SlidePrice|0.01|下单滑动价| +|RetryDelay|500|失败重试| +|MinStock|0.001|最小交易量| +|OrderAmount|0.02|固定下单数量| +|Precision|2|小数精度| + + +> 源码 (javascript) + +``` javascript +function GetAccount(e, waitFrozen) { + if (typeof(waitFrozen) == 'undefined') { + waitFrozen = false; + } + var account = null; + var alreadyAlert = false; + while (true) { + account = _C(e.GetAccount); + if (!waitFrozen || (account.FrozenStocks < MinStock && account.FrozenBalance < 0.01)) { + break; + } + if (!alreadyAlert) { + alreadyAlert = true; + Log("发现账户有冻结的钱或币", account); + } + Sleep(RetryDelay); + } + return account; +} + +function CancelPendingOrders(e, orderType) { + while (true) { + var orders = e.GetOrders(); + if (!orders) { + Sleep(RetryDelay); + continue; + } + var processed = 0; + for (var j = 0; j < orders.length; j++) { + if (typeof(orderType) == 'number' && orders[j].Type != orderType) { + continue; + } + e.CancelOrder(orders[j].Id, orders[j]); + processed++; + if (j < (orders.length - 1)) { + Sleep(RetryDelay); + } + } + if (processed == 0) { + break; + } + } +} + +function StripOrders(e, tradeType, orderId) { + var dealAmount = 0; //返回交易数量,-1表示全部交易,0表示未交易,其他值表示部分交易 + if (typeof(orderId) == 'undefined') { + orderId = null; + } + var isBuy = tradeType == ORDER_TYPE_BUY; + while (true) { + logAccount(); + var order = null; + var orders = _C(e.GetOrders); //取出未完成订单 + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == orderId) { + order = orders[i]; + } + } + if (orders.length == 0 || order == null) { + dealAmount = -1; + break; + } else { + var ticker = _C(e.GetTicker); + var tradePrice = 0; + if (isBuy) { + tradePrice = _N(ticker.Buy + SlidePrice, Precision); + } else { + tradePrice = _N(ticker.Sell - SlidePrice, Precision); + } + var price = order.Price; + if (Math.abs(tradePrice - price) > MaxSpace) { //超过最大挂单区间 + var extra = ""; + if (order.DealAmount > 0) { + dealAmount = order.DealAmount; + extra = "订单id:" + order.Id + ",成交: " + order.DealAmount; + } else { + dealAmount = 0; + extra = "订单id:" + order.Id + ",未成交"; + } + var flag = e.CancelOrder(order.Id, order.Type == ORDER_TYPE_BUY ? "买入-" : "卖出-", extra, ' #C9C9C9'); + Log('取消订单:', flag, ' #ff0000'); + if (flag) { + break; + } + } + } + Sleep(RetryDelay); + } + return dealAmount; +} + +function Trade(e, tradeType, ordPrice, tradeAmount) { + var ret = null; + var nowAccount = GetAccount(e, true); + var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell; + var isBuy = tradeType == ORDER_TYPE_BUY; + + var doAmount = 0; + if (isBuy) { + doAmount = Math.min(tradeAmount, _N(nowAccount.Balance / ordPrice, 6)); + } else { + doAmount = Math.min(tradeAmount, nowAccount.Stocks); + } + if (doAmount == MinStock) {} else if (doAmount < tradeAmount) { + Log('固定下单量:', tradeAmount, ',当前可交易:', doAmount, ' #9400D3'); + ret = { + price: ordPrice, + amount: -1 + }; + return ret; + } + logAccount(); + var orderId = tradeFunc(ordPrice, tradeAmount); + if (!orderId) { + CancelPendingOrders(e, tradeType); + ret = { + price: ordPrice, + amount: 0 + }; + } else { + var amount = StripOrders(e, tradeType, orderId); //-1成交,0全撤,大于0表示部分成交的数量 + if (amount < 0) { + ret = { + price: ordPrice, + amount: tradeAmount + }; + } else { + ret = { + price: ordPrice, + amount: amount + }; + } + } + logAccount(); + return ret; +} + +var ini_blance = 0; +var ini_stocks = 0; +var ini_cet = 0; +var count = 0; +var usdt_Profit = 0.0; +var BuyInfo; //买单信息 +var SellCet = 0; + +function OrderPrice(e) { + var ticker = _C(e.GetTicker); + var c = _N(ticker.Sell - ticker.Buy, 6); + var buyPrice = 0; + var sellPrice = 0; + if (c > MinSpace) { + buyPrice = _N(((ticker.Buy + ticker.Sell) / 2) - SlidePrice * 2, Precision); + sellPrice = _N(((ticker.Buy + ticker.Sell) / 2) + SlidePrice * 2, Precision); + } else if (c >= (2 * SlidePrice)) { + buyPrice = _N(ticker.Buy + SlidePrice, Precision); + sellPrice = _N(ticker.Sell - SlidePrice, Precision); + } else { + buyPrice = _N(ticker.Last, Precision); + sellPrice = _N(ticker.Last, Precision); + } + + if (BuyInfo != null && BuyInfo.amount > 0) { + var space = Math.abs(BuyInfo.price - sellPrice) + if (space > MaxSpace && space <= (MaxSpace * 1.5)) { //卖价小于买价-挂单距离 + sellPrice = _N(BuyInfo.price - MaxSpace, Precision); + } else if(space > (MaxSpace * 1.5)) { + sellPrice = _N(BuyInfo.price - MaxSpace * 1.5, Precision); + } + } + count = count + 1; + Log('计数器:', count, '计划买价:', buyPrice, ',计划卖价:', sellPrice, ' #f47920'); + logAccount(); + return { + buy: buyPrice, + sell: sellPrice + }; +} + +logAccount = function() { + var ex1 = exchanges[0]; //交易主账户 + var ex2 = exchanges[1]; //收益账户 + + var ticker = _C(ex1.GetTicker); + var nowBlance = _C(ex1.GetAccount); + var account2 = _C(ex2.GetAccount); + var cet = account2.Stocks; + + var table = { + type: 'table', + title: '持仓信息', + cols: ['当前价格', '初始CET', '初始USDT', '初始LTC', '当前USDT', '当前LTC', '冻结USDT', '冻结LTC', '当前CET', 'USDT收益', '当前CET收益', '卖出CET'], + rows: [ + [ticker.Last, ini_cet, ini_blance, ini_stocks, nowBlance.Balance, nowBlance.Stocks, nowBlance.FrozenBalance, nowBlance.FrozenStocks, cet, _N(usdt_Profit, 6), _N(cet - ini_cet, 8), SellCet] + ] + }; + LogStatus('`' + JSON.stringify(table) + '`\n\n新手上路,写着玩的......'); +} + +function onTick(e) { + var prices = OrderPrice(e); + var buyPrice = prices.buy; + var sellPrice = prices.sell; + var sellInfo; + + if (BuyInfo == null) { //没有买单先开买单 + var buyInfo = Trade(e, ORDER_TYPE_BUY, buyPrice, OrderAmount); + if (buyInfo != null && buyInfo.amount > 0) { + BuyInfo = buyInfo; + } else if (buyInfo.amount < 0) { + Log('购买余额不足,自动卖出平衡...... #d71345'); + Trade(e, ORDER_TYPE_SELL, -1, MinStock); + } + } + if (BuyInfo != null) { + sellInfo = Trade(e, ORDER_TYPE_SELL, sellPrice, BuyInfo.amount); + } else { + sellInfo = Trade(e, ORDER_TYPE_SELL, sellPrice, OrderAmount); + } + + if (BuyInfo != null && sellInfo != null && sellInfo.amount > 0) { + var profit = _N(sellInfo.amount * (sellInfo.price - BuyInfo.price), 6); + Log('买价为:', BuyInfo.price, '卖出价为:', sellInfo.price, '盈利:', profit, ' #d71345'); + usdt_Profit += profit; + LogProfit(usdt_Profit); + BuyInfo = null; + } else if (BuyInfo != null && sellInfo.amount < 0) { //有买单并且卖出数量不足时才需要平衡数量 + Log('卖出数量不足,自动买入平衡...... #d71345'); + Trade(e, ORDER_TYPE_BUY, -1, MinStock); + } + logAccount(); +} + +function autoSellCet(e) { + var account = _C(e.GetAccount); + var cet = account.Stocks; + var profit = _N(cet - ini_cet); + if (profit > 1 && (profit % 3) == 0) { + var orderId = e.Sell(-1, 1); + if (!orderId) { + CancelPendingOrders(e, ORDER_TYPE_SELL); + } + SellCet += 1; + Log('自动卖出CET:', 1, ' #FF00FF'); + } +} + +function main() { + LogReset(); + LogProfitReset(); + + if (exchanges.length == 2) { + var ex1 = exchanges[0]; //交易主账户 + var ex2 = exchanges[1]; //收益账户 + + var iniAccount = _C(ex1.GetAccount); + ini_blance = iniAccount.Balance; + ini_stocks = iniAccount.Stocks; + + var account2 = _C(ex2.GetAccount); + ini_cet = account2.Stocks; + Log('主交易账户:', ex1.GetCurrency(), ',结算单位:', ex1.GetQuoteCurrency(), ' #ff0000'); + Log('子交易账户:', ex2.GetCurrency(), ',结算单位:', ex2.GetQuoteCurrency(), ' #ff0000'); + Log('账户初始余额:', ini_blance, ',初始货币数量:', ini_stocks, ',初始CET数量:', ini_cet, ' #ff0000'); + + count = 0; + while (true) { + onTick(ex1, ex2); + autoSellCet(ex2); + Sleep(1000); + } + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/103464 + +> 更新时间 + +2018-07-07 15:13:14 diff --git "a/\346\226\260\346\211\213\345\205\245\351\227\250\344\271\213 - \344\270\213\344\271\260\345\215\225\345\215\226\345\215\225.js" "b/\346\226\260\346\211\213\345\205\245\351\227\250\344\271\213 - \344\270\213\344\271\260\345\215\225\345\215\226\345\215\225.js" deleted file mode 100644 index 65b9bf51..00000000 --- "a/\346\226\260\346\211\213\345\205\245\351\227\250\344\271\213 - \344\270\213\344\271\260\345\215\225\345\215\226\345\215\225.js" +++ /dev/null @@ -1,20 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/796 -策略名称: 新手入门之 - 下买单卖单 -策略作者: Zero -策略描述: - -新手入门之 - 下买单卖单 - - -参数 默认值 描述 ------ ----- ----------- -Type 0 订单类型: 买单|卖单 -Price 25.08 价格 -Num true 数量 -*/ - -function main() { - Log('账户信息:', exchange.GetAccount()); - Type == 0 ? exchange.Buy(Price, Num) : exchange.Sell(Price, Num); -} diff --git "a/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245.md" "b/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245.md" new file mode 100644 index 00000000..80ff1964 --- /dev/null +++ "b/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245.md" @@ -0,0 +1,65 @@ + +> 策略名称 + +日本云图简化版策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略名称:日本云图简化版策略 +- 支持:商品期货 +- 适用周期:多周期 +- 官方网站:WWW.QUANT.LA + + /upload/asset/8f499518ffb1876478917e564e9b7a71.png + +- 主图: + 无 + +- 副图: + 无 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N1|10|收盘价周期1| +|N4|177|收盘价周期2| +|N2|41|开盘价周期1| +|N3|52|开盘价周期2| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-06-01 00:00:00 +end: 2018-09-25 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +*) + +//交易条件 +CONDITION1:=REF(CLOSE,1) > REF(CLOSE,N1) AND REF(CLOSE,8) > REF(CLOSE,N4) AND CLOSE > OPEN AND REF(CLOSE,137)>REF(OPEN,N2) AND CLOSE > REF(OPEN,N3); +CONDITION2:=REF(CLOSE,1) < REF(CLOSE,N1) AND REF(CLOSE,8) < REF(CLOSE,N4) AND CLOSE < OPEN AND REF(CLOSE,137) 策略出处 + +https://www.fmz.com/strategy/129083 + +> 更新时间 + +2018-12-07 10:48:01 diff --git "a/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245.md" "b/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245.md" new file mode 100644 index 00000000..c4592e7a --- /dev/null +++ "b/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245.md" @@ -0,0 +1,80 @@ + +> 策略名称 + +标准差价格通道策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 数据周期:30分钟左右 +- 支持 数字货币现货、数字货币期货 +- 支持 商品期货,适合品种:热卷、焦炭、豆粕、郑醇、沪镍、郑油、聚丙烯、螺纹、橡胶、锰硅、PTA、豆油 +- 官方网站:www.quant.la + +商品期货回测 +/upload/asset/f58bc64ccfc4dca7cc1905b238f07dd7.png + +数字货币回测 +/upload/asset/5a92307691b3946e7bc5be0cb58a1e26.png + +- 主图: + 上线, 公式 : UPPERBAND^^AVGVALUE + SHIFTVALUE; + 下线, 公式 : LOWERBAND^^AVGVALUE - SHIFTVALUE; + +- 副图: + 标准差,公式:STDS:STD(C,10); + 标准差,公式:STDL:STD(C,60); + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|STOPRANGE|true|止损幅度| +|N|20|均线参数| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-05-01 00:00:00 +end: 2018-06-30 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}] +args: [["ContractType","this_week",126961]] +*) + +TPRICE:=(HIGH+LOW+OPEN+CLOSE)/4; +AVGVALUE:=MA(TPRICE,N); +//求最高价减去最低价,一个周期前的收盘价减去最高价的绝对值,一个周期前的收盘价减去最低价的绝对值,这三个值中的最大值 +TR:=MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW)); +SHIFTVALUE:=MA(TR,N);//求N个周期内的TR的简单移动平均 +UPPERBAND^^AVGVALUE + SHIFTVALUE; +LOWERBAND^^AVGVALUE - SHIFTVALUE; +STDS:STD(C,10); +STDL:STD(C,60); + +BKVOL=0 AND HIGH >= UPPERBAND AND STDS>=STDL,BPK; +SKVOL=0 AND LOW <= LOWERBAND AND STDS>=STDL,SPK; +BKVOL>0 AND BKHIGH-BKPRICE>=0.2*CLOSE AND C0 AND SKPRICE-SKLOW>=0.2*CLOSE AND C>UPPERBAND,BP; + +//止损 +C>=SKPRICE*(1+STOPRANGE*0.01),BP; +C<=BKPRICE*(1-STOPRANGE*0.01),SP; + +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/128121 + +> 更新时间 + +2018-12-05 10:53:14 diff --git "a/\346\243\200\346\237\245https:--quant.la-Argus-\346\230\257\345\220\246\346\255\243\345\270\270.md" "b/\346\243\200\346\237\245https:--quant.la-Argus-\346\230\257\345\220\246\346\255\243\345\270\270.md" new file mode 100644 index 00000000..a8a46344 --- /dev/null +++ "b/\346\243\200\346\237\245https:--quant.la-Argus-\346\230\257\345\220\246\346\255\243\345\270\270.md" @@ -0,0 +1,36 @@ + +> 策略名称 + +检查https:--quant.la-Argus-是否正常 + +> 策略作者 + +botvsing + + + + + +> 源码 (python) + +``` python +import urllib2 +def main(): + Log("开始检查@") + while True: + try: + urllib2.urlopen("https://quant.la/API/Argus/predict", timeout=15) + Log("服务正常") + except: + Log(_D()," 服务异常@") + Sleep(10*60*1000) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/100344 + +> 更新时间 + +2018-06-22 10:29:01 diff --git "a/\346\250\241\346\213\237\346\265\213\350\257\225kdj.md" "b/\346\250\241\346\213\237\346\265\213\350\257\225kdj.md" new file mode 100644 index 00000000..6792dbc8 --- /dev/null +++ "b/\346\250\241\346\213\237\346\265\213\350\257\225kdj.md" @@ -0,0 +1,442 @@ + +> 策略名称 + +模拟测试kdj + +> 策略作者 + +zhiyuanfirst + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|OpMode|0|下单方式: 吃单|挂单| +|MaxSpace|0.5|挂单失效距离| +|SlidePrice|0.1|下单浮动价| +|MaxAmount|0.8|开仓单次最大下单量| +|RetryDelay|500|失败重试毫秒| +|MAType|0|均线类型: TA.EMA|TA.MA| +|_GetMinStocks|0.01|最小交易量| + + +> 源码 (python) + +``` python +import types # 导入类型模块 +import time # 导入时间模块 +import platform # 版本信息 + +versionMainValue = None +isFirstCheck = True +def typeOfstr(str): + if str == "list": + if versionMainValue == 2: + return types.ListType + elif versionMainValue == 3: + return list + elif str == "int": + if versionMainValue == 2: + return types.IntType + elif versionMainValue == 3: + return int + elif str == "float": + if versionMainValue == 2: + return types.FloatType + elif versionMainValue == 3: + return float + else: + Log("error , typeOfstr used false") + +def CheckVersion(): + global versionMainValue,isFirstCheck + platformInfo = platform.python_version() + if platformInfo[0] == '2': + Log("您使用的托管者 python编译环境的python版本是",platformInfo) + versionMainValue = 2 + elif platformInfo[0] == '3': + Log("您使用的托管者 python编译环境的python版本是",platformInfo) + versionMainValue = 3 + else: + Log("其它版本") + isFirstCheck = False + +def CancelPendingOrders(e, orderType = "") : # 取消所有未完成挂单 + while True: # 循环 + orders = e.GetOrders() + LogStatus("orders:",orders,time.time()) # 测试 + if(type(orders) != typeOfstr("list")): + Sleep(RetryDelay) + continue + processed = 0 + for j in range(len(orders)): + if (type(orderType) == typeOfstr("int") and orders[j].Type != orderType): + continue + e.CancelOrder(orders[j].Id,orders[j]) + processed += 1 + if (j < (len(orders) - 1)): + Sleep(RetryDelay) + if(processed == 0): + break + +def GetAccount(e, waitFrozen = False): + account = null + alreadyAlert = False + while True: + account = _C(e.GetAccount) + if(not waitFrozen or (account.FrozenStocks < _GetMinStocks and account.FrozenBalance < 0.01)): + break + if(not alreadyAlert): + alreadyAlert = True + Log("发现账户有冻结的钱或币",account) + Sleep(RetryDelay) + return account + +def StripOrders(e,orderId = null): + order = null + while True: + dropped = 0 + orders = _C(e.GetOrders) + for i in range(len(orders)): + if(orders[i].Id == orderId): + order = orders[i] + else: + extra = "" + if(orders[i].DealAmount > 0): + extra = "成交:" + str(orders[i].DealAmount) + else: + extra = "未成交" + e.CancelOrder(orders[i].Id,"买单" if orders[i].Type == ORDER_TYPE_BUY else "卖单",extra) + dropped += 1 + if(dropped == 0): + break + Sleep(RetryDelay) + return order + +def Trade(e,tradeType,tradeAmount,mode,slidePrice,maxAmount,maxSpace,retryDelay): + initAccount = GetAccount(e,True) + nowAccount = initAccount + orderId = null + prePrice = 0.0 + dealAmount = 0.0 + diffMoney = 0.0 + isFirst = True + tradeFunc = e.Buy if tradeType == ORDER_TYPE_BUY else e.Sell + isBuy = (tradeType == ORDER_TYPE_BUY) + while True: + ticker = _C(e.GetTicker) + tradePrice = 0.0 + if(isBuy): + tradePrice = _N((ticker.Sell if mode == 0 else ticker.Buy) + slidePrice,4) + else: + tradePrice = _N((ticker.Buy if mode == 0 else ticker.Sell) - slidePrice,4) + if(not orderId): + if(isFirst): + isFirst = False + else: + nowAccount = GetAccount(e,True) + doAmount = 0.0; + if(isBuy): + diffMoney = _N(initAccount.Balance - nowAccount.Balance,4) + dealAmount = _N(nowAccount.Stocks - initAccount.Stocks,4) + doAmount = min(maxAmount,tradeAmount - dealAmount,_N((nowAccount.Balance - 10) / tradePrice,4)) + else: + diffMoney = _N(nowAccount.Balance - initAccount.Balance,4) + dealAmount = _N(initAccount.Stocks - nowAccount.Stocks,4) + doAmount = min(maxAmount,tradeAmount - dealAmount,nowAccount.Stocks) + if(doAmount < _GetMinStocks): + break + prePrice = tradePrice + orderId = tradeFunc(tradePrice,doAmount,ticker) + if(not orderId): + CancelPendingOrders(e,tradeType) + else: + if(mode == 0 or (abs(tradePrice - prePrice) > maxSpace)): + orderId = null + order = StripOrders(e,orderId) + if(not order): + orderId = null + Sleep(retryDelay) + if(dealAmount <= 0): + Log("交易失败--TradeType:","buy" if tradeType == ORDER_TYPE_BUY else "sell"," ,diffMoney:",diffMoney," ,dealAmount",dealAmount," ,doAmount",doAmount) + return null + + ret = {'price': _N(diffMoney/dealAmount,4),'amount':dealAmount} + return ret + # 调用时 这样写 ret['price'] 、 ret['amount'] + +def _Buy(e = exchange,amount = 0): + if isFirstCheck: + CheckVersion() + if (type(e) == typeOfstr("int") or type(e) == typeOfstr("float")): + amount = e + e = exchange + return Trade(e,ORDER_TYPE_BUY,amount,OpMode,SlidePrice,MaxAmount,MaxSpace,RetryDelay) + +def _Sell(e = exchange,amount = 0): + if isFirstCheck: + CheckVersion() + if (type(e) == typeOfstr("int") or type(e) == typeOfstr("float")): + amount = e + e = exchange + return Trade(e,ORDER_TYPE_SELL,amount,OpMode,SlidePrice,MaxAmount,MaxSpace,RetryDelay) + +def _CancelPendingOrders(e = exchange,orderType = ""): + if isFirstCheck: + CheckVersion() + return CancelPendingOrders(e,orderType) + +def _GetAccount(e = exchange): + if isFirstCheck: + CheckVersion() + return _C(e.GetAccount) + +_MACalcMethod = [TA.EMA,TA.MA][MAType] +Interval = 200 +def Cross(a,b): + if isFirstCheck: + CheckVersion() + crossNum = 0 + arr1 = [] + arr2 = [] + if type(a) == typeOfstr("list") and type(b) == typeOfstr("list"): + arr1 = a + arr2 = b + else: + records = null + while True: + records = exchange.GetRecords() + if records and len(records) > a and len(records) > b: + break + Sleep(Interval) + arr1 = _MACalcMethod(records,a) + arr2 = _MACalcMethod(records,b) + if len(arr1) != len(arr2): + raise Exception("array length not equal") + for i in range(len(arr1) - 1,-1,-1): + if (type(arr1[i]) != typeOfstr("int") and type(arr1[i]) != typeOfstr("float")) or (type(arr2[i]) != typeOfstr("int") and type(arr2[i]) != typeOfstr("float")): + break + if arr1[i] < arr2[i] : + if crossNum > 0 : + break + crossNum -= 1 + elif arr1[i] > arr2[i] : + if crossNum < 0 : + break + crossNum += 1 + else: + break + return crossNum + + +# 导出函数 +ext.Buy = _Buy +ext.Sell = _Sell +ext.CancelPendingOrders = _CancelPendingOrders +ext.GetAccount = _GetAccount +ext.Cross = Cross + +_G("status", 'none') +_G("valueJ", 0) +_G("count", 0) +_G("buy_type","default") +ZERO = 1e-9 +# 点 +class Point(object): + + def __init__(self, x, y): + self.x, self.y = x, y + +# 向量 +class Vector(object): + + def __init__(self, start_point, end_point): + self.start, self.end = start_point, end_point + self.x = end_point.x - start_point.x + self.y = end_point.y - start_point.y + +def negative(vector): + """取反""" + return Vector(vector.end, vector.start) + +def vector_product(vectorA, vectorB): + '''计算 x_1 * y_2 - x_2 * y_1''' + return vectorA.x * vectorB.y - vectorB.x * vectorA.y + +def is_intersected(A, B, C, D): + '''A, B, C, D 为 Point 类型''' + AC = Vector(A, C) + AD = Vector(A, D) + BC = Vector(B, C) + BD = Vector(B, D) + CA = negative(AC) + CB = negative(BC) + DA = negative(AD) + DB = negative(BD) + + return (vector_product(AC, AD) * vector_product(BC, BD) <= ZERO) \ + and (vector_product(CA, CB) * vector_product(DA, DB) <= ZERO) + + + +# 测试 +def onTick2(): + records = exchange.GetRecords(PERIOD_H1) + #Log("第一根k线数据为,Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High,"Low:", records[0].Close, "Volume:", records[0].Volume); + + #Log("第二根k线数据为,Time:", records[len(records)-1].Time, "Open:", records[1].Open, "High:", records[1].High,"Low:", records[1].Close, "Volume:", records[1].Volume); + kdj = TA.KDJ(records, 9, 3, 3) + k = kdj[0] + d = kdj[1] + j = kdj[2] + if len(k) == len(d) == len(j): + length = len(k) + + if k[length-1] is None or d[length-1] is None or j[length-1] is None: + return + if _G("buy_type") == "block" and j[length-1] > 0: + _G("buy_type", "default") + + if _G("status") != 'buy' and j[length-1] < 0: + if j[length-1] < -100: + _G("buy_type", "black") + + + if _G("buy_type") == "default": + #buy + ext.Buy(0.1) + _G("status", "buy") + Log("buy:k,d,j", k[length-1], d[length-1], j[length-1]) + + if _G("status") == 'buy' and j[length-1] > 100: + #sell + ext.Sell(0.1) + _G("status", "sell") + Log("sell:k,d,j", k[length-1], d[length-1], j[length-1]) + +def onTick1(): + status = 'none' + Log(exchange.GetAccount()) + records = exchange.GetRecords(PERIOD_D1) + kdj = TA.KDJ(records, 9, 3, 3) + k = kdj[0] + d = kdj[1] + j = kdj[2] + Log("kdj:", k, d, j) + if len(k) == len(d) == len(j): + length = len(k) + Log("length:", length) + if k[length-1] is None or d[length-1] is None or j[length-1] is None: + return + if k[length-2] is None or d[length-2] is None or j[length-2] is None: + return + if k[length-3] is None or d[length-3] is None or j[length-3] is None: + return + + valueJ = _G("valueJ") + if valueJ > 0 and j[length-1] > 0 or valueJ < 0 and j[length-1] < 0: + count = _G("count") + count = count + 1 + _G("count", count) + else: + _G("count", 0) + + _G("valueJ", j[length-1]) + + k1 = Point(length-2, k[length-2]) + d1 = Point(length-2, d[length-2]) + j1 = Point(length-2, j[length-2]) + + k2 = Point(length-1, k[length-1]) + d2 = Point(length-1, d[length-1]) + j2 = Point(length-1, j[length-1]) + + k3 = Point(length-3, k[length-3]) + d3 = Point(length-3, d[length-3]) + j3 = Point(length-3, j[length-3]) + + resultJ = (j2.y-j3.y) / (j2.x - j3.x) + resultJ2 = (j1.y-j3.y) / (j1.x - j3.x) + if (_G("status") != 'buy' and resultJ > 0 and resultJ2 > 0 + and j[length-1] > k[length-1] and j[length-1] > d[length-1] + and j[length-2] > k[length-2] and j[length-2] > d[length-2] + and j[length-3] > k[length-3] and j[length-3] > d[length-3]): + # 买点 + ext.Buy(0.1) + _G("status", "buy") + Log("buy:k,d,j", k[length-1], d[length-1], j[length-1]) + + if _G("status") == 'buy' and resultJ < 0 and resultJ2 < 0: + # 卖点 + ext.Sell(0.1) + _G("status", "sell") + Log("sell:k,d,j", k[length-1], d[length-1], j[length-1]) + + + + + +def onTick(): + Log(exchange.GetAccount()) + records = exchange.GetRecords(PERIOD_D1) + kdj = TA.KDJ(records, 9, 3, 3) + k = kdj[0] + d = kdj[1] + j = kdj[2] + Log("kdj:", k, d, j) + if len(k) == len(d) == len(j): + k1 = Point(0, 0) + d1 = Point(0, 0) + j1 = Point(0, 0) + for i in range(0, len(k)): + if k[i] is None or d[i] is None or j[i] is None: + continue + if i > 0: + if k[i-1] is None or d[i-1] is None or j[i-1] is None: + continue + k1 = Point(i-1, k[i-1]) + d1 = Point(i-1, d[i-1]) + j1 = Point(i-1, j[i-1]) + + k2 = Point(i, k[i]) + d2 = Point(i, d[i]) + j2 = Point(i, j[i]) + + if is_intersected(k1,k2,d1,d2) and is_intersected(d1,d2,j1,j2) and is_intersected(j1,j2,k1,k2): + # k,d,j三线相交 + resultJ = (j2.y-j1.y) / (j2.x - j1.x) + if resultJ > 0 and j[i] > k[i] and j[i] > k[i]: + # 买点 + ext.Buy(0.1) + status = 'buy' + Log("buy:k,d,j", k[i], d[i], j[i]) + + if resultJ < 0 and j[i] < k[i] and j[i] < k[i]: + # 卖点 + ext.Sell(0.1) + status = 'sell' + Log("sell:k,d,j", k[i], d[i], j[i]) + + + else: + Log("kdj not len equal") + + +def main(): + while True: + onTick2() + Sleep(15*60*1000) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/119057 + +> 更新时间 + +2018-09-30 11:30:25 diff --git "a/\346\250\241\346\235\277\345\272\223\344\275\277\347\224\250\344\276\213\345\255\220.js" "b/\346\250\241\346\235\277\345\272\223\344\275\277\347\224\250\344\276\213\345\255\220.js" deleted file mode 100644 index 945508db..00000000 --- "a/\346\250\241\346\235\277\345\272\223\344\275\277\347\224\250\344\276\213\345\255\220.js" +++ /dev/null @@ -1,19 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/10991 -策略名称: 模板库使用例子 -策略作者: Zero -策略描述: - -模板库使用例子 - - -参数 默认值 描述 ------- ----- -------- -OType 0 买或卖: 买|卖 -Amount 0.5 下单量 -*/ - - -function main() { - Log(OType === 0 ? $.Buy(Amount) : $.Sell(Amount)); -} diff --git "a/\346\250\241\346\235\277\345\272\223\344\275\277\347\224\250\344\276\213\345\255\220.md" "b/\346\250\241\346\235\277\345\272\223\344\275\277\347\224\250\344\276\213\345\255\220.md" new file mode 100644 index 00000000..fd1d43cd --- /dev/null +++ "b/\346\250\241\346\235\277\345\272\223\344\275\277\347\224\250\344\276\213\345\255\220.md" @@ -0,0 +1,39 @@ + +> 策略名称 + +模板库使用例子 + +> 策略作者 + +Zero + +> 策略描述 + +模板库使用例子 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|OType|0|买或卖: 买|卖| +|Amount|0.5|下单量| + + +> 源码 (javascript) + +``` javascript + +function main() { + Log(OType === 0 ? $.Buy(Amount) : $.Sell(Amount)); +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/10991 + +> 更新时间 + +2016-02-20 22:13:47 diff --git "a/\346\257\2171\345\210\206\351\222\237\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\345\267\256\344\273\267(by JackConan).js" "b/\346\257\2171\345\210\206\351\222\237\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\345\267\256\344\273\267(by JackConan).md" similarity index 85% rename from "\346\257\2171\345\210\206\351\222\237\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\345\267\256\344\273\267(by JackConan).js" rename to "\346\257\2171\345\210\206\351\222\237\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\345\267\256\344\273\267(by JackConan).md" index f4de43f2..5bdd9236 100644 --- "a/\346\257\2171\345\210\206\351\222\237\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\345\267\256\344\273\267(by JackConan).js" +++ "b/\346\257\2171\345\210\206\351\222\237\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\345\267\256\344\273\267(by JackConan).md" @@ -1,14 +1,22 @@ -/* -策略出处: https://www.fmz.com/strategy/98 -策略名称: 每1分钟统计各个平台间的差价(by JackConan) -策略作者: yzl_126@126.com -策略描述: + +> 策略名称 + +每1分钟统计各个平台间的差价(by JackConan) + +> 策略作者 + +yzl_126@126.com + +> 策略描述 统计各个平台间的最大差价; 如果要打印当时各交易所的市场行情,可以把 //printCurPrice(); 前面的注释//去掉; -*/ + +> 源码 (javascript) + +``` javascript var maxSpace = 0; function adjustFloat(v) { @@ -58,3 +66,12 @@ function main() { Sleep(60000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/98 + +> 更新时间 + +2014-07-20 14:52:55 diff --git "a/\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.js" "b/\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.md" similarity index 97% rename from "\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.js" rename to "\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.md" index 8aa092ef..b4e1e810 100644 --- "a/\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.js" +++ "b/\346\257\224\347\211\271\345\270\201\347\216\260\350\264\247\351\230\266\346\242\257\345\267\256\344\273\267\345\257\271\345\206\262.md" @@ -1,22 +1,33 @@ -/* -策略出处: https://www.fmz.com/strategy/30573 -策略名称: 比特币现货阶梯差价对冲 -策略作者: 我要发 -策略描述: + +> 策略名称 + +比特币现货阶梯差价对冲 + +> 策略作者 + +我要发 + +> 策略描述 阶梯差价对冲,新手策略 +> 策略参数 + + -参数 默认值 描述 ----------- ----- ----- -jizhun true 基准 -fanwei 5 范围 -maxliang 0.5 最大下单 -xianbijia 6000 最近的币价 -lirun true 利润 -zhanghushu 12 账户数量 -*/ +|参数|默认值|描述| +|----|----|----| +|jizhun|true|基准| +|fanwei|5|范围| +|maxliang|0.5|最大下单| +|xianbijia|6000|最近的币价| +|lirun|true|利润| +|zhanghushu|12|账户数量| + +> 源码 (javascript) + +``` javascript function main() { var dongjieqian = 0; @@ -477,3 +488,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/30573 + +> 更新时间 + +2017-01-26 22:10:43 diff --git "a/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245.md" "b/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245.md" new file mode 100644 index 00000000..eeb3f3ba --- /dev/null +++ "b/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245.md" @@ -0,0 +1,72 @@ + +> 策略名称 + +波动率ATR轨道突破策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 公式名称:波动率轨道突破策略 +- 数据周期:15M,30M等 +- 支持:商品期货、数字货币现货、数字货币期货 +- 官方网站:www.quant.la + +/upload/asset/36b0e279ae314411a9d6b7e94a0623f0.png + +- 主图: + 中轨,公式:MIDLINE^^MA((H + L + C)/3,LENGTH1); + 上轨,公式:UPBAND^^MIDLINE + N*ATR; + 下轨,公式:DOWNBAND^^MIDLINE - N*ATR; + + +- 副图: + 波动率,公式:ATR:=MA(TR,LENGTH2); + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|LENGTH2|100|ATR指标参数| +|LENGTH1|300|均线指标参数| +|N|2|上下轨系数| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-07-01 00:00:00 +end: 2018-09-17 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["LENGTH2",30],["LENGTH1",100],["ContractType","rb888",126961]] +*) + +TR:=MAX(MAX((H-L),ABS(REF(C,1)-H)),ABS(REF(C,1)-L)); +ATR:=MA(TR,LENGTH2); + +MIDLINE^^MA((H + L + C)/3,LENGTH1); +UPBAND^^MIDLINE + N*ATR; +DOWNBAND^^MIDLINE - N*ATR; + + +BKVOL=0 AND C>=UPBAND AND REF(C,1)REF(DOWNBAND,1),SPK; + +BKVOL>0 AND C<=MIDLINE,SP(BKVOL); +SKVOL>0 AND C>=MIDLINE,BP(SKVOL); +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/128252 + +> 更新时间 + +2018-12-05 17:17:26 diff --git "a/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" "b/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.md" similarity index 61% rename from "\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" rename to "\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.md" index c916f4b2..aef5fd8e 100644 --- "a/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.js" +++ "b/\346\265\213\350\257\225 \351\273\230\350\256\244 \345\217\202\346\225\260\347\273\204\345\212\237\350\203\275.md" @@ -1,22 +1,33 @@ -/* -策略出处: https://www.fmz.com/strategy/40155 -策略名称: 测试 默认 参数组功能 -策略作者: 小小梦 -策略描述: + +> 策略名称 + +测试 默认 参数组功能 + +> 策略作者 + +小小梦 + +> 策略描述 ### 如何使用代码精确调整“回测系统默认设置” > 在策略的参数测试,不同时间段回测,多个标的物回测等,回测策略时由于参数需要反复调整,而且不能记录,下次回测时又要重新设置。平台为了方便参数调整,新增加功能 -- 使用代码精确调整“回测系统默认设置”。 +> 策略参数 + -参数 默认值 描述 --------- ------------ ------------------------- -number 9999 数字类型 -bool true 布尔类型 -string Hello World! 字符串类型 -comboBox 0 下拉框: combo1|combo2|combo3 -*/ +|参数|默认值|描述| +|----|----|----| +|number|9999|数字类型| +|bool|true|布尔类型| +|string|Hello World!|字符串类型| +|comboBox|0|下拉框: combo1|combo2|combo3| + + +> 源码 (javascript) + +``` javascript /*backtest start: 2017-03-01 end: 2017-03-02 @@ -37,3 +48,12 @@ function main(){ Sleep(1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/40155 + +> 更新时间 + +2017-11-23 16:05:54 diff --git "a/\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).js" "b/\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).md" similarity index 93% rename from "\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).js" rename to "\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).md" index edcdc5cf..011397ec 100644 --- "a/\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).js" +++ "b/\346\265\213\350\257\225-CTP\345\225\206\345\223\201\346\234\237\350\264\247\350\277\236\346\216\245\347\212\266\346\200\201 (\345\233\276\350\241\250\346\230\276\347\244\272).md" @@ -1,18 +1,29 @@ -/* -策略出处: https://www.fmz.com/strategy/22838 -策略名称: 测试-CTP商品期货连接状态 (图表显示) -策略作者: 小小梦 -策略描述: + +> 策略名称 + +测试-CTP商品期货连接状态 (图表显示) + +> 策略作者 + +小小梦 + +> 策略描述 测试CTP商品期货连接状态 1、图标显示 +> 策略参数 + + -参数 默认值 描述 ----------------- ----- ------- -testContractType MA701 测试的合约类型 -*/ +|参数|默认值|描述| +|----|----|----| +|testContractType|MA701|测试的合约类型| + +> 源码 (javascript) + +``` javascript //获取多个品种的信息 SR', 'CF', 'RM', 'MA', 'PTA', 'ZC', 'FG', 'IO var ChartCfg = { @@ -165,3 +176,12 @@ function main() { Sleep(1000 * 5); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/22838 + +> 更新时间 + +2018-06-05 14:04:34 diff --git "a/\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211.js" "b/\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211.md" similarity index 95% rename from "\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211.js" rename to "\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211.md" index 3c4a621d..c93ff1df 100644 --- "a/\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211.js" +++ "b/\346\265\213\350\257\225-\345\270\203\346\236\227\345\270\246\347\255\226\347\225\245\357\274\210\345\237\272\344\272\216\347\255\226\347\225\245\346\241\206\346\236\266\357\274\211.md" @@ -1,23 +1,37 @@ -/* -策略出处: https://www.fmz.com/strategy/28128 -策略名称: 测试-布林带策略(基于策略框架) -策略作者: 小小梦 -策略描述: + +> 策略名称 + +测试-布林带策略(基于策略框架) + +> 策略作者 + +小小梦 + +> 策略描述 策略框架 +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|isLogReset|true|启动时是否清除日志| -参数 默认值 描述 ----------- ----- --------- -isLogReset true 启动时是否清除日志 -按钮 默认值 描述 ------------- ---------- ------- -upDateAmount true 更新开仓量按钮 -cmdOpen __button__ 开仓命令 -cmdCover __button__ 平仓命令 -*/ + +|按钮|默认值|描述| +|----|----|----| +|upDateAmount|true|更新开仓量按钮| +|cmdOpen|__button__|开仓命令| +|cmdCover|__button__|平仓命令| + + +> 源码 (javascript) + +``` javascript var Interval = 500; var _long = 1; var free = 0; @@ -274,3 +288,12 @@ function main(){ } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/28128 + +> 更新时间 + +2018-06-05 11:41:40 diff --git "a/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.js" "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.md" similarity index 91% rename from "\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.js" rename to "\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.md" index 023d89b4..d42d11c7 100644 --- "a/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.js" +++ "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.md" @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/38203 -策略名称: 测试多图表展示 -策略作者: Zero -策略描述: + +> 策略名称 + +测试多图表展示 + +> 策略作者 + +Zero + +> 策略描述 BotVS支持策略同时展现多个图表, 这是一个简单的例子. 如果不能正常展示, 请清空浏览器缓存后刷新 -*/ + +> 源码 (javascript) + +``` javascript function main() { var cfgA = { title: { @@ -89,3 +97,12 @@ function main() { }, -1); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/38203 + +> 更新时间 + +2017-03-24 20:45:59 diff --git "a/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.py" "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.md" similarity index 87% rename from "\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.py" rename to "\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.md" index 0edf2f8b..e3f052d3 100644 --- "a/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.py" +++ "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272Python\347\211\210.md" @@ -1,13 +1,19 @@ -''' -策略出处: https://www.fmz.com/strategy/84042 -策略名称: 测试多图表展示Python版 -策略作者: 小小梦 -策略描述: +> 策略名称 +测试多图表展示Python版 -''' +> 策略作者 +小小梦 + + + + + +> 源码 (python) + +``` python import random import time def main(): @@ -71,3 +77,12 @@ def main(): "y" : random.random() * 100 }, -1) +``` + +> 策略出处 + +https://www.fmz.com/strategy/84042 + +> 更新时间 + +2018-03-30 22:20:34 diff --git "a/\346\265\267\351\276\237.md" "b/\346\265\267\351\276\237.md" new file mode 100644 index 00000000..a8770324 --- /dev/null +++ "b/\346\265\267\351\276\237.md" @@ -0,0 +1,408 @@ + +> 策略名称 + +海龟 + +> 策略作者 + +alinwo + +> 策略描述 + +策略介绍 + +海龟交易策略是趋势策略中非常经典的交易策略,能在交易风险,仓位,资金利用率各方面做到很精细的控制。只要市场出现较大趋势(不管基于分钟K线,小时K线还是日K),海龟都会捕获到趋势并让利润最大化。此策略基于原版海龟交易法则实现,在2017年大牛市下取得了700%,远远高于大盘的收益。 + +策略特点 + +支持任意级别的趋势跟踪(分钟K,小时K,日K,周K等) +支持任意交易对(ETH/BTC, BSV/BTC等) +详细的策略报表(包括策略状态,交易历史记录等) +支持10几个自定义个性化参数 + +参数说明 +http://www.pcclean.io/%E6%B5%B7%E9%BE%9F%E4%BA%A4%E6%98%93%E7%AD%96%E7%95%A5/ + + + +> 源码 (javascript) + +``` javascript +/* +海龟策略 +用途:分散风险,平抑波动 +17:34 2018/9/12 retrySell后加sleep,解决清仓余额不足的问题 +17:58 2018/9/12 fixed Sell(-1, 0.00033): Less than minimum requirement +8:58 2018/9/13 fixed 无限仓位问题 +11:12 2018/9/13 符合海龟交易法则 +20:23 2018/9/23 修改清仓时不更新account.stock的问题 +11:14 2018/10/18 retrysell函数支持 对最小数量的自动修正 +11:16 2018/10/19 支持utc+8时间和logprofit +15:13 2018/10/19 支持对象化和管理多个交易对 +23:28 2018/10/20 支持统计手续费损失 +9:05 2018/10/22 retryBuy支持自动修正买入量 +22:10 2018/10/22 支持统计市价单盈亏 +11:40 2018/10/25 支持收益曲线连续 +*/ + +var ExchangProcessor={ + createNew: function(exc_obj){ + //策略参数 + var manage_assets=1;//bch + var max_positions=4;//max=4N + var price_n={BTC_BCH:8,ETH_BCH:8,XRP_BCH:8,EOS_BCH:8,LTC_BCH:8,DASH_BCH:8,CET_BCH:8}; //价格精度 + var num_n={BTC_BCH:8,ETH_BCH:8,XRP_BCH:8,EOS_BCH:8,LTC_BCH:8,DASH_BCH:8,CET_BCH:8}; //数量精度 + var minest_buy={BTC_BCH:0.001,ETH_BCH:0.01,XRP_BCH:1,EOS_BCH:1,LTC_BCH:0.1,DASH_BCH:0.01,CET_BCH:1};//最小买入量 + var minest_sell={BTC_BCH:0.001,ETH_BCH:0.01,XRP_BCH:1,EOS_BCH:1,LTC_BCH:0.1,DASH_BCH:0.01,CET_BCH:1};//最小卖出量 + var order_wait_secs=120000; //订单的最长等待时间 毫秒 + var wait_ms=1000;//默认等待毫秒 + var sxf=0.0005;//用来计算手续费消耗 + + + //全局状态变量 + var positions=[];//记录仓位 + var init_asset=0; //初始资产 + var trades=[];//所有交易 + var trades_recorder=true;//记录所有交易 + var pre_time=null; //记录轮询间隔时间 + var approximate_profit=0;//盈亏近似值 + var add_already=0;//已经加仓次数 + + var processor={}; + //重试购买,直到成功返回 + processor.retryBuy=function(ex,price,num) + { + var currency=ex.GetCurrency(); + var r=ex.Buy(_N(price,price_n[currency]), _N(num,num_n[currency])); + while (!r){ + Log("Buy失败,正在retry。"); + Sleep(wait_ms); + var account=_C(ex.GetAccount); + var ticker=_C(ex.GetTicker); + var last=ticker.Last; + var fixedAmount=(price===-1?Math.min(account.Balance*0.95,num):Math.min(account.Balance/last*0.95,num)); + r=ex.Buy(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); + } + return r; + } + + //重试卖出,直到成功返回 + processor.retrySell=function(ex,price,num){ + var currency=ex.GetCurrency(); + var r=ex.Sell(_N(price,price_n[currency]), _N(num,num_n[currency])); + while (!r){ + Log("Sell失败,正在retry。"); + Sleep(wait_ms); + var account=_C(ex.GetAccount); + var fixedAmount=Math.min(account.Stocks,num); + r=ex.Sell(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); + } + return r; + } + + + processor.get_ChinaTimeString=function(){ + var date = new Date(); + var now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), + date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); + var cdate=new Date(now_utc); + cdate.setHours(cdate.getHours()+8); + var localstring=cdate.getFullYear()+'/'+(cdate.getMonth()+1)+'/'+cdate.getDate()+' '+cdate.getHours()+':'+cdate.getMinutes()+':'+cdate.getSeconds(); + return localstring; + } + + processor.init_obj=function(){ + _CDelay(wait_ms); + pre_time = new Date(); + + //init + { + var account=_C(exc_obj.GetAccount); + var ticker=_C(exc_obj.GetTicker); + var last=ticker.Last; + init_asset=(account.Balance+account.FrozenBalance)+(account.Stocks+account.FrozenStocks)*last; + Sleep(wait_ms); + } + } + + + processor.work=function(){ + var cur_time = new Date(); + var passedtime=cur_time-pre_time; + pre_time=cur_time; + + //计算n,头寸 + var exname=exc_obj.GetName(); + var currency=exc_obj.GetCurrency(); + var account=_C(exc_obj.GetAccount); + var ticker=_C(exc_obj.GetTicker); + var depth = _C(exc_obj.GetDepth); + var last=ticker.Last; + var ask1=depth.Asks[0].Price; + var bid1=depth.Bids[0].Price; + var bestprice=bid1+(Math.abs(ask1-bid1)/2); + var records = _C(exc_obj.GetRecords); + if (records.length<=50){ + Log("records.length is not valid."); + Sleep(wait_ms); + return; + } + var atr = TA.ATR(records, 20); + if (atr.length<=1){ + Log("atr.length is not valid."); + Sleep(wait_ms); + return; + } + var N=atr[atr.length-1]; + var position_unit=Math.min(manage_assets*0.01/N,account.Balance/last*0.95);//cet + //Log("N="+N+", 头寸单位="+position_unit+"CET"); + var highest=TA.Highest(records, 20, 'High'); + var Lowest=TA.Lowest(records, 10, 'Low'); + var cur_asset=(account.Balance+account.FrozenBalance)+(account.Stocks+account.FrozenStocks)*last; + var rsi6 = TA.RSI(records, 6); + var rsi12 = TA.RSI(records, 12); + if (rsi6.length<=5 || rsi12.length<=5){ + Log("rsi is not valid."); + Sleep(wait_ms); + return; + } + var rsi_in=false; + if (rsi6[rsi6.length-1]-rsi6[rsi6.length-2]>5 && + rsi6[rsi6.length-3]-rsi6[rsi6.length-2]>5 && + rsi6[rsi6.length-2]<=55 && + rsi6[rsi6.length-1]>rsi12[rsi12.length-1]){ + //Log("rsi_in=true"); + rsi_in=true; + } + var rsi_out=false; + if (rsi6[rsi6.length-2]-rsi6[rsi6.length-1]>5 && + rsi6[rsi6.length-2]>=70){ + //Log("rsi_out=true"); + rsi_out=true; + } + + //建仓 + if (positions.length==0 && position_unit>minest_buy[currency]){ + if (last>=highest) + { + var buyID = processor.retryBuy(exc_obj,last,position_unit); + Sleep(order_wait_secs); + var buyOrder=_C(exc_obj.GetOrder,buyID); + if (buyOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(buyID); + } + if (buyOrder.DealAmount>0){ + var postion = { + amount:buyOrder.DealAmount, + buy_price:buyOrder.AvgPrice, + stoploss_price:buyOrder.AvgPrice-2*N}; + positions.push(postion); + + var details={ + type:"建仓", + time:processor.get_ChinaTimeString(), + RealAmount:buyOrder.DealAmount, + WantAmount:position_unit, + RealPrice:buyOrder.AvgPrice, + WantPrice:buyOrder.Price, + Memo:"" + }; + if (trades_recorder){ + trades.push(details); + } + + add_already=1; + } + } + } + + //加仓 + if (positions.length>0 && position_unit>minest_buy[currency]){ + var last_buy_price=positions[positions.length-1].buy_price; + if (add_already=0.5*N){ + var buyID = processor.retryBuy(exc_obj,last,position_unit); + Sleep(order_wait_secs); + var buyOrder=_C(exc_obj.GetOrder,buyID); + if (buyOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(buyID); + } + if (buyOrder.DealAmount>0){ + var postion = { + amount:buyOrder.DealAmount, + buy_price:buyOrder.AvgPrice, + stoploss_price:buyOrder.AvgPrice-2*N}; + positions.push(postion); + + var details={ + type:"加仓", + time:processor.get_ChinaTimeString(), + RealAmount:buyOrder.DealAmount, + WantAmount:position_unit, + RealPrice:buyOrder.AvgPrice, + WantPrice:last, + Memo:"" + }; + if (trades_recorder){ + trades.push(details); + } + + add_already=add_already+1; + } + } + } + } + + //止损 + if (positions.length>0){ + var positions_new=[]; + for (var i=0; i < positions.length; i++){ + if (last<=positions[i].stoploss_price){ + account=_C(exc_obj.GetAccount); + var fixedAmount=Math.min(account.Stocks,positions[i].amount); + if (fixedAmount>minest_sell[currency]){ + var sellID = processor.retrySell(exc_obj, last, fixedAmount); + Sleep(order_wait_secs); + var sellOrder=_C(exc_obj.GetOrder,sellID); + approximate_profit+=(sellOrder.AvgPrice*sellOrder.DealAmount*(1-sxf)-positions[i].buy_price*sellOrder.DealAmount*(1+sxf)); + Log("定价卖出: 数量-"+sellOrder.DealAmount+",approximate_profit="+approximate_profit); + if (sellOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(sellID); + if (Math.min(account.Stocks,fixedAmount-sellOrder.DealAmount)>minest_sell[currency]){ + var marketsellOrderID=processor.retrySell(exc_obj, -1, fixedAmount-sellOrder.DealAmount); + Sleep(order_wait_secs); + var marketsellOrderData=_C(exc_obj.GetOrder,marketsellOrderID); + approximate_profit+=(marketsellOrderData.AvgPrice*marketsellOrderData.DealAmount*(1-sxf)-positions[i].buy_price*marketsellOrderData.DealAmount*(1+sxf)); + Log("市价卖出: 数量-"+marketsellOrderData.DealAmount+",approximate_profit="+approximate_profit); + } + } + + var details={ + type:"止损", + time:processor.get_ChinaTimeString(), + RealAmount:-1, + WantAmount:fixedAmount, + RealPrice:-1, + WantPrice:last, + Memo:(last>positions[i].buy_price?"盈利":"亏损") + }; + if (trades_recorder){ + trades.push(details); + } + } + }else{ + positions_new.push(positions[i]); + } + } + positions=positions_new; + } + + //清仓 + if (positions.length>0){ + if (last<=Lowest){ + var positions_new=[]; + for (var i=0; i < positions.length; i++){ + account=_C(exc_obj.GetAccount); + var fixedAmount=Math.min(account.Stocks,positions[i].amount); + if (fixedAmount>minest_sell[currency]){ + var sellID = processor.retrySell(exc_obj, last, fixedAmount); + Sleep(order_wait_secs); + var sellOrder=_C(exc_obj.GetOrder,sellID); + approximate_profit+=(sellOrder.AvgPrice*sellOrder.DealAmount*(1-sxf)-positions[i].buy_price*sellOrder.DealAmount*(1+sxf)); + Log("定价卖出: 数量-"+sellOrder.DealAmount+",approximate_profit="+approximate_profit); + if (sellOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(sellID); + if (Math.min(account.Stocks,fixedAmount-sellOrder.DealAmount)>minest_sell[currency]){ + var marketsellOrderID=processor.retrySell(exc_obj, -1, fixedAmount-sellOrder.DealAmount); + Sleep(order_wait_secs); + var marketsellOrderData=_C(exc_obj.GetOrder,marketsellOrderID); + approximate_profit+=(marketsellOrderData.AvgPrice*marketsellOrderData.DealAmount*(1-sxf)-positions[i].buy_price*marketsellOrderData.DealAmount*(1+sxf)); + Log("市价卖出: 数量-"+marketsellOrderData.DealAmount+",approximate_profit="+approximate_profit); + } + } + + var details={ + type:"清仓", + time:processor.get_ChinaTimeString(), + RealAmount:-1, + WantAmount:fixedAmount, + RealPrice:-1, + WantPrice:last, + Memo:(last>positions[i].buy_price?"盈利":"亏损") + }; + if (trades_recorder){ + trades.push(details); + } + } + } + positions=positions_new; + } + } + + + //显示状态 + var table1 = {type: 'table', title: '仓位-'+exname+'('+currency+')', cols: ['数量', '成交价','止损价'], rows: []}; + var table2 = {type: 'table', title: '状态-'+exname+'('+currency+')', cols: ['平均真实波幅(N)','头寸单位','初始资产','当前资产','轮询时间','最新价','Highest','Lowest','加仓次数','【近似盈亏】'], rows: []}; + var table3 = {type: 'table', title: '交易历史-'+exname+'('+currency+')', cols: ['日期','类型', '成交数量','发单数量','成交价','发单价','备注'], rows: []}; + for (var i=0; i < positions.length; i++){ + table1.rows.push([positions[i].amount,positions[i].buy_price,positions[i].stoploss_price]); + } + table2.rows.push([N,position_unit,init_asset,cur_asset,passedtime+'ms',last,highest,Lowest,add_already,approximate_profit]); + for (i=0; i < trades.length; i++){ + table3.rows.push([trades[i].time,trades[i].type,trades[i].RealAmount,trades[i].WantAmount,trades[i].RealPrice,trades[i].WantPrice,trades[i].Memo]); + } + processor.logstatus=('`' + JSON.stringify([table1, table2, table3])+'`'+'\n'); + + //记录盈利 + processor.logprofit=approximate_profit; + + //rest + Sleep(wait_ms); + } + + return processor; + } +}; + + + +//主函数 +function main(){ + var exchange_num=exchanges.length; + var processors=[]; + for (var i=0; i 策略出处 + +https://www.fmz.com/strategy/128382 + +> 更新时间 + +2018-12-01 13:50:55 diff --git "a/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245.md" "b/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245.md" new file mode 100644 index 00000000..49b9806f --- /dev/null +++ "b/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245.md" @@ -0,0 +1,67 @@ + +> 策略名称 + +瀑布线策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略名称:瀑布线PUBU交易策略 +- 数据周期:15M +- 支持:商品期货 +- 官方网站:www.quant.la + +/upload/asset/3ba2dba0c6b01773b2c296438ff77d25.png + +- 主图 + 瀑布线1,公式:PUBU1^^(EMA(C,N1)+EMA(C,N1*2)+EMA(C,N1*4))/3; + 瀑布线2,公式:PUBU2^^(EMA(C,N2)+EMA(C,N2*2)+EMA(C,N2*4))/3; + 瀑布线3,公式:PUBU3^^(EMA(C,N3)+EMA(C,N3*2)+EMA(C,N3*4))/3; + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N1|20|瀑布线1参数| +|N2|50|瀑布线2参数| +|N3|70|瀑布线3参数| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-01-01 00:00:00 +end: 2018-01-07 00:00:00 +period: 30m +exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}] +args: [["TradeAmount",10,126961],["ContractType","quarter",126961]] +*) + +// 指标 +PUBU1^^(EMA(C,N1)+EMA(C,N1*2)+EMA(C,N1*4))/3; +PUBU2^^(EMA(C,N2)+EMA(C,N2*2)+EMA(C,N2*4))/3; +PUBU3^^(EMA(C,N3)+EMA(C,N3*2)+EMA(C,N3*4))/3; + +BKVOL=0 AND BARPOS>N3 AND C>PUBU1 AND PUBU1>PUBU2 AND PUBU2>PUBU3,BPK; +SKVOL=0 AND BARPOS>N3 AND CPUBU3,BP(SKVOL); +CBKPRICE,SP(BKVOL); +C>PUBU2 AND PUBU1>PUBU2 AND C 策略出处 + +https://www.fmz.com/strategy/128420 + +> 更新时间 + +2018-12-04 21:24:04 diff --git "a/\347\216\260\347\216\260\345\257\271\345\206\262(\346\220\254\347\240\226).md" "b/\347\216\260\347\216\260\345\257\271\345\206\262(\346\220\254\347\240\226).md" new file mode 100644 index 00000000..c708c04b --- /dev/null +++ "b/\347\216\260\347\216\260\345\257\271\345\206\262(\346\220\254\347\240\226).md" @@ -0,0 +1,405 @@ + +> 策略名称 + +现现对冲(搬砖) + +> 策略作者 + +alinwo + +> 策略描述 + +策略功能: + +实现跨交易所的现现对冲 +支持无限个交易所同时搬砖 +支持任意交易对搬砖 +详细报表支持(完整的状态信息, 可实时看到策略观察到的各个交易所的差价信息, 持仓信息,资金净值,策略运行状况) +24小时无人值守, 全自动运行 + +参数设置: + +策略在运行之前需要配置下参数,比如你要搬的交易所的手续费,交易所的最小买入数量,期望收益等信息。 + +详细说明: +http://www.pcclean.io/%E7%8E%B0%E7%8E%B0%E5%AF%B9%E5%86%B2%E5%A4%9A%E4%BA%A4%E6%98%93%E6%89%80%E6%90%AC%E7%A0%96botvs%E6%BA%90%E4%BB%A3%E7%A0%81%E5%88%86%E4%BA%AB/ + + + +> 源码 (javascript) + +``` javascript +/* +现现对冲(搬砖) + +注意: +1.确保设置了交易所的手续费和最小买入量 + +版本历史: +21:33 2018/10/25 处理挂单不成交的情况,不再使用市价单 +7:28 2018/10/26 支持永久记录收益 +8:00 2018/10/27 支持显示币数变化,搬砖函数每次更新getaccount +10:14 2018/10/27 修复不显示profit chart的问题 +*/ + +//搬砖参数设置 +var handfee= {FCoin:0.0 , CoinEx:0.0004,Huobi:0.002,OKEX:0.002,Binance:0.001,ZB:0.002 };//手续费 +var minestbuy={FCoin:0.01, CoinEx:0.01, Huobi:0.01, OKEX:0.01, Binance:0.04, ZB:0.01 }; //最小买入量 +var want_profit=0.0001;//期望收益 +var price_step=0.00001;//定价单调整价格的单位 +var maxbuy=5; //最大买入 +var warning_stocks=10;//余额预警 +var price_n=6; //价格精度 +var num_n=3; //数量精度 +var max_wait_order=15000;//订单等待时间 +var buypercent=1.0; //买入百分比 +var wait_ms=3000;//重试等待间隔时间 +var enable_traders_recorder=true;//记录所有交易 + + +//全局变量 +var limit_orders=[];//限价单 +var total_banzhuan=0;//搬砖次数 +var total_op=0;//总搬砖机会 +var exchange_banzhuan={};//记录交易所搬砖次数 +var total_passed=0;//因为余额不足错过了多少次搬砖机会 +var trades=[];//所有交易 +var approximate_profit=0;//盈亏近似值 +var dealamount_change=0;//币数变化 + +function get_exchange_banzhuan(exname){ + var name = exname.replace(" ", "_"); + if (isNaN(exchange_banzhuan[name])){ + return 0; + }else{ + return exchange_banzhuan[name]; + } +} +function put_exchange_banzhuan(exname,value){ + var name = exname.replace(" ", "_"); + exchange_banzhuan[name]=value; +} + +//在交易所ex1和ex2之间搬砖 +function banzhuan(exchange1,exchange2) +{ + //read price from exchange 1 + var account1=_C(exchange1.GetAccount); + var exname1=exchange1.GetName(); + var depth1 = _C(exchange1.GetDepth); + var askprice1=depth1.Asks[0].Price; + var askamount1=depth1.Asks[0].Amount; + + //read price from exchange 2 + var account2=_C(exchange2.GetAccount); + var exname2=exchange2.GetName(); + var depth2 = _C(exchange2.GetDepth); + var bidprice2=depth2.Bids[0].Price; + var bidamount2=depth2.Bids[0].Amount; + + var threshold=handfee[exname1]+handfee[exname2]+want_profit; //交易阀值 + var minbuy=Math.max(minestbuy[exname1],minestbuy[exname2]); //最小购买数量 + + //buy and sell if its prifitable + var diff=(bidprice2-askprice1)/askprice1; + var canbuy=Math.min(askamount1,bidamount2); + canbuy=canbuy*buypercent; + var min=Math.min(canbuy,maxbuy); //the minimum number for buy/sell + + if (Math.abs(diff)>=threshold && min>=minbuy) //for bch + { + if (diff>0)//exchange 1 is cheap + { + total_op=total_op+2; + put_exchange_banzhuan(exname1+"_op",get_exchange_banzhuan(exname1+"_op")+1); + put_exchange_banzhuan(exname2+"_op",get_exchange_banzhuan(exname2+"_op")+1); + put_exchange_banzhuan(exname1+"_canbuy",get_exchange_banzhuan(exname1+"_canbuy")+min); + put_exchange_banzhuan(exname2+"_cansell",get_exchange_banzhuan(exname2+"_cansell")+min); + + var needmoney=min*askprice1; + if (account2.Stocks>min && account1.Balance>needmoney ){ + + //buy from exchange 1 + var price_1=askprice1; + var buyID=retryBuy(exchange1,price_1,min); + //sell from exchange 2 + var price_2=bidprice2; + var sellID=retrySell(exchange2,price_2,min); + + //add orders to pre-processing list + var order1={ + exchange:exchange1, + ID:buyID, + create_time:new Date(), + utcdate:get_ChinaTimeString() + }; + limit_orders.push(order1); + var order2={ + exchange:exchange2, + ID:sellID, + create_time:new Date(), + utcdate:get_ChinaTimeString() + }; + limit_orders.push(order2); + + total_banzhuan=total_banzhuan+2; + put_exchange_banzhuan(exname1,get_exchange_banzhuan(exname1)+1); + put_exchange_banzhuan(exname2,get_exchange_banzhuan(exname2)+1); + }else{ + if (account2.Stocks<=min){ + Log(exchange2.GetName()+"没币了,无法搬砖。请及时充值。"+"#ff0000"); + } + if (account1.Balance<=needmoney){ + Log(exchange1.GetName()+"没钱了,无法搬砖。请及时充值。"+"#ff0000"); + } + total_passed=total_passed+2; + } + } + } +} + + +//检查订单是否执行成功,如果未完成,执行市价下单 +function process_limiteorders(){ + var cur_time=new Date(); + var limit_orders_new=[]; + for (var i=0; imax_wait_order){ + var exchange_c=limit_orders[i].exchange; + var order_ID=limit_orders[i].ID; + var exname=exchange_c.GetName(); + var account=_C(exchange_c.GetAccount); + var ticker=_C(exchange_c.GetTicker); + var last=ticker.Last; + var orderdata=_C(exchange_c.GetOrder,order_ID); + var type=orderdata.Type; + + if (orderdata.Status!=ORDER_STATE_CLOSED){ + var notcompleted=orderdata.Amount-orderdata.DealAmount; + exchange_c.CancelOrder(order_ID); + if (type===ORDER_TYPE_BUY){ + var allowbuy=Math.min(account.Balance/last,notcompleted); + if (allowbuy>minestbuy[exname]){ + var limited_order_ID=retryBuy(exchange_c,orderdata.Price+price_step,allowbuy); + Log("加价买入。"+orderdata.Price+"|"+(orderdata.Price+price_step)); + var limited_order_data={ + exchange:exchange_c, + ID:limited_order_ID, + create_time:new Date(), + utcdate:get_ChinaTimeString() + }; + limit_orders_new.push(limited_order_data); + } + approximate_profit-=(orderdata.Price*orderdata.DealAmount*(1+handfee[exname])); + dealamount_change+=(orderdata.DealAmount); + }else if (type===ORDER_TYPE_SELL){ + var allowsell=Math.min(account.Stocks,notcompleted); + if (allowsell>minestbuy[exname]){ + var limited_order_ID=retrySell(exchange_c,orderdata.Price-price_step,allowsell); + Log("降价卖出。"+orderdata.Price+"|"+(orderdata.Price-price_step)); + var limited_order_data={ + exchange:exchange_c, + ID:limited_order_ID, + create_time:new Date(), + utcdate:get_ChinaTimeString() + }; + limit_orders_new.push(limited_order_data); + } + approximate_profit+=(orderdata.Price*orderdata.DealAmount*(1-handfee[exname])); + dealamount_change-=(orderdata.DealAmount); + } + + //保存交易信息 + if (type===ORDER_TYPE_BUY){ + var details={ + type:"限价买", + time:limit_orders[i].utcdate, + RealAmount:orderdata.DealAmount, + WantAmount:orderdata.Amount, + RealPrice:orderdata.Price, + WantPrice:orderdata.Price, + Memo:"部分完成", + exname:exname + }; + if (enable_traders_recorder){ + trades.push(details); + } + }else if (type===ORDER_TYPE_SELL){ + var details={ + type:"限价卖", + time:limit_orders[i].utcdate, + RealAmount:orderdata.DealAmount, + WantAmount:orderdata.Amount, + RealPrice:orderdata.Price, + WantPrice:orderdata.Price, + Memo:"部分完成", + exname:exname + }; + if (enable_traders_recorder){ + trades.push(details); + } + } + }else{ + //保存交易信息 + if (type===ORDER_TYPE_BUY){ + approximate_profit-=(orderdata.Price*orderdata.DealAmount*(1+handfee[exname])); + dealamount_change+=(orderdata.DealAmount); + var details={ + type:"限价买", + time:limit_orders[i].utcdate, + RealAmount:orderdata.DealAmount, + WantAmount:orderdata.Amount, + RealPrice:orderdata.Price, + WantPrice:orderdata.Price, + Memo:"已完成", + exname:exname + }; + if (enable_traders_recorder){ + trades.push(details); + } + }else if (type===ORDER_TYPE_SELL){ + approximate_profit+=(orderdata.Price*orderdata.DealAmount*(1-handfee[exname])); + dealamount_change-=(orderdata.DealAmount); + var details={ + type:"限价卖", + time:limit_orders[i].utcdate, + RealAmount:orderdata.DealAmount, + WantAmount:orderdata.Amount, + RealPrice:orderdata.Price, + WantPrice:orderdata.Price, + Memo:"已完成", + exname:exname + }; + if (enable_traders_recorder){ + trades.push(details); + } + } + } + }else{ + limit_orders_new.push(limit_orders[i]); + } + } + limit_orders=limit_orders_new; +} + +//重试购买,直到成功返回 +function retryBuy(ex,price,num) +{ + var r=ex.Buy(_N(price,price_n), _N(num,num_n)); + while (!r){ + Log("Buy失败,正在retry。"); + Sleep(wait_ms); + r=ex.Buy(_N(price,price_n), _N(num,num_n)); + } + return r; +} + +//重试卖出,直到成功返回 +function retrySell(ex,price,num) +{ + var r=ex.Sell(_N(price,price_n), _N(num,num_n)); + while (!r){ + Log("Sell失败,正在retry。"); + Sleep(wait_ms); + r=ex.Sell(_N(price,price_n), _N(num,num_n)); + } + return r; +} + +//get utc+8 date string +function get_ChinaTimeString() +{ + var date = new Date(); + var now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); + var cdate=new Date(now_utc); + cdate.setHours(cdate.getHours()+8); + var localstring=cdate.getFullYear()+'/'+(cdate.getMonth()+1)+'/'+cdate.getDate()+' '+cdate.getHours()+':'+cdate.getMinutes()+':'+cdate.getSeconds(); + return localstring; +} + + +//主逻辑 +function main(){ + + _CDelay(wait_ms); + var exchange_num=exchanges.length; + var pre_time = new Date(); + var start_time=new Date(); + var last_profit=0; + var pre_profit=Number(_G("pre_profit")); + Log('之前收入累计:'+pre_profit); + + while(true){ + var cur_time = new Date(); + var passedtime=cur_time-pre_time; + pre_time=cur_time; + + for (var i=0; i 策略出处 + +https://www.fmz.com/strategy/127154 + +> 更新时间 + +2018-11-23 10:39:59 diff --git "a/\347\224\273\347\272\277\347\261\273\345\272\223.js" "b/\347\224\273\347\272\277\347\261\273\345\272\223|Plot library.md" similarity index 96% rename from "\347\224\273\347\272\277\347\261\273\345\272\223.js" rename to "\347\224\273\347\272\277\347\261\273\345\272\223|Plot library.md" index f399d1d6..e6d71063 100644 --- "a/\347\224\273\347\272\277\347\261\273\345\272\223.js" +++ "b/\347\224\273\347\272\277\347\261\273\345\272\223|Plot library.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/27293 -策略名称: 画线类库 -策略作者: Zero -策略描述: + +> 策略名称 + +画线类库|Plot library + +> 策略作者 + +Zero + +> 策略描述 简化了策略图表画线的逻辑, 可以直接调用封装好的函数 @@ -34,8 +39,11 @@ function main() { } ``` -*/ + +> 源码 (javascript) + +``` javascript var chart = null var series = [] var labelIdx = [] @@ -285,3 +293,12 @@ function main() { Sleep(60000) } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/27293 + +> 更新时间 + +2018-07-05 18:04:17 diff --git "a/\347\233\221\350\247\206\345\271\266\346\230\276\347\244\272\345\244\232\344\270\252\345\271\263\345\217\260\347\232\204\345\205\250\351\203\250\350\265\204\344\272\247\346\200\273\345\222\214\347\232\204\345\217\230\345\214\226.js" "b/\347\233\221\350\247\206\345\271\266\346\230\276\347\244\272\345\244\232\344\270\252\345\271\263\345\217\260\347\232\204\345\205\250\351\203\250\350\265\204\344\272\247\346\200\273\345\222\214\347\232\204\345\217\230\345\214\226.md" similarity index 86% rename from "\347\233\221\350\247\206\345\271\266\346\230\276\347\244\272\345\244\232\344\270\252\345\271\263\345\217\260\347\232\204\345\205\250\351\203\250\350\265\204\344\272\247\346\200\273\345\222\214\347\232\204\345\217\230\345\214\226.js" rename to "\347\233\221\350\247\206\345\271\266\346\230\276\347\244\272\345\244\232\344\270\252\345\271\263\345\217\260\347\232\204\345\205\250\351\203\250\350\265\204\344\272\247\346\200\273\345\222\214\347\232\204\345\217\230\345\214\226.md" index ea465fe2..7277c5ba 100644 --- "a/\347\233\221\350\247\206\345\271\266\346\230\276\347\244\272\345\244\232\344\270\252\345\271\263\345\217\260\347\232\204\345\205\250\351\203\250\350\265\204\344\272\247\346\200\273\345\222\214\347\232\204\345\217\230\345\214\226.js" +++ "b/\347\233\221\350\247\206\345\271\266\346\230\276\347\244\272\345\244\232\344\270\252\345\271\263\345\217\260\347\232\204\345\205\250\351\203\250\350\265\204\344\272\247\346\200\273\345\222\214\347\232\204\345\217\230\345\214\226.md" @@ -1,18 +1,29 @@ -/* -策略出处: https://www.fmz.com/strategy/443 -策略名称: 监视并显示多个平台的全部资产总和的变化 -策略作者: Zero -策略描述: + +> 策略名称 + +监视并显示多个平台的全部资产总和的变化 + +> 策略作者 + +Zero + +> 策略描述 监视并显示多个平台的全部资产总和, 账户资金发生变化时才会从新显示, 所有平台的钱和币将换算成净资产显示到收益曲线里 +> 策略参数 + + -参数 默认值 描述 ------------- ----- -------- -Interval 1000 失败重试(毫秒) -TickInterval 5000 监控频率(毫秒) -*/ +|参数|默认值|描述| +|----|----|----| +|Interval|1000|失败重试(毫秒)| +|TickInterval|5000|监控频率(毫秒)| + +> 源码 (javascript) + +``` javascript var LastState = null; function adjustFloat(v) { @@ -78,3 +89,12 @@ function main() { Sleep(Math.max(TickInterval, 100)); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/443 + +> 更新时间 + +2014-12-04 01:30:50 diff --git "a/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.js" "b/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.md" similarity index 96% rename from "\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.js" rename to "\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.md" index d63cbe0c..253177ac 100644 --- "a/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.js" +++ "b/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.md" @@ -1,18 +1,29 @@ -/* -策略出处: https://www.fmz.com/strategy/40266 -策略名称: 知乎专栏 实例文章策略 -策略作者: yilidalei -策略描述: + +> 策略名称 + +知乎专栏 实例文章策略 + +> 策略作者 + +yilidalei + +> 策略描述 测试JS +> 策略参数 + + -参数 默认值 描述 ------- ----- -------- -RatioA 0.05 调整系数 -RatioB 0.1 平仓加仓偏离系数 -*/ +|参数|默认值|描述| +|----|----|----| +|RatioA|0.05|调整系数| +|RatioB|0.1|平仓加仓偏离系数| + +> 源码 (javascript) + +``` javascript // 参数变量 (待填写) var ContractType = "rb1710"; // 标的物合约代码 ,螺纹钢 1710 合约 目前主力合约 var UsedRatio = 0.5 @@ -200,3 +211,12 @@ function onexit(){ Log("程序退出!"); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/40266 + +> 更新时间 + +2017-05-09 15:00:16 diff --git "a/\347\237\255\344\277\241\351\200\232\347\237\245\346\216\245\345\217\243\346\265\213\350\257\225.js" "b/\347\237\255\344\277\241\351\200\232\347\237\245\346\216\245\345\217\243\346\265\213\350\257\225.md" similarity index 62% rename from "\347\237\255\344\277\241\351\200\232\347\237\245\346\216\245\345\217\243\346\265\213\350\257\225.js" rename to "\347\237\255\344\277\241\351\200\232\347\237\245\346\216\245\345\217\243\346\265\213\350\257\225.md" index 00c59c5d..7a8edfea 100644 --- "a/\347\237\255\344\277\241\351\200\232\347\237\245\346\216\245\345\217\243\346\265\213\350\257\225.js" +++ "b/\347\237\255\344\277\241\351\200\232\347\237\245\346\216\245\345\217\243\346\265\213\350\257\225.md" @@ -1,20 +1,31 @@ -/* -策略出处: https://www.fmz.com/strategy/653 -策略名称: 短信通知接口测试 -策略作者: Zero -策略描述: + +> 策略名称 + +短信通知接口测试 + +> 策略作者 + +Zero + +> 策略描述 短信通知接口测试, 请到支持api的短信平台注册账户(推荐短信宝), 然后把发送的URL输入到接口里 比如 http://www.xxxx.com/sms.php?phone=1111111&c={BODY} 测试能不能手到短信 +> 策略参数 + + -参数 默认值 描述 ------- ------- ----- -SMSAPI http:// 短信接口 -Msg 你好,测试成功 发送的信息 -*/ +|参数|默认值|描述| +|----|----|----| +|SMSAPI|http://|短信接口| +|Msg|你好,测试成功|发送的信息| + +> 源码 (javascript) + +``` javascript function main() { if (SMSAPI.length > 10 && SMSAPI.indexOf('http') == 0 && SMSAPI.indexOf('{BODY}') != -1) { Log('发送: ', Msg); @@ -24,3 +35,12 @@ function main() { Log('参数配置错误, 请重新检测短信接口'); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/653 + +> 更新时间 + +2014-09-25 17:35:46 diff --git "a/\347\237\255\344\277\241\351\200\232\347\237\245\347\261\273\345\272\223.js" "b/\347\237\255\344\277\241\351\200\232\347\237\245\347\261\273\345\272\223.md" similarity index 71% rename from "\347\237\255\344\277\241\351\200\232\347\237\245\347\261\273\345\272\223.js" rename to "\347\237\255\344\277\241\351\200\232\347\237\245\347\261\273\345\272\223.md" index 76c5d0c9..11f6f7d3 100644 --- "a/\347\237\255\344\277\241\351\200\232\347\237\245\347\261\273\345\272\223.js" +++ "b/\347\237\255\344\277\241\351\200\232\347\237\245\347\261\273\345\272\223.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/26921 -策略名称: 短信通知类库 -策略作者: Zero -策略描述: + +> 策略名称 + +短信通知类库 + +> 策略作者 + +Zero + +> 策略描述 > 支持网关 @@ -15,19 +20,25 @@ $.SMSNotify("abc 短信测试"); ``` +> 策略参数 + + -参数 默认值 描述 --------------- --------------------- ----------------- -PhoneNum 138XXXXXXXX 手机号 -SMSGate 0 短信网关: 短信宝|SUBMAIL -SMSBaoUserName username 用户名 -SMSBaoPWD $$$__enc__$$$password 密码 -AppId 11111 APPID -AppKey $$$__enc__$$$11111 APPKEY -VarName content 变量名称 -Project 5x1X03 项目标记 -*/ +|参数|默认值|描述| +|----|----|----| +|PhoneNum|138XXXXXXXX|手机号| +|SMSGate|0|短信网关: 短信宝|SUBMAIL| +|SMSBaoUserName|username|用户名| +|SMSBaoPWD|$$$__enc__$$$password|密码| +|AppId|11111|APPID| +|AppKey|$$$__enc__$$$11111|APPKEY| +|VarName|content|变量名称| +|Project|5x1X03|项目标记| + +> 源码 (javascript) + +``` javascript $.SMSNotify = function(content) { if (IsVirtual()) { throw "此模板只支持实盘"; @@ -66,3 +77,12 @@ $.SMSNotify = function(content) { function main() { $.SMSNotify("abc 短信测试"); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/26921 + +> 更新时间 + +2016-12-05 17:31:11 diff --git "a/\347\240\264\345\206\260\350\200\205.js" "b/\347\240\264\345\206\260\350\200\205.md" similarity index 94% rename from "\347\240\264\345\206\260\350\200\205.js" rename to "\347\240\264\345\206\260\350\200\205.md" index df39e7f4..b4dbd590 100644 --- "a/\347\240\264\345\206\260\350\200\205.js" +++ "b/\347\240\264\345\206\260\350\200\205.md" @@ -1,36 +1,47 @@ -/* -策略出处: https://www.fmz.com/strategy/9929 -策略名称: 破冰者 -策略作者: Zero -策略描述: + +> 策略名称 + +破冰者 + +> 策略作者 + +Zero + +> 策略描述 改自 单点狙击高频加仓自动反手解套算法 V1.2 但是不反手,可以单方向做,加了止损. 效果很好, 识货的拿走,看源码. 不多说了. 回测时资金设置在10万以上, 币设置在30以上, 这样才能达到理想效果, 资金越大, 策略抗波动能力越强 +> 策略参数 + + -参数 默认值 描述 -------------- ----- ----------- -OpType 0 开仓方向: 做多|做空 -OpAmount 0.1 开仓数量 -OpMode 0 开仓方式: 吃单|挂单 -MaxSpace 0.5 挂单失效距离 -SlidePrice 0.1 下单滑动价(元) -MaxAmount 0.3 开仓最大单次下单量 -AddGoal true 加仓间距(元) -AddLine 0.8 加仓均价目标(元) -ProfitGoal 0.5 平仓目标(元) -Interval true 轮询间隔(秒) -RestoreIt false 恢复进度 -RestoreType 0 持仓方向: 做多|做空 -RestorePrice false 持仓均价 -RestoreAmount false 持仓数量 -RestoreProfit false 上次盈利 -SaveLocal false 保存本地日志 -StopLoss 8 止损(元) -MinStock 0.01 最小交易币数 -*/ +|参数|默认值|描述| +|----|----|----| +|OpType|0|开仓方向: 做多|做空| +|OpAmount|0.1|开仓数量| +|OpMode|0|开仓方式: 吃单|挂单| +|MaxSpace|0.5|挂单失效距离| +|SlidePrice|0.1|下单滑动价(元)| +|MaxAmount|0.3|开仓最大单次下单量| +|AddGoal|true|加仓间距(元)| +|AddLine|0.8|加仓均价目标(元)| +|ProfitGoal|0.5|平仓目标(元)| +|Interval|true|轮询间隔(秒)| +|RestoreIt|false|恢复进度| +|RestoreType|0|持仓方向: 做多|做空| +|RestorePrice|false|持仓均价| +|RestoreAmount|false|持仓数量| +|RestoreProfit|false|上次盈利| +|SaveLocal|false|保存本地日志| +|StopLoss|8|止损(元)| +|MinStock|0.01|最小交易币数| + +> 源码 (javascript) + +``` javascript var TradeType = null; var OrgAccount = null; var Counter = {s : 0, f: 0, m: 0}; @@ -440,3 +451,12 @@ function main() { Sleep(Interval); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/9929 + +> 更新时间 + +2018-06-05 16:35:53 diff --git "a/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272 \346\263\250\351\207\212.md" "b/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272 \346\263\250\351\207\212.md" new file mode 100644 index 00000000..341ff4f0 --- /dev/null +++ "b/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272 \346\263\250\351\207\212.md" @@ -0,0 +1,331 @@ + +> 策略名称 + +移植 OKCoin 韭菜收割机 注释 + +> 策略作者 + +lkk91297 + +> 策略描述 + +移植自: https://github.com/richox/okcoin-leeks-reaper + +原作者说收手续费以后就失效了, 我只做了移植, 没有实盘测试, 有兴趣可以学习 +因为策略使用了GetTrades 这个函数在回测系统中是被模拟出来的, 所以回测没有什么意义, 只能直接上实盘测试 ! + +以下为原说明 + + +OKCoin韭菜收割机 +================ + +这是一个在OKCoin比特币交易平台上的高频交易机器人程序,从2016年6月策略基本定型,到2017年1月中旬,这个策略成功的把最初投入的6000块钱刷到了250000。由于近日央行对比特币实行高压政策,各大平台都停止了配资,并且开始征收交易费,该策略实际上已经失效了。 + + ![image](https://dn-filebox.qbox.me/707cd47e69d21b06f3815b933b471390a8d2cedd.png) + +本机器人程序基于两个主要策略: + +1. 趋势策略:在价格发生趋势性的波动时,及时下单跟进,即俗话说的**追涨杀跌**。 +2. 平衡策略:仓位偏离50%时,放出小单使仓位逐渐回归50%,防止趋势末期的反转造成回撤,即**收益落袋,不吃鱼尾**。 + +本程序要求平衡仓位,即(本金+融资=融币),使得仓位在50%时净资产不随着价格波动,也保证了发生趋势性波动时**涨跌都赚**。 + +感谢以下两个项目: + +* https://github.com/sutra/okcoin-client +* https://github.com/timmolter/xchange + +感谢OKCoin: + +* https://www.okcoin.cn + +BTC: 3QFn1qfZMhMQ4FhgENR7fha3T8ZVw1bEeU + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|BurstThresholdPct|5e-05|burst.threshold.pct| +|BurstThresholdVol|10|burst.threshold.vol| +|MinStock|0.1|最小交易量| +|CalcNetInterval|60|净值计算周期(秒)| +|BalanceTimeout|10000|平衡等代时间(毫秒)| +|TickInterval|280|轮训周期(毫秒)| + + +> 源码 (javascript) + +``` javascript +function LeeksReaper() { //创建构造函数LeeksReaper + var self = {} //构造一个空的对象 + self.numTick = 0 + self.lastTradeId = 0 + self.vol = 0 + self.askPrice = 0 + self.bidPrice = 0 + self.orderBook = { Asks: [], Bids: [] } + self.prices = [] + self.tradeOrderId = 0 + self.p = 0.5 + self.account = null + self.preCalc = 0 + self.preNet = 0 + //以上都是self对象的属性 + //创建一个方法 + self.updateTrades = function () { + var trades = _C(exchange.GetTrades) //创建一个变量trades用来接收_C函数返回的值,传入的参数为:exchange.GetTrades + if (self.prices.length == 0) { //如果self.prices的长度等于0 + while (trades.length == 0) { //如果trades等于0时执行下方的语句 + trades = trades.concat(_C(exchange.GetTrades)) //通过数组拼接的方法把_C函数返回的值与trades进行拼接,传入的参数为:exchange.GetTrades + } + for (var i = 0; i < 15; i++) { //循环,结束条件为i=15,每次循环i都自加1 + self.prices[i] = trades[trades.length - 1].Price//每次循环都把trades数组的最后一个值赋值给self对象的prices数组上,共循环15次 + } + } + //self.vol的值等于他自己乘以0.7加上_.reduce函数的返回值*0.3,其中_.reduce函数传入的参数为trades和一个匿名函数,还有一个0,匿名函数的形参为men,trade + self.vol = 0.7 * self.vol + 0.3 * _.reduce(trades, function (mem, trade) { + // Huobi not support trade.Id + //前半段是比较rade.Id是否大于self.lastTradeId,如果结果是true就执行下方的语句,如果是fales就往后看,后半段的且运算符,trade.Id == 0和trade.Time > self.lastTradeId都为真时才会返回true,有fales时就返回fales + if ((trade.Id > self.lastTradeId) || (trade.Id == 0 && trade.Time > self.lastTradeId)) { + //等号右边是一个三目运算,如果trade.Id=0就返回trade.Time,否则就返回trade.Id, self.lastTradeId。并进行比较返回最大的值,最后把返回的最大值赋给self.lastTradeId + self.lastTradeId = Math.max(trade.Id == 0 ? trade.Time : trade.Id, self.lastTradeId) + //mem=trade.Amount+mem + mem += trade.Amount + } + //返回mem + return mem + }, 0) + + + } + //self对象的一个方法 + self.updateOrderBook = function () { + // 创建一个变量orderBook用来接收_C函数返回的值,传入的参数为:exchange.GetDepth + var orderBook = _C(exchange.GetDepth) + self.orderBook = orderBook //self.orderBook 的值等于orderBook + if (orderBook.Bids.length < 3 || orderBook.Asks.length < 3) {//前半段是判断orderBook.Bids的长度是否小于3,后半段是判断orderBook.Asks的长度是否小于3,如果两边都小于3就执行下方的语句 + //返回undefined + return + } + //self.bidPrice的值等于orderBook.Bids数组的第一个值乘以0.618加上orderBook.Asks数组的第一个值乘以0.382加上0.01 + self.bidPrice = orderBook.Bids[0].Price * 0.618 + orderBook.Asks[0].Price * 0.382 + 0.01 + //同上 + self.askPrice = orderBook.Bids[0].Price * 0.382 + orderBook.Asks[0].Price * 0.618 - 0.01 + //删除price数组的第一个值,并返回第一个值 + self.prices.shift() + //prices数组向后添加值,值为函数_N的返回值 + self.prices.push(_N((orderBook.Bids[0].Price + orderBook.Asks[0].Price) * 0.35 + + (orderBook.Bids[1].Price + orderBook.Asks[1].Price) * 0.1 + + (orderBook.Bids[2].Price + orderBook.Asks[2].Price) * 0.05)) + } + //self对象的一个方法 + self.balanceAccount = function () { + // 创建一个变量account用来接收GetAccount函数返回的值 + var account = exchange.GetAccount() + //判断account是否为空,是就返回undefined + if (!account) { + return + } + //赋值 + self.account = account + //获取当前时间的时间戳数据 + var now = new Date().getTime() + //判断self.orderBook.Bids的长度是否大于0和now - self.preCalc的值是否大于(CalcNetInterval * 1000),如果都大于就执行下方语句 + if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) { + //赋值 + self.preCalc = now + //创建一个变量net用来接收_N函数的返回值 + var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks)) + //判断net是否不等于self.preNet,如果是就执行下方语句 + if (net != self.preNet) { + //赋值 + self.preNet = net + //调用函数LogProfit并传入net + LogProfit(net) + } + } + //赋值 + self.btc = account.Stocks + self.cny = account.Balance + self.p = self.btc * self.prices[self.prices.length - 1] / (self.btc * self.prices[self.prices.length - 1] + self.cny) + var balanced = false + //判断self.p的值是否小于0.48 + if (self.p < 0.48) { + //调用Log函数并传入参数"开始平衡", self.p + Log("开始平衡", self.p) + //self.cny =self.cny-300 + self.cny -= 300 + //判断self.orderBook.Bids的长度是否大于0,如果是就执行下方语句 + if (self.orderBook.Bids.length > 0) { + //调用buy函数并传入相应的参数 + exchange.Buy(self.orderBook.Bids[0].Price + 0.00, 0.01) + exchange.Buy(self.orderBook.Bids[0].Price + 0.01, 0.01) + exchange.Buy(self.orderBook.Bids[0].Price + 0.02, 0.01) + } + //如果self.p大于0.52就执行下方语句 + } else if (self.p > 0.52) { + //调用Log函数并传入参数"开始平衡", self.p + Log("开始平衡", self.p) + //self.btc=self.btc-0.03 + self.btc -= 0.03 + //判断self.orderBook.Bids的长度是否大于0,如果是就执行下方语句 + if (self.orderBook.Asks.length > 0) { + //调用Sell函数并传入相应的参数 + exchange.Sell(self.orderBook.Asks[0].Price - 0.00, 0.01) + exchange.Sell(self.orderBook.Asks[0].Price - 0.01, 0.01) + exchange.Sell(self.orderBook.Asks[0].Price - 0.02, 0.01) + } + } + //调用函数Sleep并传入参数BalanceTimeout + Sleep(BalanceTimeout) + //创建标量order来接收GetOrders函数返回的值 + var orders = exchange.GetOrders() + //判断orders是否为真 + if (orders) { + //遍历orders + for (var i = 0; i < orders.length; i++) { + //判断orders的id是否不等于self.tradeOrderId + if (orders[i].Id != self.tradeOrderId) { + //如果是就调用CancelOrder函数并传入参数orders[i].Id + exchange.CancelOrder(orders[i].Id) + } + } + } + } + + //self的一个方法 + self.poll = function () { + //self.numTick自加1 + self.numTick++ + //执行上方创建的三个方法updateTrades,updateOrderBook,updateOrderBook + self.updateTrades() + self.updateOrderBook() + self.balanceAccount() + //burstPrice的值等于self.prices数组的最后一个值乘以BurstThresholdPct + var burstPrice = self.prices[self.prices.length - 1] * BurstThresholdPct + //创建变量并赋值 + var bull = false + var bear = false + var tradeAmount = 0 + //判断self.account是否为真 + if (self.account) { + //是真的话就调用LogStatus函数并传入相应的参数 + LogStatus(self.account, 'Tick:', self.numTick, ', lastPrice:', self.prices[self.prices.length - 1], ', burstPrice: ', burstPrice) + } + //前半段是判断self.numTick的值是否大于2,如果是大于2就往执行||后面的语句,如果不是则判断&&运算符后面的语句,如果为fales直接返回fales,执行else的语句 + if (self.numTick > 2 && ( + self.prices[self.prices.length - 1] - _.max(self.prices.slice(-6, -1)) > burstPrice || + self.prices[self.prices.length - 1] - _.max(self.prices.slice(-6, -2)) > burstPrice && self.prices[self.prices.length - 1] > self.prices[self.prices.length - 2] + )) { + //变量bull赋值为true,tradeAmount赋值为self.cnyv/self.bidPrice乘以0.99 + bull = true + tradeAmount = self.cny / self.bidPrice * 0.99 + } + //同上面if + else if (self.numTick > 2 && ( + self.prices[self.prices.length - 1] - _.min(self.prices.slice(-6, -1)) < -burstPrice || + self.prices[self.prices.length - 1] - _.min(self.prices.slice(-6, -2)) < -burstPrice && self.prices[self.prices.length - 1] < self.prices[self.prices.length - 2] + )) { + bear = true + //赋值 + tradeAmount = self.btc + } + //判断self.vol是否小于BurstThresholdVol,如果是就执行if语句内的代码 + if (self.vol < BurstThresholdVol) { + tradeAmount *= self.vol / BurstThresholdVol + } + //判断self.numTick是否小于5,如果是就执行if语句内的代码 + if (self.numTick < 5) { + //tradeAmount=tradeAmount*0.8 + tradeAmount *= 0.8 + } + //判断self.numTick是否小于10 + if (self.numTick < 10) { + tradeAmount *= 0.8 + } + //前半段是判断!bull和!bear哪一个为真,后半段是判断tradeAmount是否小于MinStock,当两边都为真时就执行if语句内的代码 + if ((!bull && !bear) || tradeAmount < MinStock) { + return + } + //如果bull为真时就返回self.bidPrice的值,否则返回self.askPrice的值 + var tradePrice = bull ? self.bidPrice : self.askPrice + //tradeAmount是否大于或者等于MinStock,如果时就进行循环while的语句 + while (tradeAmount >= MinStock) { + //当bull为真时返回Buy函数的返回值,否则返回Sell函数的返回值 + var orderId = bull ? exchange.Buy(self.bidPrice, tradeAmount) : exchange.Sell(self.askPrice, tradeAmount) + //调用Sleep函数传入参数400,0.4秒后执行 + Sleep(400) + //判断orderId是否为true + if (orderId) { + //赋值 + self.tradeOrderId = orderId + //赋值 + var order = null + while (true) { + //rder的值等于GetOrder函数的返回值 + order = exchange.GetOrder(orderId) + //判断order是否为true + if (order) { + //判断两边的值是否相等 + if (order.Status == ORDER_STATE_PENDING) { + //调用CancelOrder函数 + exchange.CancelOrder(orderId) + //0.2秒后执行 + Sleep(200) + } else { + //跳出循环 + break + } + } + } + //赋值 + self.tradeOrderId = 0 + tradeAmount -= order.DealAmount + tradeAmount *= 0.9 + //判断两边是否相等 + if (order.Status == ORDER_STATE_CANCELED) { + //调用self的updateOrderBook方法 + self.updateOrderBook() + //判断是否为true,如果时就进行循环 + while (bull && self.bidPrice - tradePrice > 0.1) { + //赋值 + tradeAmount *= 0.99 + tradePrice += 0.1 + } + //判断是否为true,如果时就进行循环 + while (bear && self.askPrice - tradePrice < -0.1) { + tradeAmount *= 0.99 + tradePrice -= 0.1 + } + } + } + } + //赋值 + self.numTick = 0 + } + //返回self + return self +} + +//函数main +function main() { + //reaper 是构造函数的实例 + var reaper = LeeksReaper() + while (true) { + //通过实例调用poll方法 + reaper.poll() + Sleep(TickInterval) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/124178 + +> 更新时间 + +2018-10-31 13:43:19 diff --git "a/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.js" "b/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.md" similarity index 94% rename from "\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.js" rename to "\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.md" index e2c9f53e..a171061e 100644 --- "a/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.js" +++ "b/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/34388 -策略名称: 移植 OKCoin 韭菜收割机 -策略作者: Zero -策略描述: + +> 策略名称 + +移植 OKCoin 韭菜收割机 + +> 策略作者 + +Zero + +> 策略描述 移植自: https://github.com/richox/okcoin-leeks-reaper @@ -37,17 +42,23 @@ OKCoin韭菜收割机 BTC: 3QFn1qfZMhMQ4FhgENR7fha3T8ZVw1bEeU +> 策略参数 + + -参数 默认值 描述 ------------------ --------- ------------------- -BurstThresholdPct 5e-05 burst.threshold.pct -BurstThresholdVol 10 burst.threshold.vol -MinStock 0.1 最小交易量 -CalcNetInterval 60 净值计算周期(秒) -BalanceTimeout 10000 平衡等代时间(毫秒) -TickInterval 280 轮训周期(毫秒) -*/ +|参数|默认值|描述| +|----|----|----| +|BurstThresholdPct|5e-05|burst.threshold.pct| +|BurstThresholdVol|10|burst.threshold.vol| +|MinStock|0.1|最小交易量| +|CalcNetInterval|60|净值计算周期(秒)| +|BalanceTimeout|10000|平衡等代时间(毫秒)| +|TickInterval|280|轮训周期(毫秒)| + +> 源码 (javascript) + +``` javascript function LeeksReaper() { var self = {} self.numTick = 0 @@ -232,3 +243,12 @@ function main() { Sleep(TickInterval) } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/34388 + +> 更新时间 + +2017-02-16 09:33:13 diff --git "a/\347\252\234\345\244\251\347\214\264 - \347\247\273\345\212\250\346\255\242\346\215\237\347\211\210.js" "b/\347\252\234\345\244\251\347\214\264 - \347\247\273\345\212\250\346\255\242\346\215\237\347\211\210.md" similarity index 88% rename from "\347\252\234\345\244\251\347\214\264 - \347\247\273\345\212\250\346\255\242\346\215\237\347\211\210.js" rename to "\347\252\234\345\244\251\347\214\264 - \347\247\273\345\212\250\346\255\242\346\215\237\347\211\210.md" index 416675d2..3282de26 100644 --- "a/\347\252\234\345\244\251\347\214\264 - \347\247\273\345\212\250\346\255\242\346\215\237\347\211\210.js" +++ "b/\347\252\234\345\244\251\347\214\264 - \347\247\273\345\212\250\346\255\242\346\215\237\347\211\210.md" @@ -1,23 +1,34 @@ -/* -策略出处: https://www.fmz.com/strategy/13594 -策略名称: 窜天猴 - 移动止损版 -策略作者: Zero -策略描述: + +> 策略名称 + +窜天猴 - 移动止损版 + +> 策略作者 + +Zero + +> 策略描述 普及下移动止损的概念, 策略学习使用, 实盘慎用 ! +> 策略参数 + + -参数 默认值 描述 ----------------- ----- --------- -FastPeriod 5 入市快线周期 -SlowPeriod 15 入市慢线周期 -EnterPeriod 2 入市观察期 -PositionRatio 0.8 仓位比例 -TrailingStopLoss 0.02 移动止损(百分比) -StopLoss 0.01 止损(百分比) -Interval 10 轮询周期(秒) -*/ +|参数|默认值|描述| +|----|----|----| +|FastPeriod|5|入市快线周期| +|SlowPeriod|15|入市慢线周期| +|EnterPeriod|2|入市观察期| +|PositionRatio|0.8|仓位比例| +|TrailingStopLoss|0.02|移动止损(百分比)| +|StopLoss|0.01|止损(百分比)| +|Interval|10|轮询周期(秒)| + +> 源码 (javascript) + +``` javascript function main() { var STATE_IDLE = -1; var state = STATE_IDLE; @@ -100,3 +111,12 @@ function main() { Sleep(Interval*1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/13594 + +> 更新时间 + +2016-04-19 00:56:36 diff --git "a/\347\252\234\345\244\251\347\214\264 \345\244\232\347\251\272\350\276\203\351\207\217 \347\210\206\347\240\264\347\211\210.js" "b/\347\252\234\345\244\251\347\214\264 \345\244\232\347\251\272\350\276\203\351\207\217 \347\210\206\347\240\264\347\211\210.md" similarity index 86% rename from "\347\252\234\345\244\251\347\214\264 \345\244\232\347\251\272\350\276\203\351\207\217 \347\210\206\347\240\264\347\211\210.js" rename to "\347\252\234\345\244\251\347\214\264 \345\244\232\347\251\272\350\276\203\351\207\217 \347\210\206\347\240\264\347\211\210.md" index 5008303a..6c1bbe74 100644 --- "a/\347\252\234\345\244\251\347\214\264 \345\244\232\347\251\272\350\276\203\351\207\217 \347\210\206\347\240\264\347\211\210.js" +++ "b/\347\252\234\345\244\251\347\214\264 \345\244\232\347\251\272\350\276\203\351\207\217 \347\210\206\347\240\264\347\211\210.md" @@ -1,26 +1,37 @@ -/* -策略出处: https://www.fmz.com/strategy/13597 -策略名称: 窜天猴 多空较量 爆破版 -策略作者: Zero -策略描述: + +> 策略名称 + +窜天猴 多空较量 爆破版 + +> 策略作者 + +Zero + +> 策略描述 - 依靠多空力量做为开仓条件 - 固定的止盈止损点 - 名子是乱起的, 学习使用, 实盘慎用 +> 策略参数 + + -参数 默认值 描述 -------------- ----- --------- -DepthLevel 5 盘口统计深度 -EnterPeriod 2 观察周期 -CalcInterval 10 观察轮询周期(秒) -DiffRatio 2.1 币量倍数 -PositionRatio 0.8 仓位比例 -StopProfit 0.02 止盈(百分比) -StopLoss 0.01 止损(百分比) -Interval true 价格轮询周期(秒) -*/ +|参数|默认值|描述| +|----|----|----| +|DepthLevel|5|盘口统计深度| +|EnterPeriod|2|观察周期| +|CalcInterval|10|观察轮询周期(秒)| +|DiffRatio|2.1|币量倍数| +|PositionRatio|0.8|仓位比例| +|StopProfit|0.02|止盈(百分比)| +|StopLoss|0.01|止损(百分比)| +|Interval|true|价格轮询周期(秒)| + +> 源码 (javascript) + +``` javascript function calcDepth(orders) { var base = parseInt(orders[0].Price); var allAmount = 0; @@ -96,3 +107,12 @@ function main() { } } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/13597 + +> 更新时间 + +2016-04-18 16:39:43 diff --git "a/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" "b/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.md" similarity index 97% rename from "\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" rename to "\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.md" index 92bf191b..62ed9ec6 100644 --- "a/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.js" +++ "b/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/30861 -策略名称: 策略框架模板 -策略作者: 小小梦 -策略描述: + +> 策略名称 + +策略框架模板 + +> 策略作者 + +小小梦 + +> 策略描述 新策略框架 现货, 开多,开空,止损,加仓,平仓。 @@ -19,18 +24,24 @@ var TASK_COVER = 5; 使用说明: https://www.botvs.com/bbs-topic/634 +> 策略参数 + -参数 默认值 描述 ----------- ------ ----------- -OpMode 0 下单方式: 吃单|挂单 -MaxSpace 0.5 挂单失效距离 -SlidePrice 0.1 下单滑动价(元) -MaxAmount 0.8 开仓最大单次下单量 -RetryDelay 500 失败重试(毫秒) -Interval 500 轮询间隔 -_minStock 0.01 最小交易币数 -*/ +|参数|默认值|描述| +|----|----|----| +|OpMode|0|下单方式: 吃单|挂单| +|MaxSpace|0.5|挂单失效距离| +|SlidePrice|0.1|下单滑动价(元)| +|MaxAmount|0.8|开仓最大单次下单量| +|RetryDelay|500|失败重试(毫秒)| +|Interval|500|轮询间隔| +|_minStock|0.01|最小交易币数| + + +> 源码 (javascript) + +``` javascript // 模板全局变量 // - 状态 var TASK_IDLE = 0; @@ -630,3 +641,12 @@ function main() { $.Relation_Exchange_onTick(exchanges[1], onTick2); $.Trend(); // 不用传参数。 } +``` + +> 策略出处 + +https://www.fmz.com/strategy/30861 + +> 更新时间 + +2018-05-30 18:28:23 diff --git "a/\347\256\200\345\215\225\345\233\272\345\256\232\344\273\267\346\240\274\346\255\242\346\215\237\346\234\272\345\231\250\344\272\272|Stop Loss Below Fixed Price.md" "b/\347\256\200\345\215\225\345\233\272\345\256\232\344\273\267\346\240\274\346\255\242\346\215\237\346\234\272\345\231\250\344\272\272|Stop Loss Below Fixed Price.md" new file mode 100644 index 00000000..95f6bcf2 --- /dev/null +++ "b/\347\256\200\345\215\225\345\233\272\345\256\232\344\273\267\346\240\274\346\255\242\346\215\237\346\234\272\345\231\250\344\272\272|Stop Loss Below Fixed Price.md" @@ -0,0 +1,82 @@ + +> 策略名称 + +简单固定价格止损机器人|Stop Loss Below Fixed Price + +> 策略作者 + +botvsing + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|StopPrice|5000|Fixed price to stop loss| +|Intervel|10|Intervel(second) of checking coin price| + + +> 源码 (javascript) + +``` javascript +function CancelPendingOrders() { + var orders = _C(exchange.GetOrders); + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]); + } +} +function StopLoss(){ + var done = false + while(!done){ + var ticker = _C(exchange.GetTicker) + account = _C(exchange.GetAccount) + var price = ticker.Buy + var amount = account.Stocks + try{ + if(amount > 0){ + var id = exchange.Sell(price, amount); + if(id){ + exchange.CancelOrder(id) + } + else{ + Log('all coins are sold') + Log('total coins: ', account.Stocks) + done = true + } + } + }catch(err){ + Log('error, stop') + done = true + } + Sleep(1000); + } +} +function main() { + Log('robot starts to run') + CancelPendingOrders() + var account = _C(exchange.GetAccount) + Log('total coins: ', account.Stocks); + while(true){ + var ticker = _C(exchange.GetTicker) + if(ticker.Last <= StopPrice){ + Log('Last price is:', ticker.Last, 'Stop price is: ', StopPrice) + Log('the stop price has reached, start to sell') + StopLoss(); + break; + } + Sleep(Intervel*1000) + } + Log('robot has stopped') +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/121081 + +> 更新时间 + +2018-10-16 10:55:52 diff --git a/Moving Average Strategy in 30 lines.js "b/\347\256\200\345\215\225\345\235\207\347\272\277\347\255\226\347\225\245|Moving Average Bot 30 lines.md" similarity index 78% rename from Moving Average Strategy in 30 lines.js rename to "\347\256\200\345\215\225\345\235\207\347\272\277\347\255\226\347\225\245|Moving Average Bot 30 lines.md" index f3c95821..91549a77 100644 --- a/Moving Average Strategy in 30 lines.js +++ "b/\347\256\200\345\215\225\345\235\207\347\272\277\347\255\226\347\225\245|Moving Average Bot 30 lines.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/103070 -策略名称: Moving Average Strategy in 30 lines -策略作者: botvsing -策略描述: + +> 策略名称 + +简单均线策略|Moving Average Bot 30 lines + +> 策略作者 + +botvsing + +> 策略描述 "Talk is cheap. Show me the code" @@ -16,17 +21,27 @@ Beginers can start with this strategy, learn how to code, know the difference be https://dn-filebox.qbox.me/fb4d0c7d773ca83e9d0230927705d419dc0bbeaa.png +> 策略参数 + + -参数 默认值 描述 ------------ ----- --------------------- -Slippage 0.1 Slippage -FastPeriod 5 fast line periods -SlowPeriod 15 slow line periods -EnterPeriod 2 observe periods -Interval 120 Interval time(second) -*/ +|参数|默认值|描述| +|----|----|----| +|Slippage|0.1|Slippage| +|FastPeriod|5|fast line periods| +|SlowPeriod|15|slow line periods| +|EnterPeriod|2|observe periods| +|Interval|120|Interval time(second)| + +> 源码 (javascript) + +``` javascript +if (exchange.GetName() != 'BotVS'){ + throw 'only support BotVS'; +} function main() { + Log('started'); var initAccount = _C(exchange.GetAccount); var ticker = exchange.GetTicker(); var InitValue = (initAccount.Stocks + initAccount.FrozenStocks)*ticker.Last + initAccount.Balance + initAccount.FrozenBalance; @@ -58,3 +73,12 @@ function main() { Sleep(Interval*1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/103070 + +> 更新时间 + +2018-10-16 10:59:06 diff --git "a/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.js" "b/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.md" similarity index 78% rename from "\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.js" rename to "\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.md" index f01e9ab2..ab2d75e9 100644 --- "a/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.js" +++ "b/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.md" @@ -1,23 +1,34 @@ -/* -策略出处: https://www.fmz.com/strategy/57029 -策略名称: 简单多品种商品期货均线策略 -策略作者: Zero -策略描述: + +> 策略名称 + +简单多品种商品期货均线策略 + +> 策略作者 + +Zero + +> 策略描述 商品期货类库实现了$.CTA函数的策略框架,借助该策略框架, 可以短短几十行实现一个并发稳定可实盘的多品种策略 https://dn-filebox.qbox.me/21384f4e53937bc1dd252ff478ff08e5b4d52e71.png +> 策略参数 + -参数 默认值 描述 -------------- ----------- ---- -Symbols rb000,MA000 操作品种 -FastPeriod 5 快线周期 -SlowPeriod 20 慢线周期 -ConfirmPeriod 2 确认周期 -Lots true 开仓手数 -*/ +|参数|默认值|描述| +|----|----|----| +|Symbols|rb000,MA000|操作品种| +|FastPeriod|5|快线周期| +|SlowPeriod|20|慢线周期| +|ConfirmPeriod|2|确认周期| +|Lots|true|开仓手数| + + +> 源码 (javascript) + +``` javascript /*backtest start: 2017-06-01 00:00:00 end: 2017-10-01 00:00:00 @@ -50,3 +61,12 @@ function main() { } }); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/57029 + +> 更新时间 + +2017-11-29 12:08:58 diff --git "a/\347\256\200\345\215\225\347\275\221\346\240\274\346\265\213\350\257\225.md" "b/\347\256\200\345\215\225\347\275\221\346\240\274\346\265\213\350\257\225.md" new file mode 100644 index 00000000..413157c9 --- /dev/null +++ "b/\347\256\200\345\215\225\347\275\221\346\240\274\346\265\213\350\257\225.md" @@ -0,0 +1,129 @@ + +> 策略名称 + +简单网格测试 + +> 策略作者 + +cnxzcxy + + + + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2018-08-01 00:00:00 +end: 2018-09-01 15:00:00 +period: 15m +exchanges: [{"eid":"Huobi","currency":"LTC_BTC","stocks":0}] +*/ + +var runBuyOrder = []; +var runSellOrder = []; +var basePrice = 0; +var percent = 0.05; + +function onTick(){ + var date = _D(); + var depth = exchange.GetDepth(); + account = exchange.GetAccount(); + + //初始化账户 + if((account.Balance > 0) && (basePrice == 0)){ + buyMoney = account.Balance * 0.09; + basePrice = depth.Asks[0].Price; + + buyPrice = basePrice * (1-percent * 0); + runBuyOrder.push(exchange.Buy(buyPrice, buyMoney / buyPrice)); + + buyPrice = basePrice * (1-percent * 1); + runBuyOrder.push(exchange.Buy(buyPrice, buyMoney / buyPrice)); + + buyPrice = basePrice * (1-percent * 2); + runBuyOrder.push(exchange.Buy(buyPrice, buyMoney / buyPrice)); + + buyPrice = basePrice * (1-percent * 3); + runBuyOrder.push(exchange.Buy(buyPrice, buyMoney / buyPrice)); + + buyPrice = basePrice * (1-percent * 4); + runBuyOrder.push(exchange.Buy(buyPrice, buyMoney / buyPrice)); + + buyPrice = basePrice * (1-percent * 5); + runBuyOrder.push(exchange.Buy(buyPrice, buyMoney / buyPrice)); + + buyPrice = basePrice * (1-percent * 6); + runBuyOrder.push(exchange.Buy(buyPrice, buyMoney / buyPrice)); + + buyPrice = basePrice * (1-percent * 7); + runBuyOrder.push(exchange.Buy(buyPrice, buyMoney / buyPrice)); + + buyPrice = basePrice * (1-percent * 8); + runBuyOrder.push(exchange.Buy(buyPrice, buyMoney / buyPrice)); + + buyPrice = basePrice * (1-percent * 9); + runBuyOrder.push(exchange.Buy(buyPrice, buyMoney / buyPrice)); + + buyPrice = basePrice * (1-percent * 10); + runBuyOrder.push(exchange.Buy(buyPrice, buyMoney / buyPrice)); + + Log(date); + Log('交易所:', exchange.GetName(), ' 账户:', exchange.GetAccount()); + Log('卖单:', runSellOrder, ' 买单:', runBuyOrder); + + } + + //检查订单轮询 + allOrders = runBuyOrder.concat(runSellOrder); + allOrders.forEach(function(orderId){ + order = exchange.GetOrder(orderId); + //检查卖单 + if(runSellOrder.indexOf(order.Id) > -1){ + if((order.Status == ORDER_STATE_CLOSED) && (order.Type == ORDER_TYPE_SELL)){ + Log(date); + Log('卖单成功 价格:', order.Price, ' 数量:', order.DealAmount); + Log('交易所:', exchange.GetName(), ' 账户:', exchange.GetAccount()); + //从本地数据库里面去掉并挂新的买单 + index = runSellOrder.indexOf(order.Id); + runSellOrder.splice(index, 1); + buyPrice = order.Price * (1 - percent); + runBuyOrder.push(exchange.Buy(buyPrice, order.DealAmount * order.Price / buyPrice)); + } + + } + //检查买单 + if(runBuyOrder.indexOf(order.Id) > -1){ + if((order.Status == ORDER_STATE_CLOSED) && (order.Type == ORDER_TYPE_BUY)){ + Log(date); + Log('买单成功 价格:', order.Price, ' 数量:', order.DealAmount); + Log('交易所:', exchange.GetName(), ' 账户:', exchange.GetAccount()); + //从本地数据库里面去掉并挂新的卖单 + index = runBuyOrder.indexOf(order.Id); + runBuyOrder.splice(index, 1); + sellPrice = order.Price * (1 + percent); + runSellOrder.push(exchange.Sell(sellPrice, order.DealAmount)); + } + + } + }); + +} + +function main(){ + while(true){ + onTick(); + } + +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/116289 + +> 更新时间 + +2018-09-14 16:05:05 diff --git "a/\347\256\200\345\215\225\351\242\204\345\256\232\344\271\260\345\205\245\345\220\216\345\215\226\345\207\272\346\234\272\345\231\250\344\272\272|Buy then Sell (ping-pong strategy).md" "b/\347\256\200\345\215\225\351\242\204\345\256\232\344\271\260\345\205\245\345\220\216\345\215\226\345\207\272\346\234\272\345\231\250\344\272\272|Buy then Sell (ping-pong strategy).md" new file mode 100644 index 00000000..013b7b8a --- /dev/null +++ "b/\347\256\200\345\215\225\351\242\204\345\256\232\344\271\260\345\205\245\345\220\216\345\215\226\345\207\272\346\234\272\345\231\250\344\272\272|Buy then Sell (ping-pong strategy).md" @@ -0,0 +1,63 @@ + +> 策略名称 + +简单预定买入后卖出机器人|Buy then Sell (ping-pong strategy) + +> 策略作者 + +botvsing + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|BUYPRICE|6200|buy price| +|BUYAMOUNT|0.1|buy amount| +|SELLPRICE|6400|sell price after buying| +|Intervel|6|sleep time (second)| + + +> 源码 (javascript) + +``` javascript +function CancelPendingOrders() { + var orders = _C(exchange.GetOrders); + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]); + } +} +function main() { + Log('robot starts to run') + if(BUYPRICE >= SELLPRICE){ + throw 'check buy and sell price' + } + CancelPendingOrders() + var account = _C(exchange.GetAccount) + Log('account: ', account.Balance); + if(account.Balance > BUYPRICE*BUYAMOUNT){ + exchange.Buy(BUYPRICE, BUYAMOUNT); + }else{ + throw 'account balances is not enough' + } + while(true){ + account = _C(exchange.GetAccount) + if(account.Stocks >= 0.1*BUYAMOUNT){ + exchange.Sell(SELLPRICE, account.Stocks) + } + Sleep(Intervel*1000) + } +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/121228 + +> 更新时间 + +2018-10-16 10:56:26 diff --git "a/\347\273\217\345\205\270\345\235\207\347\272\277\347\255\226\347\225\245.md" "b/\347\273\217\345\205\270\345\235\207\347\272\277\347\255\226\347\225\245.md" new file mode 100644 index 00000000..c45dd1e3 --- /dev/null +++ "b/\347\273\217\345\205\270\345\235\207\347\272\277\347\255\226\347\225\245.md" @@ -0,0 +1,101 @@ + +> 策略名称 + +经典均线策略 + +> 策略作者 + +Zero + +> 策略描述 + +"Talk is cheap. Show me the code" + +教学性质, 实盘慎用. + + +注: ` 策略使用了交易模板类库` + +`希望新手从此策略入门, 一步步学习编写策略, 并体验到模拟与真实环境对交易系统的影响` + +https://dn-filebox.qbox.me/fb4d0c7d773ca83e9d0230927705d419dc0bbeaa.png + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|FastPeriod|5|入市快线周期| +|SlowPeriod|15|入市慢线周期| +|EnterPeriod|2|入市观察期| +|ExitFastPeriod|7|离市快线周期| +|ExitSlowPeriod|15|离市慢线周期| +|ExitPeriod|true|离市观察期| +|PositionRatio|0.8|仓位比例| +|StopLossRatio|0.05|止损比率| +|Interval|10|轮询周期(秒)| + + +> 源码 (javascript) + +``` javascript +function main() { + var STATE_IDLE = -1; + var state = STATE_IDLE; + var entryPrice = 0; + var initAccount = _C(exchange.GetAccount); + Log(initAccount); + while (true) { + if (state === STATE_IDLE) { + var n = $.Cross(FastPeriod, SlowPeriod); + if (Math.abs(n) >= EnterPeriod) { + var account = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + var obj = n > 0 ? $.Buy(_N(account.Balance * PositionRatio / ticker.Sell, 3)) : $.Sell(_N(account.Stocks * PositionRatio, 3)); + if (obj) { + opAmount = obj.amount; + entryPrice = obj.price; + state = n > 0 ? PD_LONG : PD_SHORT; + Log("开仓详情", obj, "交叉周期", n); + } + } + } else { + var n = $.Cross(ExitFastPeriod, ExitSlowPeriod); + var needCover = Math.abs(n) >= ExitPeriod && ((state === PD_LONG && n < 0) || (state === PD_SHORT && n > 0)); + if (needCover) { + Log("离市平仓"); + } else { + var ticker = _C(exchange.GetTicker); + if (state === PD_LONG) { + if (ticker.Buy < entryPrice*(1-StopLossRatio)) { + needCover = true; + Log("止损平仓"); + } + } else { + if (ticker.Sell > entryPrice*(1+StopLossRatio)) { + needCover = true; + Log("止损平仓"); + } + } + } + if (needCover) { + var nowAccount = _C(exchange.GetAccount); + var obj = state === PD_LONG ? $.Sell(_N(nowAccount.Stocks - initAccount.Stocks, 3)) : $.Buy(_N(initAccount.Stocks - nowAccount.Stocks, 3)); + state = STATE_IDLE; + nowAccount = _C(exchange.GetAccount); + LogProfit(nowAccount.Balance - initAccount.Balance, '钱:', nowAccount.Balance, '币:', nowAccount.Stocks, '平仓详情:', obj, "交叉周期", n); + } + } + Sleep(Interval*1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/12348 + +> 更新时间 + +2018-10-13 12:05:55 diff --git "a/\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.js" "b/\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.md" similarity index 89% rename from "\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.js" rename to "\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.md" index 0b786b7c..dc314bc7 100644 --- "a/\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.js" +++ "b/\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.md" @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/1125 -策略名称: 统计K线回测是否存在趋势 -策略作者: botvsing -策略描述: + +> 策略名称 + +统计K线回测是否存在趋势 + +> 策略作者 + +botvsing + +> 策略描述 这个策略主要是想从回测数据中考察是否可以根据前面涨跌情况,预测接下来的涨跌。具体如下:如果5根K线中,出现4个或5个上涨,那么下一根是否更趋向于上涨,该策略将统计出上涨的频率。当然也已更改策略的参数统计其它上涨或下跌的情况。在几天的回测时间内,策略运行的还可以,但是回测周期较长时,比如从本月13号到现在,就会出现混乱,不清楚原因。 -*/ + +> 源码 (javascript) + +``` javascript function adjustFloat(v) { return Math.floor(v*1000)/1000; @@ -48,3 +56,12 @@ function main(){ Sleep(300000); //间隔时间,应与所选K线周期相同?这里是5分钟 } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/1125 + +> 更新时间 + +2014-10-28 19:32:09 diff --git "a/\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\344\273\267(by JackConan).js" "b/\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\344\273\267(by JackConan).md" similarity index 84% rename from "\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\344\273\267(by JackConan).js" rename to "\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\344\273\267(by JackConan).md" index a6f00294..ccf51651 100644 --- "a/\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\344\273\267(by JackConan).js" +++ "b/\347\273\237\350\256\241\345\220\204\344\270\252\345\271\263\345\217\260\351\227\264\347\232\204\346\234\200\345\244\247\345\267\256\344\273\267(by JackConan).md" @@ -1,14 +1,22 @@ -/* -策略出处: https://www.fmz.com/strategy/86 -策略名称: 统计各个平台间的最大差价(by JackConan) -策略作者: yzl_126@126.com -策略描述: + +> 策略名称 + +统计各个平台间的最大差价(by JackConan) + +> 策略作者 + +yzl_126@126.com + +> 策略描述 统计各个平台间的最大差价; 如果要打印当时各交易所的市场行情,可以把 //printCurPrice(); 前面的注释//去掉; -*/ + +> 源码 (javascript) + +``` javascript var maxSpace = 0; function adjustFloat(v) { @@ -57,3 +65,12 @@ function main() { Sleep(60000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/86 + +> 更新时间 + +2014-06-22 21:15:34 diff --git "a/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).js" "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).md" similarity index 91% rename from "\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).js" rename to "\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).md" index 299f4634..4911540b 100644 --- "a/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).js" +++ "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/8474 -策略名称: 网格变形策略之单边网格 (OK期货) -策略作者: Zero -策略描述: + +> 策略名称 + +网格变形策略之单边网格 (OK期货) + +> 策略作者 + +Zero + +> 策略描述 网格可以自定义方向 先买后卖: @@ -14,41 +19,50 @@ 网格带有自动止损和移动功能 +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|ContractTypeIdx|0|合约品种: 当周|次周|季度| +|OpType|0|网格方向: 先买后卖|先卖后买| +|FirstPriceAuto|false|首价格自动| +|FirstPrice|100|首价格| +|AllNum|10|总数量| +|PriceGrid|true|价格间隔| +|PriceDiff|2|价差(元)| +|AmountType|0|订单大小: 买卖同量|自定义量| +|AmountOnce|true|单笔数量| +|BAmountOnce|true|买单大小| +|SAmountOnce|true|卖单大小| +|MarginLevelIdx|0|杠杆大小: 10|20| +|EnableProtectDiff|false|开启价差保护| +|ProtectDiff|20|入市价差保护| +|CancelAllWS|true|停止时取消取有挂单| +|CheckInterval|2000|轮询间隔| +|Interval|1300|失败重试间隔| +|RestoreProfit|false|恢复上次盈利| +|LastProfit|false|上次盈利| +|ProfitAsOrg|false|上次盈利算入均价| +|EnableStopLoss|false|开启止损| +|StopLoss|0.1|最大浮动亏损| +|StopLossMode|0|止损后操作: 回收并退出|回收再撒网| +|AutoMove|false|自动移动| +|MaxDistance|20|最大距离(元)| +|MaxIdle|7200|最大空闲(秒)| + -参数 默认值 描述 ------------------ ----- ------------------ -ContractTypeIdx 0 合约品种: 当周|次周|季度 -OpType 0 网格方向: 先买后卖|先卖后买 -FirstPriceAuto false 首价格自动 -FirstPrice 100 首价格 -AllNum 10 总数量 -PriceGrid true 价格间隔 -PriceDiff 2 价差(元) -AmountType 0 订单大小: 买卖同量|自定义量 -AmountOnce true 单笔数量 -BAmountOnce true 买单大小 -SAmountOnce true 卖单大小 -MarginLevelIdx 0 杠杆大小: 10|20 -EnableProtectDiff false 开启价差保护 -ProtectDiff 20 入市价差保护 -CancelAllWS true 停止时取消取有挂单 -CheckInterval 2000 轮询间隔 -Interval 1300 失败重试间隔 -RestoreProfit false 恢复上次盈利 -LastProfit false 上次盈利 -ProfitAsOrg false 上次盈利算入均价 -EnableStopLoss false 开启止损 -StopLoss 0.1 最大浮动亏损 -StopLossMode 0 止损后操作: 回收并退出|回收再撒网 -AutoMove false 自动移动 -MaxDistance 20 最大距离(元) -MaxIdle 7200 最大空闲(秒) - -按钮 默认值 描述 ----- ---------- ---------- -收网 __button__ 停止并平衡到初始状态 -*/ + +|按钮|默认值|描述| +|----|----|----| +|收网|__button__|停止并平衡到初始状态| + + +> 源码 (javascript) + +``` javascript var isFuture = false; function hasOrder(orders, orderId) { @@ -474,3 +488,12 @@ function main() { } +``` + +> 策略出处 + +https://www.fmz.com/strategy/8474 + +> 更新时间 + +2018-06-05 15:09:40 diff --git "a/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.md" similarity index 91% rename from "\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" rename to "\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.md" index c80ae495..3ad6845c 100644 --- "a/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.js" +++ "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/629 -策略名称: 网格变形策略之单边网格 -策略作者: Zero -策略描述: + +> 策略名称 + +网格变形策略之单边网格 + +> 策略作者 + +Zero + +> 策略描述 网格可以自定义方向 先买后卖: @@ -14,51 +19,60 @@ 网格带有自动止损和移动功能 +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|OpType|0|网格方向: 先买后卖|先卖后买| +|FirstPriceAuto|true|首价格自动| +|FirstPrice|100|首价格| +|AllNum|10|总数量| +|PriceGrid|true|价格间隔| +|PriceDiff|2|价差(元)| +|AmountType|0|订单大小: 买卖同量|自定义量| +|AmountOnce|0.1|单笔数量| +|BAmountOnce|0.1|买单大小| +|SAmountOnce|0.1|卖单大小| +|AmountCoefficient|*1|量差| +|AmountDot|3|量小数点最长位数| +|EnableProtectDiff|false|开启价差保护| +|ProtectDiff|20|入市价差保护| +|CancelAllWS|true|停止时取消所有挂单| +|CheckInterval|2000|轮询间隔| +|Interval|1300|失败重试间隔| +|RestoreProfit|false|恢复上次盈利| +|LastProfit|false|上次盈利| +|ProfitAsOrg|false|上次盈利算入均价| +|EnableAccountCheck|true|启用资金检验| +|EnableStopLoss|false|开启止损| +|StopLoss|100|最大浮动亏损(元)| +|StopLossMode|0|止损后操作: 回收并退出|回收再撒网| +|EnableStopWin|false|开启止盈| +|StopWin|120|最大浮动盈利(元)| +|StopWinMode|0|止盈后操作: 回收并退出|回收再撒网| +|AutoMove|false|自动移动| +|MaxDistance|20|最大距离(元)| +|MaxIdle|7200|最大空闲(秒)| +|EnableDynamic|false|开启动态挂单| +|DynamicMax|30|订单失效距离(元)| +|ResetData|true|启动时清空所有数据| +|Precision|5|价格小数位长度| +|XPrecision|5|下单量小数位长度| +|MinStock|0.001|最小交易量| + -参数 默认值 描述 ------------------- ----- ------------------ -OpType 0 网格方向: 先买后卖|先卖后买 -FirstPriceAuto true 首价格自动 -FirstPrice 100 首价格 -AllNum 10 总数量 -PriceGrid true 价格间隔 -PriceDiff 2 价差(元) -AmountType 0 订单大小: 买卖同量|自定义量 -AmountOnce 0.1 单笔数量 -BAmountOnce 0.1 买单大小 -SAmountOnce 0.1 卖单大小 -AmountCoefficient *1 量差 -AmountDot 3 量小数点最长位数 -EnableProtectDiff false 开启价差保护 -ProtectDiff 20 入市价差保护 -CancelAllWS true 停止时取消所有挂单 -CheckInterval 2000 轮询间隔 -Interval 1300 失败重试间隔 -RestoreProfit false 恢复上次盈利 -LastProfit false 上次盈利 -ProfitAsOrg false 上次盈利算入均价 -EnableAccountCheck true 启用资金检验 -EnableStopLoss false 开启止损 -StopLoss 100 最大浮动亏损(元) -StopLossMode 0 止损后操作: 回收并退出|回收再撒网 -EnableStopWin false 开启止盈 -StopWin 120 最大浮动盈利(元) -StopWinMode 0 止盈后操作: 回收并退出|回收再撒网 -AutoMove false 自动移动 -MaxDistance 20 最大距离(元) -MaxIdle 7200 最大空闲(秒) -EnableDynamic false 开启动态挂单 -DynamicMax 30 订单失效距离(元) -ResetData true 启动时清空所有数据 -Precision 5 价格小数位长度 -XPrecision 5 下单量小数位长度 -MinStock 0.001 最小交易量 - -按钮 默认值 描述 ----- ---------- ---------- -收网 __button__ 停止并平衡到初始状态 -*/ + +|按钮|默认值|描述| +|----|----|----| +|收网|__button__|停止并平衡到初始状态| + + +> 源码 (javascript) + +``` javascript function hasOrder(orders, orderId) { for (var i = 0; i < orders.length; i++) { if (orders[i].Id == orderId) { @@ -650,3 +664,12 @@ function main() { Sleep(1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/629 + +> 更新时间 + +2018-04-08 12:23:15 diff --git "a/\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.js" "b/\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.md" similarity index 88% rename from "\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.js" rename to "\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.md" index 3450b1c5..a0541eca 100644 --- "a/\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.js" +++ "b/\347\275\221\346\240\274\357\274\210\346\263\242\346\256\265\357\274\211\351\246\231\345\206\234\347\211\210.md" @@ -1,19 +1,28 @@ -/* -策略出处: https://www.fmz.com/strategy/67495 -策略名称: 网格(波段)香农版 -策略作者: 小码哥 -策略描述: +> 策略名称 +网格(波段)香农版 +> 策略作者 -参数 默认值 描述 ---------------- ----- ----- -targetBaseRatio 0.5 仓位价值比 -minTradeLimit 0.001 最小交易量 -*/ +小码哥 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|targetBaseRatio|0.5|仓位价值比| +|minTradeLimit|0.001|最小交易量| +> 源码 (javascript) + +``` javascript + /*backtest start: 2017-10-01 end: 2018-01-01 @@ -96,3 +105,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/67495 + +> 更新时间 + +2018-01-07 18:26:59 diff --git "a/\350\202\241\347\245\250\350\257\201\345\210\270\346\237\245\350\257\242\344\271\260\345\215\226\347\244\272\344\276\213.js" "b/\350\202\241\347\245\250\350\257\201\345\210\270\346\237\245\350\257\242\344\271\260\345\215\226\347\244\272\344\276\213.js" deleted file mode 100644 index a4c9a977..00000000 --- "a/\350\202\241\347\245\250\350\257\201\345\210\270\346\237\245\350\257\242\344\271\260\345\215\226\347\244\272\344\276\213.js" +++ /dev/null @@ -1,45 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/5541 -策略名称: 股票证券查询买卖示例 -策略作者: Zero -策略描述: - -可以查询持仓, 合约详细信息, 出现not login错误表示还没有成功登陆服务器, not ready表示行情数据还没有接收到, 程序会自动重试 - - -参数 默认值 描述 ------------- --------- ---- -ContractType 000001.SZ 合约名称 -Num 100 手数 -*/ - -function main() { - while (!exchange.IO("status")) { - Sleep(1000) - } - Sleep(1000) - Log(_C(exchange.SetContractType, ContractType)); - while (!exchange.IO("status")) { - Sleep(1000) - } - exchange.SetDirection("buy") - var ticker = exchange.GetTicker() - Log("ticker", ticker) - if (ticker) { - exchange.Buy(ticker.Sell+10, Num) - Sleep(1000) - Log(exchange.GetPosition()) - } - exchange.SetDirection("closebuy") - ticker = exchange.GetTicker() - exchange.Sell(ticker.Buy - 1, Num) - Sleep(1000) - Log(exchange.GetPosition()) - Log(exchange.GetAccount()) - while(true){ - ticker = exchange.GetTicker() - if (ticker) { - LogStatus(ticker.Last, exchange.GetPosition()) - } - } -} diff --git "a/\350\214\203\344\276\213-\345\256\232\346\227\266\346\265\213\350\257\225\345\276\256\344\277\241\346\266\210\346\201\257\346\216\250\351\200\201.js" "b/\350\214\203\344\276\213-\345\256\232\346\227\266\346\265\213\350\257\225\345\276\256\344\277\241\346\266\210\346\201\257\346\216\250\351\200\201.md" similarity index 74% rename from "\350\214\203\344\276\213-\345\256\232\346\227\266\346\265\213\350\257\225\345\276\256\344\277\241\346\266\210\346\201\257\346\216\250\351\200\201.js" rename to "\350\214\203\344\276\213-\345\256\232\346\227\266\346\265\213\350\257\225\345\276\256\344\277\241\346\266\210\346\201\257\346\216\250\351\200\201.md" index a2f06de0..17c4f8c2 100644 --- "a/\350\214\203\344\276\213-\345\256\232\346\227\266\346\265\213\350\257\225\345\276\256\344\277\241\346\266\210\346\201\257\346\216\250\351\200\201.js" +++ "b/\350\214\203\344\276\213-\345\256\232\346\227\266\346\265\213\350\257\225\345\276\256\344\277\241\346\266\210\346\201\257\346\216\250\351\200\201.md" @@ -1,13 +1,21 @@ -/* -策略出处: https://www.fmz.com/strategy/15098 -策略名称: 范例-定时测试微信消息推送 -策略作者: 小小梦 -策略描述: + +> 策略名称 + +范例-定时测试微信消息推送 + +> 策略作者 + +小小梦 + +> 策略描述 定时测试微信消息推送 范例~抛砖引玉,方便用户参考学习。 -*/ + +> 源码 (javascript) + +``` javascript function main(){ var initTime = (new Date()).getTime() ; Log("程序起始时间:",$.getTimeByNormal(initTime) ); @@ -23,3 +31,12 @@ function main(){ Sleep(2000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/15098 + +> 更新时间 + +2017-01-04 12:00:55 diff --git "a/\350\216\267\345\217\226OK\346\234\237\350\264\247\345\256\236\346\227\266\351\231\220\344\273\267.js" "b/\350\216\267\345\217\226OK\346\234\237\350\264\247\345\256\236\346\227\266\351\231\220\344\273\267.md" similarity index 82% rename from "\350\216\267\345\217\226OK\346\234\237\350\264\247\345\256\236\346\227\266\351\231\220\344\273\267.js" rename to "\350\216\267\345\217\226OK\346\234\237\350\264\247\345\256\236\346\227\266\351\231\220\344\273\267.md" index 98e9f5b0..81d8fabb 100644 --- "a/\350\216\267\345\217\226OK\346\234\237\350\264\247\345\256\236\346\227\266\351\231\220\344\273\267.js" +++ "b/\350\216\267\345\217\226OK\346\234\237\350\264\247\345\256\236\346\227\266\351\231\220\344\273\267.md" @@ -1,14 +1,22 @@ -/* -策略出处: https://www.fmz.com/strategy/17028 -策略名称: 获取OK期货实时限价 -策略作者: 数·狂 -策略描述: + +> 策略名称 + +获取OK期货实时限价 + +> 策略作者 + +数·狂 + +> 策略描述 获取OK期货实时限价,仅实盘有效。 代码仅供学习,作者不保证程序正确性,据此交易后果自负。 -*/ + +> 源码 (javascript) + +``` javascript $.GetLimit = function(currStr, contract) { var url = "https://www.okcoin.com/api/v1/future_price_limit.do?symbol=" + currStr + "_usd&contract_type=" + contract; var httpResp = HttpQuery(url); @@ -31,3 +39,12 @@ function main() { Log(limit.high, limit.low); // 最高买入、最低卖出限价 } +``` + +> 策略出处 + +https://www.fmz.com/strategy/17028 + +> 更新时间 + +2016-06-19 11:15:05 diff --git "a/\350\216\267\345\217\226\345\221\250K\347\272\277.js" "b/\350\216\267\345\217\226\345\221\250K\347\272\277.md" similarity index 83% rename from "\350\216\267\345\217\226\345\221\250K\347\272\277.js" rename to "\350\216\267\345\217\226\345\221\250K\347\272\277.md" index 9ae91b16..d808087c 100644 --- "a/\350\216\267\345\217\226\345\221\250K\347\272\277.js" +++ "b/\350\216\267\345\217\226\345\221\250K\347\272\277.md" @@ -1,20 +1,31 @@ -/* -策略出处: https://www.fmz.com/strategy/20226 -策略名称: 获取周K线 -策略作者: 数·狂 -策略描述: + +> 策略名称 + +获取周K线 + +> 策略作者 + +数·狂 + +> 策略描述 把日K线组合为周K线,默认一周开始于周日(可调)。 使用方法: $.GetRecordsWeek(exchange) +> 策略参数 + + -参数 默认值 描述 ----------- ----- --------------------------- -weekStarts 0 一周开始于: 周日|周一|周二|周三|周四|周五|周六 -*/ +|参数|默认值|描述| +|----|----|----| +|weekStarts|0|一周开始于: 周日|周一|周二|周三|周四|周五|周六| + +> 源码 (javascript) + +``` javascript $.GetRecordsWeek = function(exchange) { var rec1 = exchange.GetRecords(PERIOD_D1); if (!rec1) return null; @@ -66,3 +77,12 @@ function main() { var rec = $.GetRecordsWeek(exchange); Log(new Date(rec[rec.length-1].Time).toString()); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/20226 + +> 更新时间 + +2016-08-17 18:22:52 diff --git "a/\350\216\267\345\217\226\345\222\214\350\256\257\346\234\237\350\264\247\346\225\260\346\215\256\357\274\210Python\347\211\210\346\234\254\357\274\211.py" "b/\350\216\267\345\217\226\345\222\214\350\256\257\346\234\237\350\264\247\346\225\260\346\215\256\357\274\210Python\347\211\210\346\234\254\357\274\211.md" similarity index 91% rename from "\350\216\267\345\217\226\345\222\214\350\256\257\346\234\237\350\264\247\346\225\260\346\215\256\357\274\210Python\347\211\210\346\234\254\357\274\211.py" rename to "\350\216\267\345\217\226\345\222\214\350\256\257\346\234\237\350\264\247\346\225\260\346\215\256\357\274\210Python\347\211\210\346\234\254\357\274\211.md" index 135c7303..96767ebe 100644 --- "a/\350\216\267\345\217\226\345\222\214\350\256\257\346\234\237\350\264\247\346\225\260\346\215\256\357\274\210Python\347\211\210\346\234\254\357\274\211.py" +++ "b/\350\216\267\345\217\226\345\222\214\350\256\257\346\234\237\350\264\247\346\225\260\346\215\256\357\274\210Python\347\211\210\346\234\254\357\274\211.md" @@ -1,14 +1,22 @@ -''' -策略出处: https://www.fmz.com/strategy/26017 -策略名称: 获取和讯期货数据(Python版本) -策略作者: edwardgyw -策略描述: + +> 策略名称 + +获取和讯期货数据(Python版本) + +> 策略作者 + +edwardgyw + +> 策略描述 数狂很早之前写了个js版本的第三方数据获取,我照着他的改写了个python版本的,可以下在云服务器上引入自己的包,这样研究时候也可以用。 update 12.01 和讯接口有变化多了60分钟和周线的信息,原版选择1440会获取60分钟的k线,这里fix了 -''' + +> 源码 (python) + +``` python #coding: utf-8 import urllib2 as url import json @@ -82,3 +90,12 @@ def hxRecords(instrument,timeFrame=1,size=1,includeLastBar=True,to_df=True): def main(): Log(exchange.GetAccount()) +``` + +> 策略出处 + +https://www.fmz.com/strategy/26017 + +> 更新时间 + +2016-12-01 00:28:00 diff --git "a/\350\236\215\350\265\204\350\236\215\345\270\201\347\273\237\350\256\241.js" "b/\350\236\215\350\265\204\350\236\215\345\270\201\347\273\237\350\256\241.md" similarity index 88% rename from "\350\236\215\350\265\204\350\236\215\345\270\201\347\273\237\350\256\241.js" rename to "\350\236\215\350\265\204\350\236\215\345\270\201\347\273\237\350\256\241.md" index 5e0d267c..a1e2c16b 100644 --- "a/\350\236\215\350\265\204\350\236\215\345\270\201\347\273\237\350\256\241.js" +++ "b/\350\236\215\350\265\204\350\236\215\345\270\201\347\273\237\350\256\241.md" @@ -1,14 +1,22 @@ -/* -策略出处: https://www.fmz.com/strategy/8954 -策略名称: 融资融币统计 -策略作者: 数·狂 -策略描述: + +> 策略名称 + +融资融币统计 + +> 策略作者 + +数·狂 + +> 策略描述 使用交易所api功能显示当前交易所的融资融币情况(未还部分,含手续费)。目前只支持OKCoin和火币,欢迎继续完善。 需要最新版托管者。 -*/ + +> 源码 (javascript) + +``` javascript function getLoanInfo(exchange, type) { var loanInfo; var dueAmount; @@ -46,3 +54,12 @@ function main() { "未归还LTC:", getLoanInfo(exchanges[i], "ltc") ); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/8954 + +> 更新时间 + +2016-01-13 19:03:22 diff --git "a/\350\256\241\345\210\222\345\247\224\346\211\230\344\271\260\345\205\245.js" "b/\350\256\241\345\210\222\345\247\224\346\211\230\344\271\260\345\205\245.md" similarity index 88% rename from "\350\256\241\345\210\222\345\247\224\346\211\230\344\271\260\345\205\245.js" rename to "\350\256\241\345\210\222\345\247\224\346\211\230\344\271\260\345\205\245.md" index b930ccbf..78c0cf56 100644 --- "a/\350\256\241\345\210\222\345\247\224\346\211\230\344\271\260\345\205\245.js" +++ "b/\350\256\241\345\210\222\345\247\224\346\211\230\344\271\260\345\205\245.md" @@ -1,24 +1,35 @@ -/* -策略出处: https://www.fmz.com/strategy/638 -策略名称: 计划委托买入 -策略作者: Zero -策略描述: + +> 策略名称 + +计划委托买入 + +> 策略作者 + +Zero + +> 策略描述 计划委托买入, 在价格涨超或者跌破指定的价格后进行买入操作, 如果使用市价单,只写购买金额就可以了,如果限价单,需要指定限价单的价格和个数 +> 策略参数 + + -参数 默认值 描述 ---------------- -------- ------------- -OpType 0 下单类型: 市价单|限价单 -TriggerPrice 2600 触发价格 -MarketUsedMoney 10000 市价单 - 购买金额 -BuyPrice 2610 限价单 - 买入价格 -BuyAmount 3 限价单 - 买入数量 -LoopInterval 200 检测间隔(豪秒) -MinStock 0.01 最小交易币数 -*/ +|参数|默认值|描述| +|----|----|----| +|OpType|0|下单类型: 市价单|限价单| +|TriggerPrice|2600|触发价格| +|MarketUsedMoney|10000|市价单 - 购买金额| +|BuyPrice|2610|限价单 - 买入价格| +|BuyAmount|3|限价单 - 买入数量| +|LoopInterval|200|检测间隔(豪秒)| +|MinStock|0.01|最小交易币数| +> 源码 (javascript) + +``` javascript + var InitPrice = 0; var Interval = 300; var UseMarketOrder = (OpType == 0); @@ -178,3 +189,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/638 + +> 更新时间 + +2018-06-05 16:31:29 diff --git "a/\350\256\241\345\210\222\345\247\224\346\211\230\345\215\226\345\207\272.js" "b/\350\256\241\345\210\222\345\247\224\346\211\230\345\215\226\345\207\272.md" similarity index 89% rename from "\350\256\241\345\210\222\345\247\224\346\211\230\345\215\226\345\207\272.js" rename to "\350\256\241\345\210\222\345\247\224\346\211\230\345\215\226\345\207\272.md" index b0e6b9a3..c2fe3a11 100644 --- "a/\350\256\241\345\210\222\345\247\224\346\211\230\345\215\226\345\207\272.js" +++ "b/\350\256\241\345\210\222\345\247\224\346\211\230\345\215\226\345\207\272.md" @@ -1,23 +1,34 @@ -/* -策略出处: https://www.fmz.com/strategy/747 -策略名称: 计划委托卖出 -策略作者: Zero -策略描述: + +> 策略名称 + +计划委托卖出 + +> 策略作者 + +Zero + +> 策略描述 计划委托卖出, 在价格涨超或者跌破指定的价格后进行卖出操作, 如果使用市价单,只需要填写卖出数量,如果限价单,需要指定卖出价格 +> 策略参数 + + -参数 默认值 描述 ------------- ----- ------------- -OpType 0 下单类型: 市价单|限价单 -TriggerPrice 2600 触发价格 -SellPrice 2610 限价单 - 卖出价格 -SellAmount 3 卖出数量 -LoopInterval true 检测间隔(秒) -MinStock 0.01 最小交易币数 -*/ +|参数|默认值|描述| +|----|----|----| +|OpType|0|下单类型: 市价单|限价单| +|TriggerPrice|2600|触发价格| +|SellPrice|2610|限价单 - 卖出价格| +|SellAmount|3|卖出数量| +|LoopInterval|true|检测间隔(秒)| +|MinStock|0.01|最小交易币数| +> 源码 (javascript) + +``` javascript + var InitPrice = 0; var Interval = 300; var UseMarketOrder = (OpType == 0); @@ -175,3 +186,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/747 + +> 更新时间 + +2018-06-05 16:29:07 diff --git "a/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.js" "b/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.md" similarity index 90% rename from "\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.js" rename to "\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.md" index f55a9b65..5eeea7b5 100644 --- "a/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.js" +++ "b/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/8916 -策略名称: 记录净资产变动情况2.0 -策略作者: 中本姜(青铜机器人) -策略描述: + +> 策略名称 + +记录净资产变动情况2.0 + +> 策略作者 + +中本姜(青铜机器人) + +> 策略描述 说明 - 本策略由https://www.botvs.com/strategy/5349 演变而来,主要是计算在含有借币的情况下,账户策略的净收入变动情况 @@ -23,21 +28,27 @@ -TODO 直接调用借款信息,计算净资产变化情况 +> 策略参数 + + -参数 默认值 描述 ------------------- ----- --------- -time true 通知周期(小时) -shuaxintime 30 刷新周期(分钟) -profit_base false 初始净资产变动值 -borrow_bi false 借币数量 -interest_bi_base false 借币现在所欠利息 -interest_bi 0.001 借币日利息 -borrow_qian false 借钱数目 -interest_qian 0.001 借钱日利息 -interest_qian_base false 借钱现在所欠利息 -log_reset false log reset -*/ +|参数|默认值|描述| +|----|----|----| +|time|true|通知周期(小时)| +|shuaxintime|30|刷新周期(分钟)| +|profit_base|false|初始净资产变动值| +|borrow_bi|false|借币数量| +|interest_bi_base|false|借币现在所欠利息| +|interest_bi|0.001|借币日利息| +|borrow_qian|false|借钱数目| +|interest_qian|0.001|借钱日利息| +|interest_qian_base|false|借钱现在所欠利息| +|log_reset|false|log reset| + +> 源码 (javascript) + +``` javascript function EnsureCall(e, method) { var r; while (!(r = e[method].apply(this, Array.prototype.slice.call(arguments).slice(2)))) { @@ -168,3 +179,12 @@ function main() { LogStatus(status_log); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/8916 + +> 更新时间 + +2016-06-14 09:04:20 diff --git "a/\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211.md" "b/\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211.md" new file mode 100644 index 00000000..c0350c2a --- /dev/null +++ "b/\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211.md" @@ -0,0 +1,51 @@ + +> 策略名称 + +设定价格微信推送(教学) + +> 策略作者 + +botvsing + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Currency|BTC_USDT|监控的交易对| +|UpPrice|6600|价格大于| +|LowPrice|6500|价格小于| +|Interval|10|轮询时间| + + +> 源码 (javascript) + +``` javascript +//实际使用时行情接口用HttpQuery访问,运行在模拟盘上就可以免费了 +function main() { + exchange.IO("currency", Currency) + var lastPushTime = 0 + while(true){ + var ticker = _C(exchange.GetTicker) + if(ticker.Last > UpPrice || ticker.Last < LowPrice){ + //五分钟内只推一次 + if(Date.now() - lastPushTime > 300*1000){ + lastPushTime = Date.now() + Log(Currency, '当前价格: ', ticker.Last, '@') + } + } + Sleep(Interval*1000) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/125482 + +> 更新时间 + +2018-11-09 16:11:27 diff --git "a/\350\264\246\346\210\267\344\275\231\351\242\235\345\217\230\345\212\250\351\202\256\347\256\261\346\217\220\351\206\222, \346\224\257\346\214\201\346\267\273\345\212\240\345\244\232\344\270\252\344\272\244\346\230\223\346\211\200.js" "b/\350\264\246\346\210\267\344\275\231\351\242\235\345\217\230\345\212\250\351\202\256\347\256\261\346\217\220\351\206\222, \346\224\257\346\214\201\346\267\273\345\212\240\345\244\232\344\270\252\344\272\244\346\230\223\346\211\200.md" similarity index 77% rename from "\350\264\246\346\210\267\344\275\231\351\242\235\345\217\230\345\212\250\351\202\256\347\256\261\346\217\220\351\206\222, \346\224\257\346\214\201\346\267\273\345\212\240\345\244\232\344\270\252\344\272\244\346\230\223\346\211\200.js" rename to "\350\264\246\346\210\267\344\275\231\351\242\235\345\217\230\345\212\250\351\202\256\347\256\261\346\217\220\351\206\222, \346\224\257\346\214\201\346\267\273\345\212\240\345\244\232\344\270\252\344\272\244\346\230\223\346\211\200.md" index 66741271..57de0659 100644 --- "a/\350\264\246\346\210\267\344\275\231\351\242\235\345\217\230\345\212\250\351\202\256\347\256\261\346\217\220\351\206\222, \346\224\257\346\214\201\346\267\273\345\212\240\345\244\232\344\270\252\344\272\244\346\230\223\346\211\200.js" +++ "b/\350\264\246\346\210\267\344\275\231\351\242\235\345\217\230\345\212\250\351\202\256\347\256\261\346\217\220\351\206\222, \346\224\257\346\214\201\346\267\273\345\212\240\345\244\232\344\270\252\344\272\244\346\230\223\346\211\200.md" @@ -1,29 +1,40 @@ -/* -策略出处: https://www.fmz.com/strategy/2006 -策略名称: 账户余额变动邮箱提醒, 支持添加多个交易所 -策略作者: Zero -策略描述: + +> 策略名称 + +账户余额变动邮箱提醒, 支持添加多个交易所 + +> 策略作者 + +Zero + +> 策略描述 检测账户余额的币和钱的变动,并发送到指定邮箱上. 这个不支持回测的 之前飞信短信的, 因为用的人多了,账号被冻结的,不能用短信接口了, 换成邮箱了. +> 策略参数 + + -参数 默认值 描述 ------------- ------------ --------------------- -LoopInterval 10 检测间隔(秒) -AlertMode 0 提醒方式: 变动提醒|条件报警|最小值报警 -MaxDiffCNY false 钱最小变动数 -MaxDiffCoin false 币最小变动数 -MinCoin false 币最小值 -MinCNY false 钱最小值 -SMTPServer smtp.163.com SMTP服务器 -SMTPUser test@163.com 发信邮箱(SMTP用户名) -SMTPPass *** 邮箱密码(SMTP密码) -SendMode 0 收信邮箱: 自己|其它 -DstMail test@163.com 收件人邮箱 -*/ +|参数|默认值|描述| +|----|----|----| +|LoopInterval|10|检测间隔(秒)| +|AlertMode|0|提醒方式: 变动提醒|条件报警|最小值报警| +|MaxDiffCNY|false|钱最小变动数| +|MaxDiffCoin|false|币最小变动数| +|MinCoin|false|币最小值| +|MinCNY|false|钱最小值| +|SMTPServer|smtp.163.com|SMTP服务器| +|SMTPUser|test@163.com|发信邮箱(SMTP用户名)| +|SMTPPass|***|邮箱密码(SMTP密码)| +|SendMode|0|收信邮箱: 自己|其它| +|DstMail|test@163.com|收件人邮箱| +> 源码 (javascript) + +``` javascript + function Notify(msg) { var ret = Mail(SMTPServer, SMTPUser, SMTPPass, SendMode == 0 ? SMTPUser : DstMail , msg, "余额变动 " + msg); if (ret) { @@ -93,3 +104,12 @@ function main() { } } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/2006 + +> 更新时间 + +2014-12-24 23:22:24 diff --git "a/\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.js" "b/\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.md" similarity index 89% rename from "\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.js" rename to "\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.md" index 10f041cc..53a815de 100644 --- "a/\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.js" +++ "b/\350\266\213\345\212\277\350\267\237\350\270\252\351\234\207\350\215\241\347\255\226\347\225\245.md" @@ -1,30 +1,41 @@ -/* -策略出处: https://www.fmz.com/strategy/179 -策略名称: 趋势跟踪震荡策略 -策略作者: Zero -策略描述: + +> 策略名称 + +趋势跟踪震荡策略 + +> 策略作者 + +Zero + +> 策略描述 趋势跟踪震荡策略, 跟踪止盈(盈利后如果出现指定幅度的缩损就止盈) +> 策略参数 + + -参数 默认值 描述 -------------------- ----- ---------------- -Interval 2000 出错重试间隔(毫秒) -SlidePrice 0.3 滑动价(元) -StopLoss 0.8 止损点 -RatioUp 0.8 上涨卖出参考点数(做空) -RatioDown 0.8 下跌买入参考点数(做多) -UpWeightingVal 50 上涨建仓做多点数(相对最高跌幅) -DownWeightingVal 50 下跌建仓做空点数(相对最高涨幅) -StopProfitThreshold 0.9 止盈系数(0-1) -EMA_Slow 30 EMA慢线周期 -EMA_Fast 7 EMA快线周期 -EnableGoingShort true 允许做空 -MinStock 0.001 最小交易量 -LoopInterval 60 轮询间隔(秒) -*/ +|参数|默认值|描述| +|----|----|----| +|Interval|2000|出错重试间隔(毫秒)| +|SlidePrice|0.3|滑动价(元)| +|StopLoss|0.8|止损点| +|RatioUp|0.8|上涨卖出参考点数(做空)| +|RatioDown|0.8|下跌买入参考点数(做多)| +|UpWeightingVal|50|上涨建仓做多点数(相对最高跌幅)| +|DownWeightingVal|50|下跌建仓做空点数(相对最高涨幅)| +|StopProfitThreshold|0.9|止盈系数(0-1)| +|EMA_Slow|30|EMA慢线周期| +|EMA_Fast|7|EMA快线周期| +|EnableGoingShort|true|允许做空| +|MinStock|0.001|最小交易量| +|LoopInterval|60|轮询间隔(秒)| +> 源码 (javascript) + +``` javascript + function CancelPendingOrders() { while (true) { var orders = null; @@ -215,3 +226,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/179 + +> 更新时间 + +2018-03-27 16:16:09 diff --git "a/\350\267\250\345\271\263\345\217\260\345\245\227\345\210\251\346\226\260\346\211\213\346\265\213\350\257\225.md" "b/\350\267\250\345\271\263\345\217\260\345\245\227\345\210\251\346\226\260\346\211\213\346\265\213\350\257\225.md" new file mode 100644 index 00000000..21ea7e84 --- /dev/null +++ "b/\350\267\250\345\271\263\345\217\260\345\245\227\345\210\251\346\226\260\346\211\213\346\265\213\350\257\225.md" @@ -0,0 +1,79 @@ + +> 策略名称 + +跨平台套利新手测试 + +> 策略作者 + +cnxzcxy + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|minRate|1.02|价格差比例| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2018-01-01 00:00:00 +end: 2018-08-01 14:00:00 +period: 1h +exchanges: [{"eid":"Bitfinex","currency":"ETH","balance":5000,"stocks":10},{"eid":"OKCoin_EN","currency":"ETH","balance":5000,"stocks":10}] +*/ +var buyExchange; +var sellExchange; + +function calc(sellExchange, buyExchange){ + var date = _D(); + sellDepth = sellExchange.GetDepth(); + sellAccount = sellExchange.GetAccount(); + sellPrice = sellDepth.Bids[1].Price; + sellAmount = sellDepth.Bids[1].Amount; + + buyDepth = buyExchange.GetDepth(); + buyAccount = buyExchange.GetAccount(); + buyPrice = buyDepth.Asks[1].Price; + buyAmount = buyDepth.Asks[1].Amount; + + amount = (sellAmount > buyAmount) ? buyAmount : sellAmount; + amount = (amount > sellAccount.Stocks) ? sellAccount.Stocks : amount; + amount = (amount > buyAccount.Balance / buyPrice) ? buyAccount.Balance / buyPrice : amount; + priceRate = sellPrice / buyPrice; + if(amount > 0){ + if(priceRate >= minRate){ + buyExchange.Buy(-1, amount); + sellExchange.Sell(-1, amount); + Log(date); + Log("卖出:", sellExchange.GetName(), "卖出价格:", sellPrice, "买入:", buyExchange.GetName(), " 买入价格:", buyPrice, " 比例:", priceRate, " 总量:", amount); + Log('统计资产...'); + Log('交易所:', exchanges[0].GetName(), ' 账户:', exchanges[0].GetAccount()); + Log('交易所:', exchanges[1].GetName(), ' 账户:', exchanges[1].GetAccount()); + } + } + +} + +function main(){ + while(true){ + calc(exchanges[0], exchanges[1]); + calc(exchanges[1], exchanges[0]); + } + +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/115574 + +> 更新时间 + +2018-09-12 15:50:04 diff --git "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237.js" "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237.md" similarity index 95% rename from "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237.js" rename to "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237.md" index 4d67f130..013e5b30 100644 --- "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237.js" +++ "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237.md" @@ -1,20 +1,31 @@ -/* -策略出处: https://www.fmz.com/strategy/35986 -策略名称: 转换任意K线周期 -策略作者: 小小梦 -策略描述: + +> 策略名称 + +转换任意K线周期 + +> 策略作者 + +小小梦 + +> 策略描述 示例策略 - 转换基础K线为任意K线周期 - 暂时不支持 秒级别 测试版本,如有BUG ,问题 欢迎留言。 +> 策略参数 + + -参数 默认值 描述 ----------------- ------------ ------- -UI_NewCycleForMS 1000*60*60*2 合成周期毫秒数 -*/ +|参数|默认值|描述| +|----|----|----| +|UI_NewCycleForMS|1000*60*60*2|合成周期毫秒数| + +> 源码 (javascript) + +``` javascript // K线周期合成 扩展为 根据基础K线 合成 为任意周期。 var cloneObj = function(obj) { // 深拷贝 对象函数 var str, newobj = obj.constructor === Array ? [] : {}; @@ -220,3 +231,12 @@ function main() { // 测试 Sleep(1000); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/35986 + +> 更新时间 + +2017-03-05 11:47:06 diff --git "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180627).js" "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180627).md" similarity index 97% rename from "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180627).js" rename to "\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180627).md" index 7d567ebe..57cf719b 100644 --- "a/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180627).js" +++ "b/\350\275\254\346\215\242\344\273\273\346\204\217K\347\272\277\345\221\250\346\234\237\347\256\241\347\220\206\346\250\241\346\235\277(\346\234\200\350\277\221\346\233\264\346\226\26020180627).md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/41163 -策略名称: 转换任意K线周期管理模板(最近更新20180627) -策略作者: 中本姜(青铜机器人) -策略描述: + +> 策略名称 + +转换任意K线周期管理模板(最近更新20180627) + +> 策略作者 + +中本姜(青铜机器人) + +> 策略描述 更新于20171114 a. 解决Open找不到问题,是record数组访问越界造成的,访问越界是之前的K线有问题导致的。 @@ -45,12 +50,18 @@ $.GetRecordsTable(n) 得到新K线最新的N个条目, 默认输出所有条目, 输出为table类型,便于LogStatus输出 $.Get***** 获得一些基本信息 +> 策略参数 + -参数 默认值 描述 ----------------- ------------ ------- -UI_NewCycleForMS 1000*60*60*2 合成周期毫秒数 -*/ +|参数|默认值|描述| +|----|----|----| +|UI_NewCycleForMS|1000*60*60*2|合成周期毫秒数| + + +> 源码 (javascript) + +``` javascript /*backtest period: 60 */ @@ -411,3 +422,12 @@ function main() { } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/41163 + +> 更新时间 + +2018-06-28 10:07:56 diff --git "a/\350\277\275\346\266\250\346\235\200\350\267\214.py" "b/\350\277\275\346\266\250\346\235\200\350\267\214.md" similarity index 77% rename from "\350\277\275\346\266\250\346\235\200\350\267\214.py" rename to "\350\277\275\346\266\250\346\235\200\350\267\214.md" index ef036928..f7eef442 100644 --- "a/\350\277\275\346\266\250\346\235\200\350\267\214.py" +++ "b/\350\277\275\346\266\250\346\235\200\350\267\214.md" @@ -1,18 +1,27 @@ -''' -策略出处: https://www.fmz.com/strategy/96634 -策略名称: 追涨杀跌 -策略作者: ChildeTang -策略描述: +> 策略名称 +追涨杀跌 +> 策略作者 -参数 默认值 描述 ------- ----- ---- -PERIOD 60 周期 -LENGTH 1440 长度 -''' +ChildeTang + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|PERIOD|60|周期| +|LENGTH|1440|长度| + + +> 源码 (python) + +``` python list=[] def doTicker(): @@ -47,3 +56,12 @@ def main(): doTicker() #执行策略 Sleep(PERIOD * 1000) #休息一段时间 +``` + +> 策略出处 + +https://www.fmz.com/strategy/96634 + +> 更新时间 + +2018-06-06 16:32:06 diff --git "a/\351\227\252\345\264\251\346\234\272\345\231\250\344\272\272 (\346\225\231\345\255\246).md" "b/\351\227\252\345\264\251\346\234\272\345\231\250\344\272\272 (\346\225\231\345\255\246).md" new file mode 100644 index 00000000..6584d9e7 --- /dev/null +++ "b/\351\227\252\345\264\251\346\234\272\345\231\250\344\272\272 (\346\225\231\345\255\246).md" @@ -0,0 +1,98 @@ + +> 策略名称 + +闪崩机器人 (教学) + +> 策略作者 + +小小梦 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Spread|50|挂单价格间隔| +|OrderSize|0.1|每单大小| +|SpreadTimes|true|订单大小递增倍数| +|TotalBuy|3|总买单量| +|TotalSell|3|总卖单量| +|Interval|300|休眠时间(s)| +|fee|0.25|手续费| + + +> 源码 (javascript) + +``` javascript +function CancelPendingOrders(orders) { // 取消所有订单 + for (var j = 0; j < orders.length; j++) { // 根据参数传来的 未完成订单数组 , 逐个取消订单。 + exchange.CancelOrder(orders[j].Id, orders[j]); + Sleep(300); // 间隔 300 毫秒 + } +} +function LogOrders(orders){ // 组织用于显示的数据,显示在 机器人 页面的状态栏上。 + var buyString = ''; // 用于显示的买单数据字符串 + var sellString = ''; // 用于显示的卖单数据字符串 + orders.sort(function(x, y){return x.Price - y.Price;}); // 排序 , orders 根据订单的 Price 属性, 从大到小 + for (var j = 0; j < orders.length; j++) { // 遍历 orders , 注意已经排过序 + if (orders[j].Type == ORDER_TYPE_SELL){ // 如果 订单是 卖单,则执行{} 内代码。 + sellString += String(orders[j].Price) + ' ' + String(orders[j].Amount) + '|'; // 储存在 字符串 sellString , 用 | 间隔 + }else{ + buyString += String(orders[j].Price) + ' ' + String(orders[j].Amount) + '|'; // 储存在 字符串 buyString , 用 | 间隔 + } + } + LogStatus('买单:' + buyString + '\n' + '卖单:' + sellString); // 在状态栏 输出这些 订单 信息。 +} +function main() { // 主函数 + while(true){ // 主循环 + var orders = _C(exchange.GetOrders); // 获取所有 未完成 挂单信息,orders 为一个 数组。 + CancelPendingOrders(orders); // 取消所有未完成挂单 + var ticker = _C(exchange.GetTicker); // 获取最新行情信息 + var account = _C(exchange.GetAccount); // 获取 当前账户信息 + var midPrice = (ticker.Buy + ticker.Sell) / 2; // 计算 盘口空隙中间的位置的价格。 + var buyAmount = 0; // 声明 buyAmount ,用于累计计划买入数量, 初始化 0 + var sellAmount = 0; // 声明 sellAmount , 用于累计计划卖出数量, 初始化 0 + var amount = OrderSize; // OrderSize 每单下单量大小, 赋值给 amount + var buyPrice = midPrice - Spread; // 在盘口中间位置 上下 一定 挂单价格间隔, 挂单,设置挂买单价 buyPrice + var sellPrice = midPrice + Spread; // .... + while((buyAmount < TotalBuy) && (account.Balance > amount*buyPrice) && buyPrice > 0){ // 当 计划买入数量 小于 总买单量, 并且 账户可用计价币(资金)大于 本次计划下单使用的资金,并且 下单价格大于0(防止 midPrice - Spread 小于0) + if(exchange.Buy(buyPrice, amount)){ // 下单,如果返回 null 执行 else 内代码块, 如果返回id 执行 if 代码块 + buyAmount += amount; // 累计买单挂单量 + account.Balance -= amount*buyPrice; // 更新账户 计价币数量 + buyPrice -= Spread; // 更新挂单价格 + amount = amount * SpreadTimes; // 更新订单下单量,根据参数 SpreadTimes 设置进行递增。 + + }else{ // 下单失败,更新账户信息,用于 当前while 循环条件判断 + account = _C(exchange.GetAccount); + } + Sleep(500); // 用于控制 挂单频率 + } + amount = OrderSize; // 重置 amount 变量为 OrderSize + while((sellAmount < TotalSell) && (account.Stocks*(1-fee/100) > amount)){ // 当 计划卖出的量 小于 总卖单量, 并且 账户可用 币数 扣除 交易手续费后 大于每单数量,执行while 循环 + if(exchange.Sell(sellPrice, amount)){ // 下卖单, 返回订单ID ,更新相关 变量。 + sellAmount += amount; // 累计 挂出的卖单的量 + account.Stocks -= amount; // 更新 可用币数 + sellPrice += Spread; // 更新下单价格 位置 + amount = amount * SpreadTimes; // 更新订单下单量,根据参数 SpreadTimes 设置进行递增。 + }else{ + account = _C(exchange.GetAccount); // 如果下单失败 更新账户信息 + } + Sleep(500); + } + orders = _C(exchange.GetOrders); // 获取 挂单信息 + LogOrders(orders); // 输出挂单信息 在状态栏 + Sleep(Interval*1000); // 轮询间隔,控制 策略运转频率 + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/118939 + +> 更新时间 + +2018-10-09 13:59:53 diff --git "a/\351\230\266\346\242\257\344\270\213\345\215\225 - \345\217\257\350\256\276\347\275\256\350\247\246\345\217\221\344\273\267\346\240\274.js" "b/\351\230\266\346\242\257\344\270\213\345\215\225 - \345\217\257\350\256\276\347\275\256\350\247\246\345\217\221\344\273\267\346\240\274.md" similarity index 80% rename from "\351\230\266\346\242\257\344\270\213\345\215\225 - \345\217\257\350\256\276\347\275\256\350\247\246\345\217\221\344\273\267\346\240\274.js" rename to "\351\230\266\346\242\257\344\270\213\345\215\225 - \345\217\257\350\256\276\347\275\256\350\247\246\345\217\221\344\273\267\346\240\274.md" index 76c72600..d681015c 100644 --- "a/\351\230\266\346\242\257\344\270\213\345\215\225 - \345\217\257\350\256\276\347\275\256\350\247\246\345\217\221\344\273\267\346\240\274.js" +++ "b/\351\230\266\346\242\257\344\270\213\345\215\225 - \345\217\257\350\256\276\347\275\256\350\247\246\345\217\221\344\273\267\346\240\274.md" @@ -1,23 +1,34 @@ -/* -策略出处: https://www.fmz.com/strategy/639 -策略名称: 阶梯下单 - 可设置触发价格 -策略作者: Zero -策略描述: + +> 策略名称 + +阶梯下单 - 可设置触发价格 + +> 策略作者 + +Zero + +> 策略描述 阶梯下单, 可买可卖, 程序依次按下单间隔下够指定数目的买单或者卖单, 如果是买单,刚第一个单为价格最高的单,后面的单依次价格递减,卖单第一个为最便宜的卖单,后面的价格依次增加 +> 策略参数 + + -参数 默认值 描述 -------------- ----- ---------- -OpType 0 下买单: 买单|卖单 -StartPrice 20 下单初始价 -PriceDiff 0.2 下单间隔 -OrderNum 10 下单次数 -Amount 0.8 每个订单币的数量 -EnableTrigger false 使用触发条件 -TriggerPrice 18 触发价 -*/ +|参数|默认值|描述| +|----|----|----| +|OpType|0|下买单: 买单|卖单| +|StartPrice|20|下单初始价| +|PriceDiff|0.2|下单间隔| +|OrderNum|10|下单次数| +|Amount|0.8|每个订单币的数量| +|EnableTrigger|false|使用触发条件| +|TriggerPrice|18|触发价| + +> 源码 (javascript) + +``` javascript function adjustFloat(v) { return Math.floor(parseFloat(v.toFixed(10))*1000)/1000; } @@ -80,3 +91,12 @@ function main() { } Log("全部委托完成"); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/639 + +> 更新时间 + +2015-04-22 16:18:14 diff --git "a/\351\235\236\345\270\270\347\256\200\345\215\225\347\232\204\347\255\226\347\225\245\357\274\214\344\275\206\346\230\257\345\276\210\346\234\211\346\225\210.js" "b/\351\235\236\345\270\270\347\256\200\345\215\225\347\232\204\347\255\226\347\225\245\357\274\214\344\275\206\346\230\257\345\276\210\346\234\211\346\225\210.js" deleted file mode 100644 index 7f6c96a0..00000000 --- "a/\351\235\236\345\270\270\347\256\200\345\215\225\347\232\204\347\255\226\347\225\245\357\274\214\344\275\206\346\230\257\345\276\210\346\234\211\346\225\210.js" +++ /dev/null @@ -1,70 +0,0 @@ -/* -策略出处: https://www.fmz.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); - } -} diff --git "a/\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220.js" "b/\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220.js" deleted file mode 100644 index bd7e6cff..00000000 --- "a/\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220.js" +++ /dev/null @@ -1,78 +0,0 @@ -/* -策略出处: https://www.fmz.com/strategy/59356 -策略名称: 顺大势逆小势策略之代码实现及可行性分析 -策略作者: 深蓝 -策略描述: - - - - -参数 默认值 描述 ------ ----- ----- -maLen 100 maLen -kd1 50 kd1 -kd2 15 kd2 -*/ - -//语法固定格式,调用main主函数 -function main() { - - //调用商品期货交易类库中的CTA框架 - $.CTA("RM000", function(st) { - - //获取K线数组 - var j = st.records; - - //指标运算参考的最大K线数量 - if (j.length < 100) { - return; - } - - //获取上根K线的收盘价 - var c = j[j.length - 2].Close; - - //获取KDJ指标数组 - var kds = TA.KDJ(j, kd1, kd2, kd2); - - //获取KDJ指标K的数组 - var ks = kds[0]; - - //获取KDJ指标D的数组 - var ds = kds[1]; - - //获取上根K线的K值 - var k = ks[ks.length - 2].toFixed(2); - - //获取上根K线的D值 - var d = ds[ds.length - 2].toFixed(2); - - //获取均线数组 - var mas = TA.MA(j, 100); - - //获取上根K线的MA值 - var ma = mas[mas.length - 2]; - - //获取当前的持仓数量,正数指多仓, 负数指空仓, 0则不持仓 - var mp = st.position.amount; - - //如果当前持有多单,并且上根K线的K值小于上根K线的D值,平多单 - if (mp > 0 && k < d) { - return -1; //如果当前有多单,指定返回值为-N,就是平N手多单。 - } - - //如果当前持有空单,并且上根K线的K值大于上根K线的D值,平空单 - if (mp < 0 && k > d) { - return 1; //如果当前有空单,指定返回值为N,就是平N手空单。 - } - - //如果当前无持仓,并且上根K线的收盘价大于上根K线的MA值,并且上根K线的K值大于上根K线的D值,开多单 - if (mp === 0 && c > ma && k > d) { - return 1; //如果当前无持仓,指定返回值为N,就是开N手多单。 - } - - //如果当前无持仓,并且上根K线的收盘价小于上根K线的MA值,并且上根K线的K值小于上根K线的D值,开空单 - if (mp === 0 && c < ma && k < d) { - return -1; //如果当前无持仓,指定返回值为-N,就是开N手空单。 - } - }); -} diff --git "a/02\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220 (Share 1513097042).js" "b/\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220.md" similarity index 86% rename from "02\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220 (Share 1513097042).js" rename to "\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220.md" index 8c705818..45a8d4fe 100644 --- "a/02\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220 (Share 1513097042).js" +++ "b/\351\241\272\345\244\247\345\212\277\351\200\206\345\260\217\345\212\277\347\255\226\347\225\245\344\271\213\344\273\243\347\240\201\345\256\236\347\216\260\345\217\212\345\217\257\350\241\214\346\200\247\345\210\206\346\236\220.md" @@ -1,19 +1,28 @@ -/* -策略出处: https://www.fmz.com/strategy/63223 -策略名称: 02顺大势逆小势策略之代码实现及可行性分析 (Share 1513097042) -策略作者: ellajella-0378 -策略描述: +> 策略名称 +顺大势逆小势策略之代码实现及可行性分析 +> 策略作者 -参数 默认值 描述 ------ ----- ----- -maLen 100 maLen -kd1 50 kd1 -kd2 15 kd2 -*/ +深蓝 + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|maLen|100|maLen| +|kd1|50|kd1| +|kd2|15|kd2| + + +> 源码 (javascript) + +``` javascript //语法固定格式,调用main主函数 function main() { @@ -76,3 +85,12 @@ function main() { } }); } +``` + +> 策略出处 + +https://www.fmz.com/strategy/59356 + +> 更新时间 + +2018-05-08 17:00:54 diff --git "a/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245.md" "b/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245.md" new file mode 100644 index 00000000..1d7530af --- /dev/null +++ "b/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245.md" @@ -0,0 +1,76 @@ + +> 策略名称 + +高低点与波动率ROC指标策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略名称:高低点与波动率ROC指标策略 +- 数据周期:15M等 +- 支持:商品期货 +- 官方网站:www.quant.la + +/upload/asset/1f5e3caa65a3871ae9c9d99f9c11bdf0.png +/upload/asset/ec4cbcbb036925739a04de90cadf1d8d.png + +- 主图: + N周期最高价,公式:HH^^HHV(H,N); + N周期最低价,公式:LL^^LLV(L,N); + +- 副图: + ARC指标, 公式:ARC:SMA(RC,M,1); + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N|200|高低点周期参数| +|SLOSS|true|止损百分比| +|M|50|ARC参数| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-03-03 00:00:00 +end: 2018-03-31 00:00:00 +period: 15m +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["ContractType","rb888",126961]] +*) + +HH^^HHV(H,N); +LL^^LLV(L,N); +MD:=(HH+LL)/2; + +UP:=H>=HH; +DOWN:=L<=LL; + +RC:=CLOSE/REF(CLOSE,M); +ARC:SMA(RC,M,1); + +BARPOS>N AND BKVOL=0 AND H>=HH AND ARC>1,BPK; +BARPOS>N AND SKVOL=0 AND L<=LL AND ARC<1,SPK; + +DOWN AND C>BKPRICE*(1+SLOSS*0.01),SP(BKVOL); +UP AND CSKPRICE*(1+SLOSS*0.01),BP(SKVOL); +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/128417 + +> 更新时间 + +2018-12-04 22:06:21 diff --git "a/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245.md" "b/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245.md" new file mode 100644 index 00000000..567fe508 --- /dev/null +++ "b/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245.md" @@ -0,0 +1,78 @@ + +> 策略名称 + +高低点突破成交量指数加权策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略名称:高低点突破成交量指数加权策略 +- 数据周期:多周期 +- 回测可以选择 OKEX期货 +- 合约:this_week 当周合约 +- 官方网站:www.quant.la + +/upload/asset/efa8dad9db6b13862283a69ee8255934.png + +- 主图: + 无 + +- 副图 + VJQ, 计算公式: VJQ:EMA(V*(C-REF(C,NC)),N);//定义成交量加权指数为VJQ + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|SLOSS|2|止损百分比| +|N|300|EMA指标参数| +|NC|50|多少个周期前的收盘价| +|MINAMOUNT|true|最少一次下单数量| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-04-01 00:00:00 +end: 2018-05-28 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}] +args: [["N",100],["MINAMOUNT",10],["TradeAmount",10,126961],["ContractType","this_week",126961]] +*) + +LOTS:=MAX(MINAMOUNT,INTPART(MONEYTOT/O * 0.8)); +VJQ:EMA(V*(C-REF(C,NC)),N);//定义成交量加权指数为VJQ +B:=VJQ>0;//定义多头势 +S:=VJQ<0;//定义空头势 +BUYPK:=BARPOS>N AND BKVOL=0 AND B AND H>=HHV(H,N); +SELLPK:=BARPOS>N AND SKVOL=0 AND S AND L<=LLV(L,N); +BUYP:=SKVOL>0 AND B; +SELLP:=BKVOL>0 AND S; + +//入场 +SELLPK,SPK(LOTS); +BUYPK,BPK(LOTS); + +//出场 +BUYP,BP(SKVOL); +SELLP,SP(BKVOL); + +//止损 +C>=SKPRICE*(1+SLOSS*0.01),BP(SKVOL); +C<=BKPRICE*(1-SLOSS*0.01),SP(BKVOL); +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/128125 + +> 更新时间 + +2018-12-05 10:57:07 diff --git "a/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245.md" new file mode 100644 index 00000000..c2c75e44 --- /dev/null +++ "b/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -0,0 +1,89 @@ + +> 策略名称 + +高胜率ORB交易策略 + +> 策略作者 + +littleDreamXX + +> 策略描述 + +- 策略名称:高胜率ORB交易策略 +- 数据周期:日K +- 支持:商品期货 +- 官方网站:www.quant.la + + /upload/asset/860ae7cefa35c714a7f3c028ad77e656.png + +- 主图: + 均线, 公式:MAC^^MA(CLOSE,LENGTH); + 最高价均线,公式:MA_HH^^MA(HHV(HIGH,LENGTH),LENGTH); + 最低价均线,公式:MA_LL^^MA(LLV(LOW,LENGTH),LENGTH); + + 上轨,公式:UPBAND^^O_TODAY+BAND; + 下轨,公式:DOWNBAND^^O_TODAY-BAND; + +- 副图: + 无 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N_DAY|10|N日周期| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-03-01 00:00:00 +end: 2018-09-30 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["ContractType","rb888",126961]] +*) + +NN:=BARSLAST(DATE<>REF(DATE,1))+1; +LENGTH_DAY:=HHV(NN,NN+62); +O_TODAY:=VALUEWHEN(NN=1,OPEN); +H_TODAY:=HHV(HIGH,NN); +L_TODAY:=LLV(LOW,NN); +H_YESTERDAY:=REF(H_TODAY,NN); +L_YESTERDAY:=REF(L_TODAY,NN); +C_YESTERDAY:=REF(C,NN); +LENGTH:=N_DAY*LENGTH_DAY; +DISTANCE:=MA(H_YESTERDAY-L_YESTERDAY,LENGTH); +ORB:=MIN(ABS(H_YESTERDAY-C_YESTERDAY),ABS(L_YESTERDAY-C_YESTERDAY)); +BAND:=MAX(ORB,DISTANCE*0.1); +UPBAND^^O_TODAY+BAND; +DOWNBAND^^O_TODAY-BAND; +MAC^^MA(CLOSE,LENGTH); +MA_HH^^MA(HHV(HIGH,LENGTH),LENGTH); +MA_LL^^MA(LLV(LOW,LENGTH),LENGTH); + +BUYPK:=CLOSE>UPBAND AND CLOSE>MAC AND CLOSE>MA_HH; +SELLPK:=CLOSEBKPRICE; +BUYY:=CLOSE>MAC AND CLOSELENGTH THEN +BEGIN + BKVOL=0 AND BUYPK,BPK; + SKVOL=0 AND SELLPK,SPK; +END +SELLY,SP(BKVOL); +BUYY,BP(SKVOL); + +``` + +> 策略出处 + +https://www.fmz.com/strategy/129084 + +> 更新时间 + +2018-12-06 17:33:27 diff --git "a/\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213 - Penny Jump.js" "b/\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213 - Penny Jump.md" similarity index 90% rename from "\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213 - Penny Jump.js" rename to "\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213 - Penny Jump.md" index 5120799b..2be76b32 100644 --- "a/\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213 - Penny Jump.js" +++ "b/\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213 - Penny Jump.md" @@ -1,8 +1,13 @@ -/* -策略出处: https://www.fmz.com/strategy/358 -策略名称: 高频交易策略之 - Penny Jump -策略作者: Zero -策略描述: + +> 策略名称 + +高频交易策略之 - Penny Jump + +> 策略作者 + +Zero + +> 策略描述 今天假设有一个笨笨的大型机构投资人(共同基金,银行,退休基金….),他想要买进一只股票,但又不想挂市价买进,所以就在市场里面挂了一张要买进的大单。这时候所有市场里面的人都会看的到limit order book里面有人挂进了大单准备要买进这只股票。 @@ -22,23 +27,29 @@ https://dn-filebox.qbox.me/33ecc8cd888b2918dcfb4044913c3c89a4cd4061.jpg +> 策略参数 + + -参数 默认值 描述 --------------- ----- ---------- -Interval 2000 出错重试间隔(毫秒) -Lot 0.01 手数 -DisableLog false 关闭订单跟踪 -ElephantAmount 10 大象级别(BTC) -ElephantSpace 0.2 大象距离(元) -LockCount true 大象确定次数 -PennyTick 0.1 跳 -WaitInterval 5000 买单超时(毫秒) -CheckInterval 300 快速检测间隔(毫秒) -ProfitTick 5 利润跳数 -STTick true 止损跳数 -*/ +|参数|默认值|描述| +|----|----|----| +|Interval|2000|出错重试间隔(毫秒)| +|Lot|0.01|手数| +|DisableLog|false|关闭订单跟踪| +|ElephantAmount|10|大象级别(BTC)| +|ElephantSpace|0.2|大象距离(元)| +|LockCount|true|大象确定次数| +|PennyTick|0.1|跳| +|WaitInterval|5000|买单超时(毫秒)| +|CheckInterval|300|快速检测间隔(毫秒)| +|ProfitTick|5|利润跳数| +|STTick|true|止损跳数| +> 源码 (javascript) + +``` javascript + var Counter = { i: 0, w: 0, @@ -167,3 +178,12 @@ function main() { LogProfit(account.Balance - InitAccount.Balance, account); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/358 + +> 更新时间 + +2016-08-27 10:37:36 diff --git "a/\351\253\230\351\242\221\346\224\266\345\211\262\346\234\272\344\270\200\345\217\267.js" "b/\351\253\230\351\242\221\346\224\266\345\211\262\346\234\272\344\270\200\345\217\267.md" similarity index 92% rename from "\351\253\230\351\242\221\346\224\266\345\211\262\346\234\272\344\270\200\345\217\267.js" rename to "\351\253\230\351\242\221\346\224\266\345\211\262\346\234\272\344\270\200\345\217\267.md" index d06a6f9b..439aed32 100644 --- "a/\351\253\230\351\242\221\346\224\266\345\211\262\346\234\272\344\270\200\345\217\267.js" +++ "b/\351\253\230\351\242\221\346\224\266\345\211\262\346\234\272\344\270\200\345\217\267.md" @@ -1,31 +1,45 @@ -/* -策略出处: https://www.fmz.com/strategy/6237 -策略名称: 高频收割机一号 -策略作者: Zero -策略描述: + +> 策略名称 + +高频收割机一号 + +> 策略作者 + +Zero + +> 策略描述 代码本身就是很好的注释, 识货的拿走. +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|DicAmount|0.6,1.5,1.8,1.9|交易量| +|DicBuyOffset|1.5,2.5,4.5,8|买单距离| +|DicSellOffset|1,1.8,2.5,4|卖单距离| +|DicResetDiff|0.1,0.3,0.3,0.4|撤单差价| +|DicStep|9,12,17,25|增量步长| +|DicSleep|1,2,3,5|等待周期| +|SleepPeriod|3000|轮询周期| +|ChartPeriod|600|统计周期| +|IsEnableLog|true|开启订单跟踪| -参数 默认值 描述 -------------- --------------- ------ -DicAmount 0.6,1.5,1.8,1.9 交易量 -DicBuyOffset 1.5,2.5,4.5,8 买单距离 -DicSellOffset 1,1.8,2.5,4 卖单距离 -DicResetDiff 0.1,0.3,0.3,0.4 撤单差价 -DicStep 9,12,17,25 增量步长 -DicSleep 1,2,3,5 等待周期 -SleepPeriod 3000 轮询周期 -ChartPeriod 600 统计周期 -IsEnableLog true 开启订单跟踪 -按钮 默认值 描述 ---------- ---------- --------- -开启/关闭订单跟踪 __button__ 开启/关闭订单跟踪 -统计周期 3600 秒数 -*/ +|按钮|默认值|描述| +|----|----|----| +|开启/关闭订单跟踪|__button__|开启/关闭订单跟踪| +|统计周期|3600|秒数| + + +> 源码 (javascript) + +``` javascript + var TAmount, TBuyOffset, TSellOffset, TResetDiff, TStep, TSleep, TLen; var OrdersBuy = []; var OrdersSell = []; @@ -314,3 +328,12 @@ function main() { Sleep(SleepPeriod); } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/6237 + +> 更新时间 + +2016-11-30 14:12:21 diff --git "a/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214.md" "b/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214.md" new file mode 100644 index 00000000..88872a41 --- /dev/null +++ "b/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214.md" @@ -0,0 +1,78 @@ + +> 策略名称 + +麦语言海龟策略体验 + +> 策略作者 + +Zero + +> 策略描述 + +> 尝个鲜 + +* 完全兼容文华麦语言语法 +* 基于发明者强大的低层, 完全支持数字货币现货期货与国内大宗商品期货 +* 兼容工作会一直持续, 目前兼容度90%大部分策略可以直接运行, 无需修改 +* API文档 https://www.fmz.com/bbs-topic/2569 + +>语言增强 + +发明者量化不单实现了麦语言的解释器, 而且还增强让其能与高级语言Javascript混合编程,放个例子 + +``` +%% +// 这里面可以调用发明者量化的任何API +scope.TEST = function(obj) { + return obj.val * 100; +} +%% +收盘价:C; +收盘价放大100倍:TEST(C); +上一个收盘价放大100倍:TEST(REF(C, 1)); // 鼠标移动到回测的K线上就会提示变量值 +``` + + /upload/asset/81cecb83b47ecca04ddd63c3206eb0db.png + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-06-01 00:00:00 +end: 2018-11-21 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","balance":500000,"minfee":0,"fee":[0,0]}] +*) + +//该示范主要用海龟交易法则,演示“头寸计算,最大仓位控制等资金管理”的编写方法 +//编写示范中,只对示范重点内容语句进行了注释,其他语句请自行翻译,或者咨询客服 +//该模型仅仅用来示范演示使用,依此入市,风险自负。 + +TR:=MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW));//真实波幅 +ATR:MA(TR,26); //求26个周期内真实波幅的简单移动平均, 在附图显示 +ZOOM:=IFELSE(ISCONTRACT('@Futures_(?!CTP).*'), CLOSE, 1); // 兼容数字货币期货币为保证金 +LOT:=((MONEYTOT*0.01*ZOOM)/(UNIT*ATR))*ZOOM;//根据权益的1%计算下单手数 +TC..IFELSE(ISCONTRACT('@Futures.*'), INTPART(LOT), LOT); // 兼容期货与现货ISCONTRACT以@开头表示匹配交易所名子, 支持正则 +MTC..4*TC; //总的持仓头寸 +HH^^HV(H,20); // 附加到主图显示 +LL^^LV(L,20); // 附加到主图显示 +CROSSUP(C,HH)&&ISLASTBK=0&&ISLASTSK=0&&BARPOS>=26,BK(TC);//最新价超过20周期的最高值,首次买入开仓,手数为TC手 +CROSSDOWN(C,LL)&&ISLASTBK=0&&ISLASTSK=0,SK(TC); //最新价跌破20周期的最低值,首次卖出开仓,手数为TC手 +C>=BKPRICE+0.5*ATR&&BKVOL0,SP(BKVOL);//最新价小于开仓价减去2倍的ATR,止损平仓 +C>=(SKPRICE+2*ATR)&&SKVOL>0,BP(SKVOL); //最新价大于开仓价加上2倍的ATR,止损平仓 +CROSSUP(H,HV(H,10))&&SKVOL>0,BP(SKVOL);//最高价上穿10周期最高价,平仓 +CROSSDOWN(L,LV(L,10))&&BKVOL>0,SP(BKVOL); //最低价下穿10周期的最低价,平仓 +TRADE_AGAIN(10); +``` + +> 策略出处 + +https://www.fmz.com/strategy/126968 + +> 更新时间 + +2018-12-06 16:01:33 diff --git "a/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.js" "b/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.md" similarity index 95% rename from "\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.js" rename to "\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.md" index bbd87e8a..033d9db5 100644 --- "a/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.js" +++ "b/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.md" @@ -1,23 +1,37 @@ -/* -策略出处: https://www.fmz.com/strategy/20663 -策略名称: (13)策略框架 -策略作者: 小小梦 -策略描述: + +> 策略名称 + +(13)策略框架 + +> 策略作者 + +小小梦 + +> 策略描述 策略框架 +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|isLogReset|true|启动时是否清除日志| -参数 默认值 描述 ----------- ----- --------- -isLogReset true 启动时是否清除日志 -按钮 默认值 描述 ------------- ---------- ------- -upDateAmount true 更新开仓量按钮 -cmdOpen __button__ 开仓命令 -cmdCover __button__ 平仓命令 -*/ + +|按钮|默认值|描述| +|----|----|----| +|upDateAmount|true|更新开仓量按钮| +|cmdOpen|__button__|开仓命令| +|cmdCover|__button__|平仓命令| + + +> 源码 (javascript) + +``` javascript var Interval = 500; var _long = 1; var free = 0; @@ -254,3 +268,12 @@ function main(){ } } +``` + +> 策略出处 + +https://www.fmz.com/strategy/20663 + +> 更新时间 + +2018-09-13 12:06:44 From 2e9ff0ae19908169ed30958fcb112ba5c51d6fe3 Mon Sep 17 00:00:00 2001 From: Zero Date: Sat, 8 Dec 2018 12:48:26 +0800 Subject: [PATCH 07/19] update --- ...40\207\347\273\204\345\220\210\347\255\226\347\225\245.md" | 2 +- "RUMI\347\255\226\347\225\245.md" | 4 ++-- ...40\274\347\252\201\347\240\264\347\255\226\347\225\245.md" | 2 +- ...63\242\345\212\250\347\216\207\347\255\226\347\225\245.md" | 2 +- ...07\215\350\266\213\345\212\277\347\255\226\347\225\245.md" | 2 +- ...32\204\344\272\244\346\230\223\347\255\226\347\225\245.md" | 2 +- ...53\230\344\275\216\347\202\271\347\255\226\347\225\245.md" | 2 +- ...01\222\346\270\251\345\231\250\347\255\226\347\225\245.md" | 2 +- ...214\345\235\207\347\272\277DDI\347\255\226\347\225\245.md" | 2 +- ...261RSI\346\214\207\346\240\207\347\273\204\345\220\210.md" | 2 +- ...\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" | 2 +- ...33\210\350\266\213\345\212\277\347\255\226\347\225\245.md" | 2 +- ...207\344\273\267\345\267\256ATR\347\255\226\347\225\245.md" | 2 +- ...53\230\344\275\216\347\202\271\347\255\226\347\225\245.md" | 2 +- ...56\200\345\214\226\347\211\210\347\255\226\347\225\245.md" | 2 +- ...40\274\351\200\232\351\201\223\347\255\226\347\225\245.md" | 4 ++-- ...01\223\347\252\201\347\240\264\347\255\226\347\225\245.md" | 2 +- ...00\221\345\270\203\347\272\277\347\255\226\347\225\245.md" | 2 +- ...207ROC\346\214\207\346\240\207\347\255\226\347\225\245.md" | 4 ++-- ...25\260\345\212\240\346\235\203\347\255\226\347\225\245.md" | 2 +- ...207ORB\344\272\244\346\230\223\347\255\226\347\225\245.md" | 2 +- ...76\237\347\255\226\347\225\245\344\275\223\351\252\214.md" | 2 +- 22 files changed, 25 insertions(+), 25 deletions(-) diff --git "a/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" "b/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" index 8d8e5b87..dec13d32 100644 --- "a/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" +++ "b/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" @@ -23,7 +23,7 @@ littleDreamXX 主图显示:DMA1,公式 DMA1^^MA(C,L1); DMA2,公式 DMA2^^MA(C,L2); -/upload/asset/6d7b1a3241d607bbc4f4f853687fcf54.png +![IMG](https://www.fmz.com/upload/asset/6d7b1a3241d607bbc4f4f853687fcf54.png) > 策略参数 diff --git "a/RUMI\347\255\226\347\225\245.md" "b/RUMI\347\255\226\347\225\245.md" index 021a14ee..80173260 100644 --- "a/RUMI\347\255\226\347\225\245.md" +++ "b/RUMI\347\255\226\347\225\245.md" @@ -15,9 +15,9 @@ littleDreamXX - 官方网站:www.quant.la - /upload/asset/df2427683a93f2c896c853c89e3ae494.png + ![IMG](https://www.fmz.com/upload/asset/df2427683a93f2c896c853c89e3ae494.png) - /upload/asset/67f75ccbe20acf6cbaa62a1d580daeda.png + ![IMG](https://www.fmz.com/upload/asset/67f75ccbe20acf6cbaa62a1d580daeda.png) - 主图: diff --git "a/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245.md" "b/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245.md" index 8577dea9..e6fc5998 100644 --- "a/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245.md" +++ "b/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245.md" @@ -16,7 +16,7 @@ littleDreamXX - 适合品种:商品期货 - 官方网站:www.quant.la -/upload/asset/4327c3e54a8618bb6f5b0ac3ea54dfc2.png +![IMG](https://www.fmz.com/upload/asset/4327c3e54a8618bb6f5b0ac3ea54dfc2.png) > 策略参数 diff --git "a/\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245.md" "b/\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245.md" index 570c61ea..3e6e3caf 100644 --- "a/\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245.md" +++ "b/\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245.md" @@ -14,7 +14,7 @@ littleDreamXX - 交易合约:螺纹主连,郑煤主连,热卷主连,铁矿主连,焦炭主连,棕榈主连,橡胶主连,郑醇主连,PP主连,沪铜主连; - 数据级别:日K线; -/upload/asset/785c3a0e4e8c164bc831b05dcdc355a3.png +![IMG](https://www.fmz.com/upload/asset/785c3a0e4e8c164bc831b05dcdc355a3.png) - 主图指标显示: MIDTR^^MA(C,CN); // 确定MIDTR diff --git "a/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245.md" "b/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245.md" index e1c4562c..5e42d13f 100644 --- "a/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245.md" +++ "b/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245.md" @@ -14,7 +14,7 @@ littleDreamXX - 支持:商品期货 - 官方网站:www.quant.la -/upload/asset/487949c7affb8521d9c041610551c3cd.png +![IMG](https://www.fmz.com/upload/asset/487949c7affb8521d9c041610551c3cd.png) - 主图: diff --git "a/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" index 346afb96..2cb2b75b 100644 --- "a/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" +++ "b/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -15,7 +15,7 @@ littleDreamXX - 指标使用了EMA,KD线,其中KD线使用的是默认参数(指标参数固定3,3,9) - 官方网站:www.quant.la -/upload/asset/f842e44b0b8451cb562b8d5bd888e4c0.png +![IMG](https://www.fmz.com/upload/asset/f842e44b0b8451cb562b8d5bd888e4c0.png) - 主图 EMA均线,公式:MAC^^EMA(C,N); diff --git "a/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" "b/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" index c9b1f184..2c70018e 100644 --- "a/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" +++ "b/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" @@ -16,7 +16,7 @@ littleDreamXX -/upload/asset/739ea1e668541f362205d9b5acb43372.png +![IMG](https://www.fmz.com/upload/asset/739ea1e668541f362205d9b5acb43372.png) - 主图: AMA1指标,公式:AMA1^^EMA(DMA(CLOSE,CQ1),2); diff --git "a/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" "b/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" index f9bc1814..f57b431a 100644 --- "a/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" +++ "b/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" @@ -14,7 +14,7 @@ littleDreamXX - 支持:商品期货 - 官方网站:WWW.QUANT.LA - /upload/asset/bcf664987bac1aaff72110b1e3679d10.png + ![IMG](https://www.fmz.com/upload/asset/bcf664987bac1aaff72110b1e3679d10.png) - 主图: 上轨,公式:TOP^^MAC+N_TMP*TMP;//布林通道上轨 diff --git "a/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245.md" "b/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245.md" index c5de956b..c7d1ec0b 100644 --- "a/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245.md" +++ "b/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245.md" @@ -25,7 +25,7 @@ littleDreamXX VAR10:MA(VAR9,PARAM1); VAR8:VAR6-VAR7; -/upload/asset/e83641b0567b242687792b105de8e211.png +![IMG](https://www.fmz.com/upload/asset/e83641b0567b242687792b105de8e211.png) > 策略参数 diff --git "a/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210.md" "b/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210.md" index a80e5a55..de16fbb5 100644 --- "a/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210.md" +++ "b/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210.md" @@ -14,7 +14,7 @@ littleDreamXX - 支持:商品期货 - 官方网站:www.quant.la -/upload/asset/9955a36cca1be0e9d73f99fa8bdb4ac8.png +![IMG](https://www.fmz.com/upload/asset/9955a36cca1be0e9d73f99fa8bdb4ac8.png) - 主图: 均线1,公式:MA1^^EMA(C,N1); diff --git "a/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" "b/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" index b3f42d06..9250f62a 100644 --- "a/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" +++ "b/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" @@ -9,7 +9,7 @@ > 策略描述 -/upload/asset/20dd683abc5a0e70f84c5f2ae37c1753.png +![IMG](https://www.fmz.com/upload/asset/20dd683abc5a0e70f84c5f2ae37c1753.png) > 策略参数 diff --git "a/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245.md" "b/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245.md" index cd0619ec..5c3aaa12 100644 --- "a/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245.md" +++ "b/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245.md" @@ -14,7 +14,7 @@ littleDreamXX - 支持:商品期货、数字货币 - 官方网站:www.quant.la -/upload/asset/b8d89a704605b72bc44a56575a570bf6.png +![IMG](https://www.fmz.com/upload/asset/b8d89a704605b72bc44a56575a570bf6.png) - 主图: 上线,公式 :UPPERLINE^^今开+BAND; diff --git "a/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245.md" "b/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245.md" index 619ed6c8..ad2ef51b 100644 --- "a/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245.md" +++ "b/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245.md" @@ -24,7 +24,7 @@ littleDreamXX 显示:ATR,公式 ATR^^MA(TR,N); 显示 :C_O,公式 C_O:EMA(C,N)-EMA(O,N); -/upload/asset/ab8d909c6464234b06ef1f116a4de200.png +![IMG](https://www.fmz.com/upload/asset/ab8d909c6464234b06ef1f116a4de200.png) > 策略参数 diff --git "a/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" "b/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" index 302232f4..10b93d3a 100644 --- "a/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" +++ "b/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" @@ -14,7 +14,7 @@ littleDreamXX - 策略支持:商品期货、数字货币现货,数字货币期货 - 官方网站:www.quant.la -/upload/asset/4d9459b9af47702f7c2c6666212927c7.png +![IMG](https://www.fmz.com/upload/asset/4d9459b9af47702f7c2c6666212927c7.png) > 策略参数 diff --git "a/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245.md" "b/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245.md" index 80ff1964..7f7c2881 100644 --- "a/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245.md" +++ "b/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245.md" @@ -14,7 +14,7 @@ littleDreamXX - 适用周期:多周期 - 官方网站:WWW.QUANT.LA - /upload/asset/8f499518ffb1876478917e564e9b7a71.png + ![IMG](https://www.fmz.com/upload/asset/8f499518ffb1876478917e564e9b7a71.png) - 主图: 无 diff --git "a/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245.md" "b/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245.md" index c4592e7a..0e2d68ed 100644 --- "a/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245.md" +++ "b/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245.md" @@ -15,10 +15,10 @@ littleDreamXX - 官方网站:www.quant.la 商品期货回测 -/upload/asset/f58bc64ccfc4dca7cc1905b238f07dd7.png +![IMG](https://www.fmz.com/upload/asset/f58bc64ccfc4dca7cc1905b238f07dd7.png) 数字货币回测 -/upload/asset/5a92307691b3946e7bc5be0cb58a1e26.png +![IMG](https://www.fmz.com/upload/asset/5a92307691b3946e7bc5be0cb58a1e26.png) - 主图: 上线, 公式 : UPPERBAND^^AVGVALUE + SHIFTVALUE; diff --git "a/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245.md" "b/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245.md" index eeb3f3ba..fa2b8339 100644 --- "a/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245.md" +++ "b/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245.md" @@ -14,7 +14,7 @@ littleDreamXX - 支持:商品期货、数字货币现货、数字货币期货 - 官方网站:www.quant.la -/upload/asset/36b0e279ae314411a9d6b7e94a0623f0.png +![IMG](https://www.fmz.com/upload/asset/36b0e279ae314411a9d6b7e94a0623f0.png) - 主图: 中轨,公式:MIDLINE^^MA((H + L + C)/3,LENGTH1); diff --git "a/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245.md" "b/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245.md" index 49b9806f..cecfc5d3 100644 --- "a/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245.md" +++ "b/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245.md" @@ -14,7 +14,7 @@ littleDreamXX - 支持:商品期货 - 官方网站:www.quant.la -/upload/asset/3ba2dba0c6b01773b2c296438ff77d25.png +![IMG](https://www.fmz.com/upload/asset/3ba2dba0c6b01773b2c296438ff77d25.png) - 主图 瀑布线1,公式:PUBU1^^(EMA(C,N1)+EMA(C,N1*2)+EMA(C,N1*4))/3; diff --git "a/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245.md" "b/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245.md" index 1d7530af..1f1b1641 100644 --- "a/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245.md" +++ "b/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245.md" @@ -14,8 +14,8 @@ littleDreamXX - 支持:商品期货 - 官方网站:www.quant.la -/upload/asset/1f5e3caa65a3871ae9c9d99f9c11bdf0.png -/upload/asset/ec4cbcbb036925739a04de90cadf1d8d.png +![IMG](https://www.fmz.com/upload/asset/1f5e3caa65a3871ae9c9d99f9c11bdf0.png) +![IMG](https://www.fmz.com/upload/asset/ec4cbcbb036925739a04de90cadf1d8d.png) - 主图: N周期最高价,公式:HH^^HHV(H,N); diff --git "a/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245.md" "b/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245.md" index 567fe508..edd864f3 100644 --- "a/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245.md" +++ "b/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245.md" @@ -15,7 +15,7 @@ littleDreamXX - 合约:this_week 当周合约 - 官方网站:www.quant.la -/upload/asset/efa8dad9db6b13862283a69ee8255934.png +![IMG](https://www.fmz.com/upload/asset/efa8dad9db6b13862283a69ee8255934.png) - 主图: 无 diff --git "a/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245.md" index c2c75e44..fd584f77 100644 --- "a/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245.md" +++ "b/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -14,7 +14,7 @@ littleDreamXX - 支持:商品期货 - 官方网站:www.quant.la - /upload/asset/860ae7cefa35c714a7f3c028ad77e656.png + ![IMG](https://www.fmz.com/upload/asset/860ae7cefa35c714a7f3c028ad77e656.png) - 主图: 均线, 公式:MAC^^MA(CLOSE,LENGTH); diff --git "a/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214.md" "b/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214.md" index 88872a41..37c405e7 100644 --- "a/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214.md" +++ "b/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214.md" @@ -32,7 +32,7 @@ scope.TEST = function(obj) { 上一个收盘价放大100倍:TEST(REF(C, 1)); // 鼠标移动到回测的K线上就会提示变量值 ``` - /upload/asset/81cecb83b47ecca04ddd63c3206eb0db.png + ![IMG](https://www.fmz.com/upload/asset/81cecb83b47ecca04ddd63c3206eb0db.png) From d9c3182152b862800b231e5d3bc3361713f1455e Mon Sep 17 00:00:00 2001 From: Zero Date: Sat, 8 Dec 2018 12:54:59 +0800 Subject: [PATCH 08/19] update --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4800b71f..5bb66dd1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# 用 Javascript / Python 进行量化交易 +# 发明者(FMZ) - 筑就非凡的量化世界 -> 开源策略列表 +> 开源策略 - [RUMI策略](https://www.fmz.com/strategy/129082) From 9a4ff483a3a90b8f5d37a429e17409041de69abc Mon Sep 17 00:00:00 2001 From: Zero Date: Sun, 23 Dec 2018 21:00:42 +0800 Subject: [PATCH 09/19] update --- "CTP \346\234\237\350\264\247.md" | 649 ++++++++++++++++++ ...\210)|Dual Thrust (MyLanguage version).md" | 35 +- Dynamic Balance Strategy.md | 106 --- ...04\345\220\210\347\255\226\347\225\245.md" | 14 +- README.md | 56 +- ...\347\255\226\347\225\245|RUMI Strategy.md" | 27 +- ...5|Three-MA Price Breakthrough Strategy.md" | 31 +- ...50\347\216\207\347\255\226\347\225\245.md" | 89 --- ...25\245|Three-track Volatility Strategy.md" | 131 ++++ ...high and low - Ichimoku trend strategy.md" | 27 +- ...44\346\230\223\347\255\226\347\225\245.md" | 73 -- ...y of Traditional MA Index and KD Index.md" | 98 +++ ...04\345\220\210\347\255\226\347\225\245.md" | 79 --- ...MACD+MA Indicator Combination Strategy.md" | 79 +++ ...\347\225\245|DMI and High-Low Strategy.md" | 32 +- ...51\345\231\250\347\255\226\347\225\245.md" | 108 --- ...7\225\245|Upgraded Thermostat Strategy.md" | 148 ++++ ...245|Double Average Lines -DDI Strategy.md" | 54 +- ...5\245|Double MA and Formation Strategy.md" | 98 +++ ...0\210|Combination of Double MA and RSI.md" | 32 +- ...37\345\215\225\347\263\273\347\273\237.md" | 131 ++-- ...ative Strength Strategy Based on Price.md" | 96 +++ ...32\351\201\223\347\255\226\347\225\245.md" | 56 -- ...tegy based on ATR volatility indicator.md" | 76 ++ ...\225\245|Channel strategy based on ATR.md" | 91 +++ ...13\345\212\277\347\255\226\347\225\245.md" | 110 --- ...25\245|Multilevel Take Profit Strategy.md" | 157 +++++ ...rage of difference - combined with ATR.md" | 35 +- ...45|SAR and Price High and Low Strategy.md" | 29 +- ...Version of ICHIMOKU KINKO HYO Strategy.md" | 34 +- ...ndard deviation price channel strategy.md" | 40 +- ...lity ATR - Track Breakthrough Strategy.md" | 30 +- ...45\270\201macd\351\207\221\345\217\211.md" | 175 +++++ ...226\347\225\245|Trading Chaos Strategy.md" | 113 +++ ...7\347\255\226\347\225\245|PBX Strategy.md" | 28 +- ...rice high and low - ROC index strategy.md" | 29 +- ... Low - Volume Index Weighting Strategy.md" | 45 +- ...gh Winning Rate - ORB Trading Strategy.md" | 28 +- 38 files changed, 2420 insertions(+), 849 deletions(-) create mode 100644 "CTP \346\234\237\350\264\247.md" rename "Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210).md" => "Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210)|Dual Thrust (MyLanguage version).md" (53%) delete mode 100644 Dynamic Balance Strategy.md rename "RUMI\347\255\226\347\225\245.md" => "RUMI\347\255\226\347\225\245|RUMI Strategy.md" (62%) rename "\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245.md" => "\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245|Three-MA Price Breakthrough Strategy.md" (68%) delete mode 100644 "\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245.md" create mode 100644 "\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245|Three-track Volatility Strategy.md" rename "\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245.md" => "\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245|Price high and low - Ichimoku trend strategy.md" (55%) delete mode 100644 "\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" create mode 100644 "\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245|Trading Strategy of Traditional MA Index and KD Index.md" delete mode 100644 "\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" create mode 100644 "\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245|MACD+MA Indicator Combination Strategy.md" rename "\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" => "\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|DMI and High-Low Strategy.md" (60%) delete mode 100644 "\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" create mode 100644 "\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245|Upgraded Thermostat Strategy.md" rename "\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245.md" => "\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245|Double Average Lines -DDI Strategy.md" (61%) create mode 100644 "\345\217\214\345\235\207\347\272\277\344\270\216\345\275\242\346\200\201\347\255\226\347\225\245|Double MA and Formation Strategy.md" rename "\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210.md" => "\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210|Combination of Double MA and RSI.md" (66%) create mode 100644 "\345\235\207\347\272\277\345\222\214\351\253\230\344\275\216\347\202\271\347\233\270\345\257\271\345\274\272\345\274\261\347\255\226\347\225\245|Relative Strength Strategy Based on Price.md" delete mode 100644 "\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245.md" create mode 100644 "\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245|Channel strategy based on ATR volatility indicator.md" create mode 100644 "\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245|Channel strategy based on ATR.md" delete mode 100644 "\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245.md" create mode 100644 "\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245|Multilevel Take Profit Strategy.md" rename "\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245.md" => "\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245|The average of difference - combined with ATR.md" (62%) rename "\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" => "\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|SAR and Price High and Low Strategy.md" (59%) rename "\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245.md" => "\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245|Simplified Version of ICHIMOKU KINKO HYO Strategy.md" (56%) rename "\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245.md" => "\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245|Standard deviation price channel strategy.md" (58%) rename "\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245.md" => "\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245|Volatility ATR - Track Breakthrough Strategy.md" (59%) create mode 100644 "\346\265\213\350\257\225\347\201\253\345\270\201macd\351\207\221\345\217\211.md" create mode 100644 "\346\267\267\346\262\214\346\223\215\344\275\234\346\263\225\347\255\226\347\225\245|Trading Chaos Strategy.md" rename "\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245.md" => "\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245|PBX Strategy.md" (66%) rename "\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245.md" => "\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245|Price high and low - ROC index strategy.md" (63%) rename "\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245.md" => "\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245|Break High and Low - Volume Index Weighting Strategy.md" (58%) rename "\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245.md" => "\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245|High Winning Rate - ORB Trading Strategy.md" (70%) diff --git "a/CTP \346\234\237\350\264\247.md" "b/CTP \346\234\237\350\264\247.md" new file mode 100644 index 00000000..767ecdf5 --- /dev/null +++ "b/CTP \346\234\237\350\264\247.md" @@ -0,0 +1,649 @@ + +> 策略名称 + +CTP 期货 + +> 策略作者 + +tyz + +> 策略描述 + +- 只支持操作CTP商品期货 +- 支持自动或手动恢复进度 +- 可同时操作多个不同品种 +- 增加时间段区分与各种网络错误问题的应对处理 +- 移仓功能目前正在加入中 + +请下载最新托管者并比较版本号是否最新 +``` text +$ ./robot -v +BotVS docker 3.0 compiled at 2016-07-05T09:56:18+0800 +``` + + https://dn-filebox.qbox.me/d33687abb648c489b6883296685e8717ea3f44ca.png + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Instruments|MA701,CF701,zn1701,SR701,pp1701,l1701,hc1610,ni1701,i1701,v1701,rb1610,jm1701,ag1612,al1701,jd1701,cs1701,p1701|合约列表| +|LoopInterval|3|轮询周期(秒)| +|RiskRatio|true|% Risk Per N ( 0 - 100)| +|ATRLength|20|ATR计算周期| +|EnterPeriodA|20|系统一入市周期| +|LeavePeriodA|10|系统一离市周期| +|EnterPeriodB|55|系统二入市周期| +|LeavePeriodB|20|系统二离市周期| +|UseEnterFilter|true|使用入市过滤| +|IncSpace|0.5|加仓间隔(N的倍数)| +|StopLossRatio|2|止损系数(N的倍数)| +|MaxLots|4|单品种加仓次数| +|RMode|0|进度恢复模式: 自动|手动| +|VMStatus|{}|手动恢复字符串| +|WXPush|true|推送交易信息| +|MaxTaskRetry|5|开仓最多重试次数| +|KeepRatio|10|预留保证金比例| + + + + +|按钮|默认值|描述| +|----|----|----| +|暂停/继续|__button__|暂停/继续| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2016-03-01 00:00:00 +end: 2016-12-30 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +*/ + +var _bot = $.NewPositionManager(); + +var TTManager = { + New: function(needRestore, symbol, keepBalance, riskRatio, atrLen, enterPeriodA, leavePeriodA, enterPeriodB, leavePeriodB, useFilter, + multiplierN, multiplierS, maxLots) { + + // subscribe + var symbolDetail = _C(exchange.SetContractType, symbol); + if (symbolDetail.VolumeMultiple == 0 || symbolDetail.MaxLimitOrderVolume == 0 || symbolDetail.MinLimitOrderVolume == 0 || symbolDetail.LongMarginRatio == 0 || symbolDetail.ShortMarginRatio == 0) { + Log(symbolDetail); + throw "合约信息异常"; + } else { + Log("合约", symbolDetail.InstrumentName, "一手", symbolDetail.VolumeMultiple, "份, 最大下单量", symbolDetail.MaxLimitOrderVolume, "保证金率:", _N(symbolDetail.LongMarginRatio), _N(symbolDetail.ShortMarginRatio), "交割日期", symbolDetail.StartDelivDate); + } + + var ACT_IDLE = 0; + var ACT_LONG = 1; + var ACT_SHORT = 2; + var ACT_COVER = 3; + + + var ERR_SUCCESS = 0; + var ERR_SET_SYMBOL = 1; + var ERR_GET_ORDERS = 2; + var ERR_GET_POS = 3; + var ERR_TRADE = 4; + var ERR_GET_DEPTH = 5; + var ERR_NOT_TRADING = 6; + var errMsg = ["成功", "切换合约失败", "获取订单失败", "获取持仓失败", "交易下单失败", "获取深度失败", "不在交易时间"]; + + var obj = { + symbol: symbol, + keepBalance: keepBalance, + riskRatio: riskRatio, + atrLen: atrLen, + enterPeriodA: enterPeriodA, + leavePeriodA: leavePeriodA, + enterPeriodB: enterPeriodB, + leavePeriodB: leavePeriodB, + useFilter: useFilter, + multiplierN: multiplierN, + multiplierS: multiplierS + }; + obj.task = { + action: ACT_IDLE, + amount: 0, + dealAmount: 0, + avgPrice: 0, + preCost: 0, + preAmount: 0, + init: false, + retry: 0, + desc: "空闲", + onFinish: null + } + obj.maxLots = maxLots; + obj.lastPrice = 0; + obj.symbolDetail = symbolDetail; + obj.status = { + symbol: symbol, + recordsLen: 0, + vm: [], + open: 0, + cover: 0, + st: 0, + marketPosition: 0, + lastPrice: 0, + holdPrice: 0, + holdAmount: 0, + holdProfit: 0, + N: 0, + upLine: 0, + downLine: 0, + symbolDetail: symbolDetail, + lastErr: "", + lastErrTime: "", + stopPrice: '', + leavePrice: '', + isTrading: false + }; + + obj.setLastError = function(err) { + if (typeof(err) === 'undefined' || err === '') { + obj.status.lastErr = ""; + obj.status.lastErrTime = ""; + return; + } + var t = new Date(); + obj.status.lastErr = err; + obj.status.lastErrTime = t.toLocaleString(); + }; + obj.reset = function(marketPosition, openPrice, N, leavePeriod, preBreakoutFailure) { + if (typeof(marketPosition) !== 'undefined') { + obj.marketPosition = marketPosition; + obj.openPrice = openPrice; + obj.preBreakoutFailure = preBreakoutFailure; + obj.N = N; + obj.leavePeriod = leavePeriod; + var pos = _bot.GetPosition(obj.symbol, marketPosition > 0 ? PD_LONG : PD_SHORT); + if (pos) { + obj.holdPrice = pos.Price; + obj.holdAmount = pos.Amount; + Log(obj.symbol, "仓位", pos); + } else { + throw "恢复" + obj.symbol + "的持仓状态出错, 没有找到仓位信息"; + } + Log("恢复", obj.symbol, "加仓次数", obj.marketPosition, "持仓均价:", obj.holdPrice, "持仓数量:", obj.holdAmount, "最后一次加仓价", obj.openPrice, "N值", obj.N, "离市周期:", leavePeriod, "上次突破:", obj.preBreakoutFailure ? "失败" : "成功"); + obj.status.open = 1; + obj.status.vm = [obj.marketPosition, obj.openPrice, obj.N, obj.leavePeriod, obj.preBreakoutFailure]; + } else { + obj.marketPosition = 0; + obj.holdPrice = 0; + obj.openPrice = 0; + obj.holdAmount = 0; + obj.holdProfit = 0; + obj.preBreakoutFailure = true; // test system A + obj.N = 0; + obj.leavePeriod = leavePeriodA; + } + obj.holdProfit = 0; + obj.lastErr = ""; + obj.lastErrTime = ""; + }; + + obj.Status = function() { + obj.status.N = obj.N; + obj.status.marketPosition = obj.marketPosition; + obj.status.holdPrice = obj.holdPrice; + obj.status.holdAmount = obj.holdAmount; + obj.status.lastPrice = obj.lastPrice; + if (obj.lastPrice > 0 && obj.holdAmount > 0 && obj.marketPosition !== 0) { + obj.status.holdProfit = _N((obj.lastPrice - obj.holdPrice) * obj.holdAmount * symbolDetail.VolumeMultiple, 4) * (obj.marketPosition > 0 ? 1 : -1); + } else { + obj.status.holdProfit = 0; + } + return obj.status; + }; + obj.setTask = function(action, amount, onFinish) { + obj.task.init = false; + obj.task.retry = 0; + obj.task.action = action; + obj.task.preAmount = 0; + obj.task.preCost = 0; + obj.task.amount = typeof(amount) === 'number' ? amount : 0; + obj.task.onFinish = onFinish; + if (action == ACT_IDLE) { + obj.task.desc = "空闲"; + obj.task.onFinish = null; + } else { + if (action !== ACT_COVER) { + obj.task.desc = (action == ACT_LONG ? "加多仓" : "加空仓") + "(" + amount + ")"; + } else { + obj.task.desc = "平仓"; + } + Log("接收到任务", obj.symbol, obj.task.desc); + // process immediately + obj.Poll(true); + } + }; + obj.processTask = function() { + var insDetail = exchange.SetContractType(obj.symbol); + if (!insDetail) { + return ERR_SET_SYMBOL; + } + var SlideTick = 1; + var ret = false; + if (obj.task.action == ACT_COVER) { + var hasPosition = false; + do { + if (!$.IsTrading(obj.symbol)) { + return ERR_NOT_TRADING; + } + hasPosition = false; + var positions = exchange.GetPosition(); + if (!positions) { + return ERR_GET_POS; + } + var depth = exchange.GetDepth(); + if (!depth) { + return ERR_GET_DEPTH; + } + var orderId = null; + for (var i = 0; i < positions.length; i++) { + if (positions[i].ContractType !== obj.symbol) { + continue; + } + var amount = Math.min(insDetail.MaxLimitOrderVolume, positions[i].Amount); + if (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) { + exchange.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy"); + orderId = exchange.Sell(_N(depth.Bids[0].Price - (insDetail.PriceTick * SlideTick), 2), Math.min(amount, depth.Bids[0].Amount), obj.symbol, positions[i].Type == PD_LONG ? "平今" : "平昨", 'Bid', depth.Bids[0]); + hasPosition = true; + } else if (positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD) { + exchange.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell"); + orderId = exchange.Buy(_N(depth.Asks[0].Price + (insDetail.PriceTick * SlideTick), 2), Math.min(amount, depth.Asks[0].Amount), obj.symbol, positions[i].Type == PD_SHORT ? "平今" : "平昨", 'Ask', depth.Asks[0]); + hasPosition = true; + } + } + if (hasPosition) { + if (!orderId) { + return ERR_TRADE; + } + Sleep(1000); + while (true) { + // Wait order, not retry + var orders = exchange.GetOrders(); + if (!orders) { + return ERR_GET_ORDERS; + } + if (orders.length == 0) { + break; + } + for (var i = 0; i < orders.length; i++) { + exchange.CancelOrder(orders[i].Id); + Sleep(500); + } + } + } + } while (hasPosition); + ret = true; + } else if (obj.task.action == ACT_LONG || obj.task.action == ACT_SHORT) { + do { + if (!$.IsTrading(obj.symbol)) { + return ERR_NOT_TRADING; + } + Sleep(1000); + while (true) { + // Wait order, not retry + var orders = exchange.GetOrders(); + if (!orders) { + return ERR_GET_ORDERS; + } + if (orders.length == 0) { + break; + } + for (var i = 0; i < orders.length; i++) { + exchange.CancelOrder(orders[i].Id); + Sleep(500); + } + } + var positions = exchange.GetPosition(); + // Error + if (!positions) { + return ERR_GET_POS; + } + // search position + var pos = null; + for (var i = 0; i < positions.length; i++) { + if (positions[i].ContractType == obj.symbol && (((positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) && obj.task.action == ACT_LONG) || ((positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD) && obj.task.action == ACT_SHORT))) { + if (!pos) { + pos = positions[i]; + pos.Cost = positions[i].Price * positions[i].Amount; + } else { + pos.Amount += positions[i].Amount; + pos.Profit += positions[i].Profit; + pos.Cost += positions[i].Price * positions[i].Amount; + } + } + } + // record pre position + if (!obj.task.init) { + obj.task.init = true; + if (pos) { + obj.task.preAmount = pos.Amount; + obj.task.preCost = pos.Cost; + } else { + obj.task.preAmount = 0; + obj.task.preCost = 0; + } + } + var remain = obj.task.amount; + if (pos) { + obj.task.dealAmount = pos.Amount - obj.task.preAmount; + remain = parseInt(obj.task.amount - obj.task.dealAmount); + if (remain <= 0 || obj.task.retry >= MaxTaskRetry) { + ret = { + price: (pos.Cost - obj.task.preCost) / (pos.Amount - obj.task.preAmount), + amount: (pos.Amount - obj.task.preAmount), + position: pos + }; + break; + } + } else if (obj.task.retry >= MaxTaskRetry) { + ret = null; + break; + } + + var depth = exchange.GetDepth(); + if (!depth) { + return ERR_GET_DEPTH; + } + var orderId = null; + if (obj.task.action == ACT_LONG) { + exchange.SetDirection("buy"); + orderId = exchange.Buy(_N(depth.Asks[0].Price + (insDetail.PriceTick * SlideTick), 2), Math.min(remain, depth.Asks[0].Amount), obj.symbol, 'Ask', depth.Asks[0]); + } else { + exchange.SetDirection("sell"); + orderId = exchange.Sell(_N(depth.Bids[0].Price - (insDetail.PriceTick * SlideTick), 2), Math.min(remain, depth.Bids[0].Amount), obj.symbol, 'Bid', depth.Bids[0]); + } + // symbol not in trading or other else happend + if (!orderId) { + obj.task.retry++; + return ERR_TRADE; + } + } while (true); + } + if (obj.task.onFinish) { + obj.task.onFinish(ret); + } + obj.setTask(ACT_IDLE); + return ERR_SUCCESS; + }; + obj.Poll = function(subroutine) { + obj.status.isTrading = $.IsTrading(obj.symbol); + if (!obj.status.isTrading) { + return; + } + if (obj.task.action != ACT_IDLE) { + var retCode = obj.processTask(); + if (obj.task.action != ACT_IDLE) { + obj.setLastError("任务没有处理成功: " + errMsg[retCode] + ", " + obj.task.desc + ", 重试: " + obj.task.retry); + } else { + obj.setLastError(); + } + return; + } + if (typeof(subroutine) !== 'undefined' && subroutine) { + return; + } + // Loop + var suffix = WXPush ? '@' : ''; + // switch symbol + _C(exchange.SetContractType, obj.symbol); + var records = exchange.GetRecords(); + if (!records) { + obj.setLastError("获取K线失败"); + return; + } + obj.status.recordsLen = records.length; + if (records.length < obj.atrLen) { + obj.setLastError("K线长度小于 " + obj.atrLen); + return; + } + var opCode = 0; // 0: IDLE, 1: LONG, 2: SHORT, 3: CoverALL + var lastPrice = records[records.length - 1].Close; + obj.lastPrice = lastPrice; + if (obj.marketPosition === 0) { + obj.status.stopPrice = '--'; + obj.status.leavePrice = '--'; + obj.status.upLine = 0; + obj.status.downLine = 0; + for (var i = 0; i < 2; i++) { + if (i == 0 && obj.useFilter && !obj.preBreakoutFailure) { + continue; + } + var enterPeriod = i == 0 ? obj.enterPeriodA : obj.enterPeriodB; + if (records.length < (enterPeriod + 1)) { + continue; + } + var highest = TA.Highest(records, enterPeriod, 'High'); + var lowest = TA.Lowest(records, enterPeriod, 'Low'); + obj.status.upLine = obj.status.upLine == 0 ? highest : Math.min(obj.status.upLine, highest); + obj.status.downLine = obj.status.downLine == 0 ? lowest : Math.max(obj.status.downLine, lowest); + if (lastPrice > highest) { + opCode = 1; + } else if (lastPrice < lowest) { + opCode = 2; + } + if (opCode != 0) { + obj.leavePeriod = (enterPeriod == obj.enterPeriodA) ? obj.leavePeriodA : obj.leavePeriodB; + break; + } + } + } else { + var spread = obj.marketPosition > 0 ? (obj.openPrice - lastPrice) : (lastPrice - obj.openPrice); + obj.status.stopPrice = _N(obj.openPrice + (obj.N * StopLossRatio * (obj.marketPosition > 0 ? -1 : 1))); + if (spread > (obj.N * StopLossRatio)) { + opCode = 3; + obj.preBreakoutFailure = true; + Log(obj.symbolDetail.InstrumentName, "止损平仓", suffix); + obj.status.st++; + } else if (-spread > (IncSpace * obj.N)) { + opCode = obj.marketPosition > 0 ? 1 : 2; + } + if (opCode == 0 && records.length > obj.leavePeriod) { + obj.status.leavePrice = obj.marketPosition > 0 ? TA.Lowest(records, obj.leavePeriod, 'Low') : TA.Highest(records, obj.leavePeriod, 'High'); + if ((obj.marketPosition > 0 && lastPrice < obj.status.leavePrice) || + (obj.marketPosition < 0 && lastPrice > obj.status.leavePrice)) { + obj.preBreakoutFailure = false; + Log(obj.symbolDetail.InstrumentName, "正常平仓", suffix); + opCode = 3; + obj.status.cover++; + } + } + } + + if (opCode == 0) { + return; + } + if (opCode == 3) { + obj.setTask(ACT_COVER, 0, function(ret) { + obj.reset(); + _G(obj.symbol, null); + }); + return; + } + // Open + if (Math.abs(obj.marketPosition) >= obj.maxLots) { + obj.setLastError("禁止开仓, 超过最大持仓 " + obj.maxLots); + return; + } + var atrs = TA.ATR(records, atrLen); + var N = _N(atrs[atrs.length - 1], 4); + + var account = _bot.GetAccount(); + var currMargin = JSON.parse(exchange.GetRawJSON()).CurrMargin; + var unit = parseInt((account.Balance+currMargin-obj.keepBalance) * (obj.riskRatio / 100) / N / obj.symbolDetail.VolumeMultiple); + var canOpen = parseInt((account.Balance-obj.keepBalance) / (opCode == 1 ? obj.symbolDetail.LongMarginRatio : obj.symbolDetail.ShortMarginRatio) / (lastPrice * 1.2) / obj.symbolDetail.VolumeMultiple); + unit = Math.min(unit, canOpen); + if (unit < obj.symbolDetail.MinLimitOrderVolume) { + obj.setLastError("可开 " + unit + " 手 无法开仓, " + (canOpen >= obj.symbolDetail.MinLimitOrderVolume ? "风控触发" : "资金限制")); + return; + } + obj.setTask((opCode == 1 ? ACT_LONG : ACT_SHORT), unit, function(ret) { + if (!ret) { + obj.setLastError("下单失败"); + return; + } + Log(obj.symbolDetail.InstrumentName, obj.marketPosition == 0 ? "开仓" : "加仓", "离市周期", obj.leavePeriod, suffix); + obj.N = N; + obj.openPrice = ret.price; + obj.holdPrice = ret.position.Price; + if (obj.marketPosition == 0) { + obj.status.open++; + } + obj.holdAmount = ret.position.Amount; + obj.marketPosition += opCode == 1 ? 1 : -1; + obj.status.vm = [obj.marketPosition, obj.openPrice, N, obj.leavePeriod, obj.preBreakoutFailure]; + _G(obj.symbol, obj.status.vm); + }); + }; + var vm = null; + if (RMode === 0) { + vm = _G(obj.symbol); + } else { + vm = JSON.parse(VMStatus)[obj.symbol]; + } + if (vm) { + Log("准备恢复进度, 当前合约状态为", vm); + obj.reset(vm[0], vm[1], vm[2], vm[3], vm[4]); + } else { + if (needRestore) { + Log("没有找到" + obj.symbol + "的进度恢复信息"); + } + obj.reset(); + } + return obj; + } +}; + +function onexit() { + Log("已退出策略..."); +} + +function main() { + if (exchange.GetName().indexOf('CTP') == -1) { + throw "只支持商品期货CTP"; + } + SetErrorFilter("login|ready|流控|连接失败|初始|Timeout"); + var mode = exchange.IO("mode", 0); + if (typeof(mode) !== 'number') { + throw "切换模式失败, 请更新到最新托管者!"; + } + while (!exchange.IO("status")) { + Sleep(3000); + LogStatus("正在等待与交易服务器连接, " + new Date()); + } + var positions = _C(exchange.GetPosition); + if (positions.length > 0) { + Log("检测到当前持有仓位, 系统将开始尝试恢复进度..."); + Log("持仓信息", positions); + } + Log("风险系数:", RiskRatio, "N值周期:", ATRLength, "系统1: 入市周期", EnterPeriodA, "离市周期", LeavePeriodA, "系统二: 入市周期", EnterPeriodB, "离市周期", LeavePeriodB, "加仓系数:", IncSpace, "止损系数:", StopLossRatio, "单品种最多开仓:", MaxLots, "次"); + var initAccount = _bot.GetAccount(); + var initMargin = JSON.parse(exchange.GetRawJSON()).CurrMargin; + var keepBalance = _N((initAccount.Balance + initMargin) * (KeepRatio/100), 3); + Log("资产信息", initAccount, "保留资金:", keepBalance); + + var tts = []; + var filter = []; + var arr = Instruments.split(','); + for (var i = 0; i < arr.length; i++) { + var symbol = arr[i].replace(/^\s+/g, "").replace(/\s+$/g, ""); + if (typeof(filter[symbol]) !== 'undefined') { + Log(symbol, "已经存在, 系统已自动过滤"); + continue; + } + filter[symbol] = true; + var hasPosition = false; + for (var j = 0; j < positions.length; j++) { + if (positions[j].ContractType == symbol) { + hasPosition = true; + break; + } + } + var obj = TTManager.New(hasPosition, symbol, keepBalance, RiskRatio, ATRLength, EnterPeriodA, LeavePeriodA, EnterPeriodB, LeavePeriodB, UseEnterFilter, IncSpace, StopLossRatio, MaxLots); + tts.push(obj); + } + + + var preTotalHold = -1; + var lastStatus = ''; + while (true) { + if (GetCommand() === "暂停/继续") { + Log("暂停交易中..."); + while (GetCommand() !== "暂停/继续") { + Sleep(1000); + } + Log("继续交易中..."); + } + while (!exchange.IO("status")) { + Sleep(3000); + LogStatus("正在等待与交易服务器连接, " + new Date() + "\n" + lastStatus); + } + var tblStatus = { + type: "table", + title: "持仓信息", + cols: ["合约名称", "持仓方向", "持仓均价", "持仓数量", "持仓盈亏", "加仓次数", "开仓次数", "止损次数", "成功次数", "当前价格", "N"], + rows: [] + }; + var tblMarket = { + type: "table", + title: "运行状态", + cols: ["合约名称", "合约乘数", "保证金率", "交易时间", "柱线长度", "上线", "下线", "止损价", "离市价", "异常描述", "发生时间"], + rows: [] + }; + var totalHold = 0; + var vmStatus = {}; + var ts = new Date().getTime(); + var holdSymbol = 0; + for (var i = 0; i < tts.length; i++) { + tts[i].Poll(); + var d = tts[i].Status(); + if (d.holdAmount > 0) { + vmStatus[d.symbol] = d.vm; + holdSymbol++; + } + tblStatus.rows.push([d.symbolDetail.InstrumentName, d.holdAmount == 0 ? '--' : (d.marketPosition > 0 ? '多' : '空'), d.holdPrice, d.holdAmount, d.holdProfit, Math.abs(d.marketPosition), d.open, d.st, d.cover, d.lastPrice, d.N]); + tblMarket.rows.push([d.symbolDetail.InstrumentName, d.symbolDetail.VolumeMultiple, _N(d.symbolDetail.LongMarginRatio, 4) + '/' + _N(d.symbolDetail.ShortMarginRatio, 4), (d.isTrading ? '是#0000ff' : '否#ff0000'), d.recordsLen, d.upLine, d.downLine, d.stopPrice, d.leavePrice, d.lastErr, d.lastErrTime]); + totalHold += Math.abs(d.holdAmount); + } + var now = new Date(); + var elapsed = now.getTime() - ts; + var tblAssets = _bot.GetAccount(true); + var nowAccount = _bot.Account(); + + if (tblAssets.rows.length > 10) { + // replace AccountId + tblAssets.rows[0] = ["InitAccount", "初始资产", initAccount]; + } else { + tblAssets.rows.unshift(["NowAccount", "当前可用", nowAccount], ["InitAccount", "初始资产", initAccount]); + } + lastStatus = '`' + JSON.stringify([tblStatus, tblMarket, tblAssets]) + '`\n轮询耗时: ' + elapsed + ' 毫秒, 当前时间: ' + now.toLocaleString() + ', 星期' + ['日', '一', '二', '三', '四', '五', '六'][now.getDay()] + ", 持有品种个数: " + holdSymbol; + if (totalHold > 0) { + lastStatus += "\n手动恢复字符串: " + JSON.stringify(vmStatus); + } + LogStatus(lastStatus); + if (preTotalHold > 0 && totalHold == 0) { + LogProfit(nowAccount.Balance - initAccount.Balance - initMargin); + } + preTotalHold = totalHold; + Sleep(LoopInterval * 1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/130234 + +> 更新时间 + +2018-12-14 12:31:22 diff --git "a/Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210).md" "b/Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210)|Dual Thrust (MyLanguage version).md" similarity index 53% rename from "Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210).md" rename to "Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210)|Dual Thrust (MyLanguage version).md" index 47a57e99..ede513bc 100644 --- "a/Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210).md" +++ "b/Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210)|Dual Thrust (MyLanguage version).md" @@ -1,7 +1,7 @@ > 策略名称 -Dual Thrust (麦语言版) +Dual Thrust (麦语言版)|Dual Thrust (MyLanguage version) > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] > 基本原理 - 在当天收盘,计算两个值: 最高价-收盘价,和收盘价-最低价。然后取这两个值较大的那个,乘以k值,结果称为触发值。 @@ -31,15 +32,35 @@ littleDreamXX - 副图: 无 +|| + +- Fundamental: + At the close of the day, two values are calculated: the highest price - the closing price, and the closing price - the lowest price. Then take the larger one and multiply it by the value of k. The result is called the trigger value. + At the opening of the next day, record the opening price, then buy immediately when the price exceeds (opening price + trigger value), or sell short when the price is lower than (opening price - trigger value). + This system is a reversal system with no separate stop loss. In other words, the reverse signal is also the closing signal. + + ![IMG](https://www.fmz.com/upload/asset/d2d373289db613f356811d9314775b83.jpg) + ![IMG](https://www.fmz.com/upload/asset/c6c5a6c53fa4f0c9c5971df9349e1dca.png) + ![IMG](https://www.fmz.com/upload/asset/65fd01ff1e7b844006ba18ad0ea3dedf.png) + +- Main chart: + Upper track: formula: UPTRACK^^O+KSRG; + Lower track: formula: DOWNTRACK^^O-KXRG; + +- Secondary chart: + none + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|N|4|计算周期| -|KS|0.5|上轨系数| -|KX|0.5|下轨系数| +|N|4|计算周期|Period: calculate period| +|KS|0.5|上轨系数|upper track coefficient| +|KX|0.5|下轨系数|lower track coefficient| > 源码 (麦语言) @@ -62,10 +83,10 @@ RG:=MAX(HH-LC,HC-LL); UPTRACK^^O+KS*RG; DOWNTRACK^^O-KX*RG; -// 交易信号 + C>UPTRACK,BPK; C 策略出处 @@ -74,4 +95,4 @@ https://www.fmz.com/strategy/128884 > 更新时间 -2018-12-06 12:09:22 +2018-12-18 11:28:40 diff --git a/Dynamic Balance Strategy.md b/Dynamic Balance Strategy.md deleted file mode 100644 index 77b35080..00000000 --- a/Dynamic Balance Strategy.md +++ /dev/null @@ -1,106 +0,0 @@ - -> 策略名称 - -Dynamic Balance Strategy - -> 策略作者 - -ruby - - - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|threshold|0.05|threshold| -|ZPrecision|8|Price Precision| -|XPrecision|4|Amount Precision| -|MinStock|0.001|minimum buying amount| -|Interval|2000|error retry interval| -|LoopInterval|60|Polling Interval| - - -> 源码 (javascript) - -``` javascript -var InitAccount = null; - -function onTick(){ - var acc = _C(exchange.GetAccount); - var ticker = _C(exchange.GetTicker); - var spread = ticker.Sell - ticker.Buy; - var diffAsset = (acc.Balance - (acc.Stocks * ticker.Sell))/2; - var ratio = diffAsset / acc.Balance; - LogStatus('ratio:', ratio, _D()); - if(Math.abs(ratio) < threshold){ - return false; - } - if(ratio > 0){ - var buyPrice = _N(ticker.Sell + spread, ZPrecision); - var buyAmount = _N(diffAsset / buyPrice, XPrecision); - if(buyAmount < MinStock){ - return false; - } - exchange.Buy(buyPrice, buyAmount); - } else { - var sellPrice = _N(ticker.Buy - spread, ZPrecision); - var sellAmount = _N(-diffAsset / sellPrice, XPrecision); - if (sellAmount < MinStock) { - return false; - } - exchange.Sell(sellPrice, sellAmount, diffAsset, ratio); - } - return true; -} - -function CancelPendingOrders(){ - var ret = false; - while(true){ - var orders = null; - while(!(orders = exchange.GetOrders())){ - Sleep(Interval); - } - if(orders.length == 0){ - return ret; - } - for(var j = 0; j < orders.length; j++){ - exchange.CancelOrder(orders[j],Id); - ret = true; - if(j < (orders.length - 1)){ - Sleep(Interval); - - } - - } - - } - - } - - -function main() { - InitAccount = _C(exchange.GetAccount); - while(true){ - if(onTick()){ - Sleep(1000); - CancelPendingOrders(); - Log(_C(exchange.GetAccount)); - - } - Sleep(LoopInterval * 1000); - } - - -} -``` - -> 策略出处 - -https://www.fmz.com/strategy/110900 - -> 更新时间 - -2018-08-13 12:35:18 diff --git "a/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" "b/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" index dec13d32..1a9f44f0 100644 --- "a/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" +++ "b/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" @@ -49,18 +49,6 @@ period: 1h exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] *) -// MACD计算参数 已经添加到,策略参数 -// FASTLENGTH:=12; -// SLOWLENGTH:=26; -// MACDLENGTH:=9; - -// 均线长度 已经添加到,策略参数 -// L1:=50; -// L2:=120; - -// 止损5% 已经添加到,策略参数 -// STOPLOSS:=5; - //MACD MACDVALUE:=EMA(CLOSE,FASTLENGTH)-EMA(CLOSE,SLOWLENGTH); AVGMACD:=EMA(MACDVALUE,MACDLENGTH); @@ -96,4 +84,4 @@ https://www.fmz.com/strategy/128134 > 更新时间 -2018-12-05 11:48:12 +2018-12-18 15:30:12 diff --git a/README.md b/README.md index 5bb66dd1..f5c35de6 100644 --- a/README.md +++ b/README.md @@ -4,36 +4,42 @@ > 开源策略 - - [RUMI策略](https://www.fmz.com/strategy/129082) - - [日本云图简化版策略](https://www.fmz.com/strategy/129083) - - [高胜率ORB交易策略](https://www.fmz.com/strategy/129084) - - [麦语言海龟策略体验](https://www.fmz.com/strategy/126968) - - [升级版恒温器策略](https://www.fmz.com/strategy/129086) - - [Dual Thrust (麦语言版)](https://www.fmz.com/strategy/128884) - - [传统均线指标与KD指标的交易策略](https://www.fmz.com/strategy/128249) - - [双均线策略与相对强弱RSI指标组合](https://www.fmz.com/strategy/128250) - - [抛物线转向SAR与价格高低点策略](https://www.fmz.com/strategy/128251) - - [波动率ATR轨道突破策略](https://www.fmz.com/strategy/128252) - - [价格高低点与一目均线双重趋势策略](https://www.fmz.com/strategy/128415) - - [动向指数(DMI)与高低点策略](https://www.fmz.com/strategy/128418) + - [测试火币macd金叉](https://www.fmz.com/strategy/92839) + - [基于ATR波动率指标构建的通道策略|Channel strategy based on ATR volatility indicator](https://www.fmz.com/strategy/127691) + - [商品期货跟单系统](https://www.fmz.com/strategy/79351) + - [升级版恒温器策略|Upgraded Thermostat Strategy](https://www.fmz.com/strategy/129086) - [MACD+MA指标组合策略](https://www.fmz.com/strategy/128134) - - [双均线DDI策略](https://www.fmz.com/strategy/128133) - - [高低点突破成交量指数加权策略](https://www.fmz.com/strategy/128125) - - [标准差价格通道策略](https://www.fmz.com/strategy/128121) - - [基于ATR波动率指标构建的通道策略](https://www.fmz.com/strategy/128126) - - [三均线顺势价格突破策略](https://www.fmz.com/strategy/128130) - - [高低点与波动率ROC指标策略](https://www.fmz.com/strategy/128417) - - [瀑布线策略](https://www.fmz.com/strategy/128420) + - [基于ATR波动率指标构建的通道策略|Channel strategy based on ATR](https://www.fmz.com/strategy/128126) + - [三轨道波动率策略|Three-track Volatility Strategy](https://www.fmz.com/strategy/128129) + - [Dual Thrust (麦语言版)|Dual Thrust (MyLanguage version)](https://www.fmz.com/strategy/128884) + - [高胜率ORB交易策略|High Winning Rate - ORB Trading Strategy](https://www.fmz.com/strategy/129084) + - [混沌操作法策略|Trading Chaos Strategy](https://www.fmz.com/strategy/129077) + - [均线和高低点相对强弱策略|Relative Strength Strategy Based on Price](https://www.fmz.com/strategy/129078) + - [日本云图简化版策略|Simplified Version of ICHIMOKU KINKO HYO Strategy](https://www.fmz.com/strategy/129083) + - [双均线与形态策略|Double MA and Formation Strategy](https://www.fmz.com/strategy/129079) + - [RUMI策略|RUMI Strategy](https://www.fmz.com/strategy/129082) + - [瀑布线策略|PBX Strategy](https://www.fmz.com/strategy/128420) + - [动向指数(DMI)与高低点策略|DMI and High-Low Strategy](https://www.fmz.com/strategy/128418) + - [价格高低点与一目均线双重趋势策略|Price high and low - Ichimoku trend strategy](https://www.fmz.com/strategy/128415) + - [高低点与波动率ROC指标策略|Price high and low - ROC index strategy](https://www.fmz.com/strategy/128417) + - [波动率ATR轨道突破策略|Volatility ATR - Track Breakthrough Strategy](https://www.fmz.com/strategy/128252) + - [抛物线转向SAR与价格高低点策略|SAR and Price High and Low Strategy](https://www.fmz.com/strategy/128251) + - [三均线顺势价格突破策略|Three-MA Price Breakthrough Strategy](https://www.fmz.com/strategy/128130) + - [多级止盈趋势策略|Multilevel Take Profit Strategy](https://www.fmz.com/strategy/128122) + - [传统均线指标与KD指标的交易策略|Trading Strategy of Traditional MA Index and KD Index](https://www.fmz.com/strategy/128249) + - [双均线策略与相对强弱RSI指标组合|Combination of Double MA and RSI](https://www.fmz.com/strategy/128250) + - [开收盘均价差ATR策略|The average of difference - combined with ATR](https://www.fmz.com/strategy/128136) + - [双均线DDI策略|Double Average Lines -DDI Strategy](https://www.fmz.com/strategy/128133) + - [高低点突破成交量指数加权策略|Break High and Low - Volume Index Weighting Strategy](https://www.fmz.com/strategy/128125) + - [标准差价格通道策略|Standard deviation price channel strategy](https://www.fmz.com/strategy/128121) + - [CTP 期货](https://www.fmz.com/strategy/130234) + - [你不知道的MACD+MA指标组合策略|MACD+MA Indicator Combination Strategy](https://www.fmz.com/strategy/127101) + - [麦语言海龟策略体验](https://www.fmz.com/strategy/126968) - [Bitmex仓位变化推送微信(wss协议,需要bitmex api ID)|Bitmex position-change push(websocket)](https://www.fmz.com/strategy/128624) - - [开收盘均价差ATR策略](https://www.fmz.com/strategy/128136) - - [多级止盈趋势策略](https://www.fmz.com/strategy/128122) - - [三轨道波动率策略](https://www.fmz.com/strategy/128129) - - [基于ATR波动率指标构建的通道策略](https://www.fmz.com/strategy/127691) - [海龟](https://www.fmz.com/strategy/128382) - [OKEX期现对冲](https://www.fmz.com/strategy/127939) - [商品期货交易类库(旧版)](https://www.fmz.com/strategy/127341) - [现现对冲(搬砖)](https://www.fmz.com/strategy/127154) - - [你不知道的MACD+MA指标组合策略](https://www.fmz.com/strategy/127101) - [BitMEX 高级API功能 V.1.1.0 (期货:批量下单,编辑订单,冰山订单,一键撤单,定时撤单) Python2/3](https://www.fmz.com/strategy/114148) - [OkEX 高级API功能 V.1.1.0 (期货:批量下单,现货;TBD) Python2/3](https://www.fmz.com/strategy/113979) - [多交易所集合行情/下单 策略 范例](https://www.fmz.com/strategy/125569) @@ -78,7 +84,6 @@ - [50行多平台对冲策略(教学)](https://www.fmz.com/strategy/113278) - [Dual Thrust OKEX期货 (教学)](https://www.fmz.com/strategy/112425) - [[VNC] SVM Test](https://www.fmz.com/strategy/112188) - - [Dynamic Balance Strategy](https://www.fmz.com/strategy/110900) - [区块链量化投资系列课程(3) - 跨期套利](https://www.fmz.com/strategy/104964) - [区块链量化投资系列课程(4) - 动态平衡策略](https://www.fmz.com/strategy/110545) - [单平台均衡策略](https://www.fmz.com/strategy/345) @@ -87,7 +92,6 @@ - [画线类库|Plot library](https://www.fmz.com/strategy/27293) - [Iceberg Buy Order](https://www.fmz.com/strategy/103319) - [Dual Thrust OKEX Feature](https://www.fmz.com/strategy/103247) - - [商品期货跟单系统](https://www.fmz.com/strategy/79351) - [转换任意K线周期管理模板(最近更新20180627)](https://www.fmz.com/strategy/41163) - [检查https://quant.la/Argus/是否正常](https://www.fmz.com/strategy/100344) - [2014年的简易短线机器人](https://www.fmz.com/strategy/1088) diff --git "a/RUMI\347\255\226\347\225\245.md" "b/RUMI\347\255\226\347\225\245|RUMI Strategy.md" similarity index 62% rename from "RUMI\347\255\226\347\225\245.md" rename to "RUMI\347\255\226\347\225\245|RUMI Strategy.md" index 80173260..60858302 100644 --- "a/RUMI\347\255\226\347\225\245.md" +++ "b/RUMI\347\255\226\347\225\245|RUMI Strategy.md" @@ -1,7 +1,7 @@ > 策略名称 -RUMI策略 +RUMI策略|RUMI Strategy > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 策略名称:RUMI策略 - 适用周期:多周期 - 支持:商品期货、数字货币期货、数字货币现货 @@ -26,15 +27,31 @@ littleDreamXX - 副图: AOS指标,公式: AOS:MA(OS,N3); +|| + +- Strategy Name: RUMI Strategy +- Applicable cycle: multi-cycle +- Support: Commodity Futures, Digital Currency Futures, Digital Currency Spot + + ![IMG](https://www.fmz.com/upload/asset/d0d4ae5dd9629a8e2b52c821c63f8873.png) + ![IMG](https://www.fmz.com/upload/asset/2cd3d79c46dec610c116645b9a43ae80.png) + +- Main chart: + none +- Secondary chart: + AOS index, formula: AOS:MA(OS,N3); + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|N1|3|AOS指标参数1| -|N2|100|AOS指标参数2| -|N3|30|AOS指标参数3| +|N1|3|AOS指标参数1|AOS index parameter1| +|N2|100|AOS指标参数2|AOS index parameter2| +|N3|30|AOS指标参数3|AOS index parameter3| > 源码 (麦语言) @@ -63,4 +80,4 @@ https://www.fmz.com/strategy/129082 > 更新时间 -2018-12-07 11:36:11 +2018-12-17 18:19:15 diff --git "a/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245.md" "b/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245|Three-MA Price Breakthrough Strategy.md" similarity index 68% rename from "\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245.md" rename to "\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245|Three-MA Price Breakthrough Strategy.md" index e6fc5998..9c2d4b50 100644 --- "a/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245.md" +++ "b/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245|Three-MA Price Breakthrough Strategy.md" @@ -1,7 +1,7 @@ > 策略名称 -三均线顺势价格突破策略 +三均线顺势价格突破策略|Three-MA Price Breakthrough Strategy > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 公式名称:三均线顺势价格突破策略 - 数据周期:多周期 - 数据合约:指数合约 @@ -18,16 +19,27 @@ littleDreamXX ![IMG](https://www.fmz.com/upload/asset/4327c3e54a8618bb6f5b0ac3ea54dfc2.png) +|| + +- Data cycle: multiple cycles +- Data contract: index contract +- Trading contract: main contract +- Suitable for: commodity futures + + ![IMG](https://www.fmz.com/upload/asset/ed995f267589e43cdc0492a87952dcad.png) + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|SLOSS|2|止损百分比| -|N1|30|均线1参数| -|N2|60|均线2参数| -|N3|90|均线3参数| +|SLOSS|2|止损百分比|stop loss percentage| +|N1|30|均线1参数|MA1 parameter| +|N2|60|均线2参数|MA2 parameter| +|N3|90|均线3参数|MA3 parameter| > 源码 (麦语言) @@ -54,14 +66,15 @@ SELLP:=BKVOL>0 AND CROSS(MA2,C) AND MA1>C AND C>=BKPRICE*(1+2*SLOSS*0.01); BUYK,BK(LOTS); SELLK,SK(LOTS); -//止盈 +// 止盈 +// take profit BUYP,BP(SKVOL); SELLP,SP(BKVOL); -//止损 +// 止损 +// stop loss C>=SKPRICE*(1+SLOSS*0.01),BP(SKVOL); C<=BKPRICE*(1-SLOSS*0.01),SP(BKVOL); -//TRADE_OTHER('AUTO'); ``` > 策略出处 @@ -70,4 +83,4 @@ https://www.fmz.com/strategy/128130 > 更新时间 -2018-12-04 22:11:09 +2018-12-17 12:23:47 diff --git "a/\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245.md" "b/\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245.md" deleted file mode 100644 index 3e6e3caf..00000000 --- "a/\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245.md" +++ /dev/null @@ -1,89 +0,0 @@ - -> 策略名称 - -三轨道波动率策略 - -> 策略作者 - -littleDreamXX - -> 策略描述 - -- K线走完下单:收盘价开仓、平仓 -- 数据合约:螺纹指数,郑煤指数,热卷指数,铁矿指数,焦炭指数,棕榈指数,橡胶指数,郑醇指数,PP指数,沪铜指数; -- 交易合约:螺纹主连,郑煤主连,热卷主连,铁矿主连,焦炭主连,棕榈主连,橡胶主连,郑醇主连,PP主连,沪铜主连; -- 数据级别:日K线; - -![IMG](https://www.fmz.com/upload/asset/785c3a0e4e8c164bc831b05dcdc355a3.png) - -- 主图指标显示: - MIDTR^^MA(C,CN); // 确定MIDTR - UPTR^^MIDTR+2*STD(C,CN); // 确定UPTR - DOWNTR^^MIDTR-2*STD(C,CN); // 确定DOWNTR - HPOINT^^HV(H,CN),DOT,COLORRED; // 计算前一周期CN周期内最高价的最大值。 - LPOINT^^LV(L,CN),DOT,COLORBLUE; // 计算前一周期CN周期内最低价的最小值。 - -- 副图: - 无 - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|AMOUNT|true|单仓| -|N|20|标准差周期数| -|MINN|20|CN最小值| -|MAXN|60|CN最大值| -|STOPRANGE|50|止损幅度| - - -> 源码 (麦语言) - -``` pascal -(*backtest -start: 2017-07-01 00:00:00 -end: 2018-11-30 00:00:00 -period: 1d -exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] -*) - -// 确定CN -VOLAT:=STD(C,N); // VOLAT(波动率):M周期收盘价的标准差 -VOLATCHANGE:=(VOLAT-REF(VOLAT,1))/VOLAT; // 2个VOLAT的变化率 -N1:=(1+VOLATCHANGE)*MINN; // VOLATCHANGE : 波动率变化 -N2:=INTPART(N1); // 取整 -N3:=MIN(N2,MAXN); // 确认CN不大于60 -CN:=MAX(N3,MINN); // 确认CN不小于20 - -MIDTR^^MA(C,CN); // 确定MIDTR -UPTR^^MIDTR+2*STD(C,CN); // 确定UPTR -DOWNTR^^MIDTR-2*STD(C,CN); // 确定DOWNTR -HPOINT^^HV(H,CN),DOT,COLORRED; // 计算前一周期CN周期内最高价的最大值。 -LPOINT^^LV(L,CN),DOT,COLORBLUE; // 计算前一周期CN周期内最低价的最小值。 - -// 开仓 -L<=LPOINT AND LMINN,SK(AMOUNT); // 当最低价小于DOWNTR和低点,且K线位置大于60,收盘价卖开 -H>=HPOINT AND H>UPTR AND BARPOS>MINN,BK(AMOUNT); // 当最高价大于UPTR和高点,且K线位置大于60,收盘价买开 - -// 启动止损 -C>=SKPRICE*(1+STOPRANGE*0.001),BP(SKVOL); -C<=BKPRICE*(1-STOPRANGE*0.001),SP(BKVOL); - -// 平仓 -CMIDTR,BP(SKVOL); // 当收盘价大于MIDTR,收盘价买平 - -// 动态止损 -REF(BKHIGH,1)>BKPRICE*(1+2*0.001*STOPRANGE) AND CLV(C,BARSSK)*(1+STOPRANGE*0.001),BP(SKVOL); // 卖开后最低价小于卖开价*(1-2*0.001*STOPRANGE),且收盘价大于卖开后最低收盘价*(1+STOPRANGE*0.001),收盘价买平 -``` - -> 策略出处 - -https://www.fmz.com/strategy/128129 - -> 更新时间 - -2018-12-03 09:52:12 diff --git "a/\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245|Three-track Volatility Strategy.md" "b/\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245|Three-track Volatility Strategy.md" new file mode 100644 index 00000000..b3b8d59e --- /dev/null +++ "b/\344\270\211\350\275\250\351\201\223\346\263\242\345\212\250\347\216\207\347\255\226\347\225\245|Three-track Volatility Strategy.md" @@ -0,0 +1,131 @@ + +> 策略名称 + +三轨道波动率策略|Three-track Volatility Strategy + +> 策略作者 + +littleDreamXX + +> 策略描述 + +[trans] +- K线走完下单:收盘价开仓、平仓 +- 数据级别:日K线; + +![IMG](https://www.fmz.com/upload/asset/785c3a0e4e8c164bc831b05dcdc355a3.png) + +- 主图指标显示: + MIDTR^^MA(C,CN); // 确定MIDTR + UPTR^^MIDTR+2*STD(C,CN); // 确定UPTR + DOWNTR^^MIDTR-2*STD(C,CN); // 确定DOWNTR + HPOINT^^HV(H,CN),DOT,COLORRED; // 计算前一周期CN周期内最高价的最大值。 + LPOINT^^LV(L,CN),DOT,COLORBLUE; // 计算前一周期CN周期内最低价的最小值。 + +- 副图: + 无 + +|| + +- Place order after K line is done, open or close position when closing price is determined +- Data Level: Daily K Line + + ![IMG](https://www.fmz.com/upload/asset/3a476a37c7f7a6939aab1d1ad7164e72.png) + ![IMG](https://www.fmz.com/upload/asset/63c9bc0e146e9a3164e78055b0154be7.png) + +- Main chart: + MIDTR^^MA(C,CN); // Determine MIDTR + UPTR^^MIDTR+2STD(C,CN); // Determine UPTR + DOWNTR^^MIDTR-2STD(C,CN); // Determine DOWNTR + HPOINT^^HV(H,CN), DOT, COLORRED; + // Calculate the maximum value of the highest price in the CN cycle of the previous cycle. + LPOINT^^LV(L,CN), DOT, COLORBLUE; + // Calculate the minimum value of the lowest price in the CN cycle of the previous cycle. + +- Secondary chart: + none + +[/trans] + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|AMOUNT|true|单仓|single order opening amount| +|N|20|标准差周期数|cycles of standard deviation| +|MINN|20|CN最小值|minimum of CN| +|MAXN|60|CN最大值|maximum of CN| +|STOPRANGE|50|止损幅度|stop loss range| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2017-07-01 00:00:00 +end: 2018-11-30 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_BitMEX","currency":"XBT_USD"}] +args: [["AMOUNT",1000],["TradeAmount",1000,126961],["ContractType","XBTUSD",126961]] +*) + +// 确定CN +// Determine CN +VOLAT:=STD(C,N); // VOLAT(波动率):M周期收盘价的标准差 + // VOLAT(volatility): Standard deviation of closing price in M-cycle +VOLATCHANGE:=(VOLAT-REF(VOLAT,1))/VOLAT; // 2个VOLAT的变化率 + // Change rate of two VOLATs +N1:=(1+VOLATCHANGE)*MINN; // VOLATCHANGE : 波动率变化 + // VOLATCHANGE : Volatility change +N2:=INTPART(N1); // 取整 + // Rounding off an integer +N3:=MIN(N2,MAXN); // 确认CN不大于60 + // Confirm that CN is no more than 60 +CN:=MAX(N3,MINN); // 确认CN不小于20 + // Confirm that CN is no less than 20 +MIDTR^^MA(C,CN); // 确定MIDTR + // Determine MIDTR +UPTR^^MIDTR+2*STD(C,CN); // 确定UPTR + // Determine UPTR +DOWNTR^^MIDTR-2*STD(C,CN); // 确定DOWNTR + // Determine DOWNTR +HPOINT^^HV(H,CN),DOT,COLORRED; // 计算前一周期CN周期内最高价的最大值。 + // see main chart +LPOINT^^LV(L,CN),DOT,COLORBLUE; // 计算前一周期CN周期内最低价的最小值。 + // see main chart + +// 开仓 +// open position +L<=LPOINT AND LMINN,SK(AMOUNT); // 当最低价小于DOWNTR和低点,且K线位置大于60,收盘价卖开 + // when the lowest price < the lowest point and DOWNTR,and the K-line position > 60, sell short the closing price +H>=HPOINT AND H>UPTR AND BARPOS>MINN,BK(AMOUNT); // 当最高价大于UPTR和高点,且K线位置大于60,收盘价买开 + // when the highest price > UPTR and the highest point, and the K-line position > 60, buy long the closing price +// 启动止损 +// start stop loss +C>=SKPRICE*(1+STOPRANGE*0.001),BP(SKVOL); +C<=BKPRICE*(1-STOPRANGE*0.001),SP(BKVOL); + +// 平仓 +// close position +CMIDTR,BP(SKVOL); // 当收盘价大于MIDTR,收盘价买平 + // when closing price > MIDTR, buy to cover the closing price + +// 动态止损 +// Dynamic stop loss +REF(BKHIGH,1)>BKPRICE*(1+2*0.001*STOPRANGE) AND C buy long price*(1+2*0.001*STOPRANGE), and closing price < the highest closing price after buying long*(1-STOPRANGE*0.001), then sell closing price +REF(SKLOW,1)LV(C,BARSSK)*(1+STOPRANGE*0.001),BP(SKVOL); // 卖开后最低价小于卖开价*(1-2*0.001*STOPRANGE),且收盘价大于卖开后最低收盘价*(1+STOPRANGE*0.001),收盘价买平 + // the lowest price after sellong short < sell short price *(1-2*0.001*STOPRANGE), and closing price > the lowest closing price after selling short*(1+STOPRANGE*0.001), then buy to cover closing price +``` + +> 策略出处 + +https://www.fmz.com/strategy/128129 + +> 更新时间 + +2018-12-18 12:21:38 diff --git "a/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245.md" "b/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245|Price high and low - Ichimoku trend strategy.md" similarity index 55% rename from "\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245.md" rename to "\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245|Price high and low - Ichimoku trend strategy.md" index 5e42d13f..ce797f13 100644 --- "a/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245.md" +++ "b/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245|Price high and low - Ichimoku trend strategy.md" @@ -1,7 +1,7 @@ > 策略名称 -价格高低点与一目均线双重趋势策略 +价格高低点与一目均线双重趋势策略|Price high and low - Ichimoku trend strategy > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 策略名称:价格高低点与一目均线双重趋势策略 - 数据周期:15M等 - 支持:商品期货 @@ -22,15 +23,31 @@ littleDreamXX LINE2指标线,公式:LINE2^^(HHV(H,N2)+LLV(L,N2))*0.5; +|| + +- Strategy Name: Price high and low - Ichimoku trend strategy +- Data cycle: 15M, etc. +- Support: Commodity Futures + + ![IMG](https://www.fmz.com/upload/asset/5988d1b7eb989f7a2e345fba35201cc9.png) + ![IMG](https://www.fmz.com/upload/asset/a0c6881a0bac6f2c89ffe8fc137be941.png) + ![IMG](https://www.fmz.com/upload/asset/227a3bb45cd8ab1bf54e64cdda96650b.png) + +- main chart: + LINE1 index line,formula:LINE1^^(HHV(H,N1)+LLV(L,N1))*0.5; + LINE2 index line,formula:LINE2^^(HHV(H,N2)+LLV(L,N2))*0.5; + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|N1|150|高点低点均值1周期| -|N2|500|高点低点均值2周期| -|SLOSS|2|止损百分比| +|N1|150|高点低点均值1周期|the highest of high price N1 ago/ the lowest of low price N1 ago| +|N2|500|高点低点均值2周期|the highest of high price N2 ago/ the lowest of low price N2 ago| +|SLOSS|2|止损百分比|stop loss percentage| > 源码 (麦语言) @@ -64,4 +81,4 @@ https://www.fmz.com/strategy/128415 > 更新时间 -2018-12-05 16:59:14 +2018-12-17 17:16:35 diff --git "a/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" deleted file mode 100644 index 2cb2b75b..00000000 --- "a/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" +++ /dev/null @@ -1,73 +0,0 @@ - -> 策略名称 - -传统均线指标与KD指标的交易策略 - -> 策略作者 - -littleDreamXX - -> 策略描述 - -- 策略名称:传统均线指标与KD指标的交易策略 -- 数据周期:15M,30M等 -- 支持:商品期货 -- 指标使用了EMA,KD线,其中KD线使用的是默认参数(指标参数固定3,3,9) -- 官方网站:www.quant.la - -![IMG](https://www.fmz.com/upload/asset/f842e44b0b8451cb562b8d5bd888e4c0.png) - -- 主图 - EMA均线,公式:MAC^^EMA(C,N); - - -- 副图 - - KD线中的K线,公式:K:SMA(RSV,M1,1);//RSV的移动平均值 - KD线中的D线,公式:D:SMA(K,M2,1);//K的移动平均值 - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|SLOSS|2|止损百分比| -|N|120|EMA参数| - - -> 源码 (麦语言) - -``` pascal -(*backtest -start: 2018-04-01 00:00:00 -end: 2018-05-15 00:00:00 -period: 30m -exchanges: [{"eid":"Futures_BitMEX","currency":"XBT_USD"}] -args: [["TradeAmount",100,126961],["ContractType","XBTUSD",126961]] -*) - -MAC^^EMA(C,N); - -NKD:=9; -M1:=3; -M2:=3; -RSV:=(CLOSE-LLV(LOW,NKD))/(HHV(HIGH,NKD)-LLV(LOW,NKD))*100;//收盘价与NKD周期最低值做差,NKD周期最高值与NKD周期最低值做差,两差之间做比值。 -K:SMA(RSV,M1,1);//RSV的移动平均值 -D:SMA(K,M2,1);//K的移动平均值 - -BARPOS>N AND C>MAC AND KN AND CD,SK; -C<=BKPRICE*(1-SLOSS*0.01),SP(BKVOL); -C>=SKPRICE*(1+SLOSS*0.01),BP(SKVOL); -C>=BKPRICE*(1+SLOSS*0.01) AND CMAC,BP(SKVOL); -``` - -> 策略出处 - -https://www.fmz.com/strategy/128249 - -> 更新时间 - -2018-12-05 18:34:08 diff --git "a/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245|Trading Strategy of Traditional MA Index and KD Index.md" "b/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245|Trading Strategy of Traditional MA Index and KD Index.md" new file mode 100644 index 00000000..87421702 --- /dev/null +++ "b/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245|Trading Strategy of Traditional MA Index and KD Index.md" @@ -0,0 +1,98 @@ + +> 策略名称 + +传统均线指标与KD指标的交易策略|Trading Strategy of Traditional MA Index and KD Index + +> 策略作者 + +littleDreamXX + +> 策略描述 + +[trans] +- 策略名称:传统均线指标与KD指标的交易策略 +- 数据周期:15M,30M等 +- 支持:商品期货 +- 指标使用了EMA,KD线,其中KD线使用的是默认参数(指标参数固定3,3,9) +- 官方网站:www.quant.la + +![IMG](https://www.fmz.com/upload/asset/f842e44b0b8451cb562b8d5bd888e4c0.png) + +- 主图 + EMA均线,公式:MAC^^EMA(C,N); + + +- 副图 + + KD线中的K线,公式:K:SMA(RSV,M1,1);//RSV的移动平均值 + KD线中的D线,公式:D:SMA(K,M2,1);//K的移动平均值 + +|| + +- Data Cycle: 15M, 30M, etc. +- Support: Commodity Futures +- Indicators are EMA, KD lines, and KD line use default parameters (index parameters fixed 3, 3, 9) + + ![IMG](https://www.fmz.com/upload/asset/320fafa2ce5d6f68a4260a028783580d.png) + ![IMG](https://www.fmz.com/upload/asset/6753142c9c078ad25e9c913e82c0d999.png) + +- Main chart: + EMA mean, formula: MAC ^^ EMA (C, N); + +- Secondary chart: + K line in KD, formula: K: SMA (RSV, M1, 1); //RSV moving average + D line in KD, formula: D: SMA (K, M2, 1); //K moving average value + +[/trans] + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|SLOSS|2|止损百分比|stop loss percentage| +|N|120|EMA参数|EMA parameter| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-04-01 00:00:00 +end: 2018-05-15 00:00:00 +period: 30m +exchanges: [{"eid":"Futures_BitMEX","currency":"XBT_USD"}] +args: [["TradeAmount",100,126961],["ContractType","XBTUSD",126961]] +*) + +MAC^^EMA(C,N); + +NKD:=9; +M1:=3; +M2:=3; +RSV:=(CLOSE-LLV(LOW,NKD))/(HHV(HIGH,NKD)-LLV(LOW,NKD))*100; //收盘价与NKD周期最低值做差,NKD周期最高值与NKD周期最低值做差,两差之间做比值。 +// (1)closing price minus the lowest value in NKD cycle, +// (2)the highest value in NKD cycle minus the lowest value in NKD cycle, then (1) divided by (2). + +K:SMA(RSV,M1,1); // RSV的移动平均值 + // MA of RSV + +D:SMA(K,M2,1); // K的移动平均值 + // MA of K + +BARPOS>N AND C>MAC AND KN AND CD,SK; +C<=BKPRICE*(1-SLOSS*0.01),SP(BKVOL); +C>=SKPRICE*(1+SLOSS*0.01),BP(SKVOL); +C>=BKPRICE*(1+SLOSS*0.01) AND CMAC,BP(SKVOL); +``` + +> 策略出处 + +https://www.fmz.com/strategy/128249 + +> 更新时间 + +2018-12-15 16:06:00 diff --git "a/\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" "b/\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" deleted file mode 100644 index 712f4095..00000000 --- "a/\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" +++ /dev/null @@ -1,79 +0,0 @@ - -> 策略名称 - -你不知道的MACD+MA指标组合策略 - -> 策略作者 - -Zero - -> 策略描述 - -本期分享MACD+MA指标组合策略,在技术分析中,指标的组合使用是非常常见的,不同的指标组合在一起具有不同的操作要点和分析方法,指标的组合使用可以增强信号的准确性。该策略正是通过比较价格与MA的相互关系,再以MACD指标衡量价格运动加速度,来判断市场所处的状态,构建一种简单的择时交易策略。 - - - -> 源码 (麦语言) - -``` pascal -(*backtest -start: 2018-11-01 00:00:00 -end: 2018-11-22 00:00:00 -period: 1h -exchanges: [{"eid":"OKCoin_EN","currency":"BTC_USD"}] -*) - -// 公式名称:MACD+MA指标组合策略 -// 数据周期:4小时 -// 适合品种:商品期货/数字货币现货/数字货币期货 - -// MACD计算参数 -FASTLENGTH:=12; -SLOWLENGTH:=26; -MACDLENGTH:=9; - -// 均线长度 -L1:=50; -L2:=120; - -// 止损5% -STOPLOSS:=5; - -//MACD -MACDVALUE:=EMA(CLOSE,FASTLENGTH)-EMA(CLOSE,SLOWLENGTH); -AVGMACD:=EMA(MACDVALUE,MACDLENGTH); -MACDDIFF:=MACDVALUE-AVGMACD; - -//MA1、MA2 -DMA1:=MA(C,L1); -DMA2:=MA(C,L2); -买入开仓价:=VALUEWHEN(BARSBK=1,O); -卖出开仓价:=VALUEWHEN(BARSSK=1,O); -BUYCONDITION:=MACDVALUE>0 && DMA1>DMA2 && MACDDIFF>0 && C>DMA1 && REF(C,1)>REF(DMA1,1); -SELLCONDITION:=MACDVALUE<0 && DMA10 AND (REF(MACDVALUE,1)<0 OR REF(DMA1,1)0 AND (REF(MACDVALUE,1)>0 OR REF(DMA1,1)>REF(DMA2,1)),BP; - -// 启动止损 -SKVOL>0 AND HIGH>=卖出开仓价*(1+STOPLOSS*0.01),BP; -SETSIGPRICETYPE(BP,MAX(O,卖出开仓价*(1+STOPLOSS*0.01))); -BKVOL>0 AND LOW<=买入开仓价*(1-STOPLOSS*0.01),SP; -SETSIGPRICETYPE(SP,MIN(O,买入开仓价*(1-STOPLOSS*0.01))); -AUTOFILTER; -``` - -> 策略出处 - -https://www.fmz.com/strategy/127101 - -> 更新时间 - -2018-11-22 22:47:00 diff --git "a/\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245|MACD+MA Indicator Combination Strategy.md" "b/\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245|MACD+MA Indicator Combination Strategy.md" new file mode 100644 index 00000000..a4ef6bad --- /dev/null +++ "b/\344\275\240\344\270\215\347\237\245\351\201\223\347\232\204MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245|MACD+MA Indicator Combination Strategy.md" @@ -0,0 +1,79 @@ + +> 策略名称 + +你不知道的MACD+MA指标组合策略|MACD+MA Indicator Combination Strategy + +> 策略作者 + +Zero + +> 策略描述 + +[trans] +本期分享MACD+MA指标组合策略,在技术分析中,指标的组合使用是非常常见的,不同的指标组合在一起具有不同的操作要点和分析方法,指标的组合使用可以增强信号的准确性。该策略正是通过比较价格与MA的相互关系,再以MACD指标衡量价格运动加速度,来判断市场所处的状态,构建一种简单的择时交易策略。 +|| +The MA indicator is short for English(Moving average) and is called the moving average indicator. The moving average(MA) has a trending characteristic, which is relatively stable, unlike the day K line that will rise and fall. The longer the moving average, the more stable the performance. Not easily up and down, you must wait for the true clarity of the stock price trend. The moving average is, in the final analysis, a trend-tracking tool that makes it easy to identify whether a trend has ended or reversed and whether a new trend is emerging. + +In this issue, we share the MACD+MA index combination strategy. In the technical analysis, the combination of indicators is very common. Different indicators have different operation points and analysis methods. The combination of indicators can enhance the accuracy of the signal. The strategy is to compare the relationship between price and MA, and then measure the price movement acceleration by MACD index to judge the state of the market and construct a simple timing trading strategy. + +[/trans] + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-11-01 00:00:00 +end: 2018-11-22 00:00:00 +period: 1h +exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] +*) + + +// MACD calculation +FASTLENGTH:=12; +SLOWLENGTH:=26; +MACDLENGTH:=9; + +// Length of MA +L1:=50; +L2:=120; + +// stop loss 止损 5% +STOPLOSS:=5; + +//MACD +MACDVALUE:=EMA(CLOSE,FASTLENGTH)-EMA(CLOSE,SLOWLENGTH); +AVGMACD:=EMA(MACDVALUE,MACDLENGTH); +MACDDIFF:=MACDVALUE-AVGMACD; + +//MA1、MA2 +DMA1:=MA(C,L1); +DMA2:=MA(C,L2); +BUYCONDITION:=MACDVALUE>0 && DMA1>DMA2 && MACDDIFF>0 && C>DMA1 && REF(C,1)>REF(DMA1,1); +SELLCONDITION:=MACDVALUE<0 && DMA10 AND (REF(MACDVALUE,1)<0 OR REF(DMA1,1)0 AND (REF(MACDVALUE,1)>0 OR REF(DMA1,1)>REF(DMA2,1)),BP; + +// 启动止损 Start stop loss +SKVOL>0 AND HIGH>=SKPRICE*(1+STOPLOSS*0.01),BP; +BKVOL>0 AND LOW<=BKPRICE*(1-STOPLOSS*0.01),SP; +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/127101 + +> 更新时间 + +2018-12-14 10:25:27 diff --git "a/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" "b/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|DMI and High-Low Strategy.md" similarity index 60% rename from "\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" rename to "\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|DMI and High-Low Strategy.md" index 2c70018e..5613c28c 100644 --- "a/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" +++ "b/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|DMI and High-Low Strategy.md" @@ -1,7 +1,7 @@ > 策略名称 -动向指数(DMI)与高低点策略 +动向指数(DMI)与高低点策略|DMI and High-Low Strategy > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 策略名称:动向指数(DMI)与高低点策略 - 数据周期:5M - 支持:商品期货 @@ -23,18 +24,33 @@ littleDreamXX AMA2指标,公式:AMA2^^EMA(DMA(CLOSE,CQ2),2); +|| + +- Strategy Name: DMI and High-Low Strategy +- Data Cycle: 5M +- Support: Commodity Futures + + ![IMG](https://www.fmz.com/upload/asset/e373cde011ba569f143e399a6f51528d.png) + ![IMG](https://www.fmz.com/upload/asset/9c51e404853a232c50c6ef12bb809e7d.png) + +- Main chart: + AMA1 index, formula: AMA1 ^ ^ EMA (DMA (CLOSE, CQ1), 2); + AMA2 index, formula: AMA2 ^ ^ EMA (DMA (CLOSE, CQ2), 2); + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|N|20|AMA1指标参数(1)| -|N1|4|AMA1指标参数(2)| -|N2|60|AMA1指标参数(3)| -|M|40|AMA2指标参数(1)| -|M1|8|AMA2指标参数(2)| -|M2|120|AMA2指标参数(3)| +|N|20|AMA1指标参数(1)|AMA1 index parameter(1)| +|N1|4|AMA1指标参数(2)|AMA1 index parameter(2)| +|N2|60|AMA1指标参数(3)|AMA1 index parameter(3)| +|M|40|AMA2指标参数(1)|AMA2 index parameter(1)| +|M1|8|AMA2指标参数(2)|AMA2 index parameter(2)| +|M2|120|AMA2指标参数(3)|AMA2 index parameter(3)| > 源码 (麦语言) @@ -76,4 +92,4 @@ https://www.fmz.com/strategy/128418 > 更新时间 -2018-12-05 12:38:58 +2018-12-17 17:40:05 diff --git "a/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" "b/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" deleted file mode 100644 index f57b431a..00000000 --- "a/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" +++ /dev/null @@ -1,108 +0,0 @@ - -> 策略名称 - -升级版恒温器策略 - -> 策略作者 - -littleDreamXX - -> 策略描述 - -- 策略名称:升级版恒温器策略 -- 数据周期:1H -- 支持:商品期货 -- 官方网站:WWW.QUANT.LA - - ![IMG](https://www.fmz.com/upload/asset/bcf664987bac1aaff72110b1e3679d10.png) - -- 主图: - 上轨,公式:TOP^^MAC+N_TMP*TMP;//布林通道上轨 - 下轨,公式:BOTTOM^^MAC-N_TMP*TMP;//布林通道下轨 - -- 副图: - CMI,公式 : CMI:ABS(C-REF(C,N_CMI-1))/(HHV(H,N_CMI)-LLV(L,N_CMI))*100;//0-100 取值越大,说明趋势越强,CMI<20震荡模式,CMI>20为趋势 - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|STOPLOSS|true|止损价格百分比| -|N|50|布林线指标参数1| -|N_TMP|2|布林线指标参数2| - - -> 源码 (麦语言) - -``` pascal -(*backtest -start: 2018-11-06 00:00:00 -end: 2018-12-04 00:00:00 -period: 1h -exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] -*) - -MAC:=MA(CLOSE,N); -TMP:=STD(CLOSE,N); -TOP^^MAC+N_TMP*TMP;//布林通道上轨 -BOTTOM^^MAC-N_TMP*TMP;//布林通道下轨 -BBOLL:=C>MAC; -SBOLL:=C20为趋势 - -N_KD:=9; -M1:=3; -M2:=3; -RSV:=(CLOSE-LLV(LOW,N_KD))/(HHV(HIGH,N_KD)-LLV(LOW,N_KD))*100;//收盘价与N周期最低值做差,N周期最高值与N周期最低值做差,两差之间做比值。 -K:=SMA(RSV,M1,1);//RSV的移动平均值 -D:=SMA(K,M2,1);//K的移动平均值 -MIND:=30; -BKD:=K>D AND D100-MIND; - -//震荡模式 -BUYPK1:=CMI < 20 AND BKD;//震荡多单买平开 -SELLPK1:=CMI < 20 AND SKD;//震荡空单卖平开 - -//趋势模式下原有震荡持仓的处理 -SELLY1:=REF(CMI,BARSBK) < 20 AND C>BKPRICE*(1+0.01*STOPLOSS*3) AND KD;//震荡空单止盈 - -//趋势模式 -BUYPK2:=CMI >= 20 AND C > TOP;//趋势多单买平开 -SELLPK2:=CMI >= 20 AND C < BOTTOM;//趋势空单卖平开 - -//趋势模式下原有震荡持仓的处理 -SELLY2:=REF(CMI,BARSBK) >= 20 AND C>BKPRICE*(1+0.01*STOPLOSS*3) AND SBOLL;//趋势多单止盈 -BUYY2:=REF(CMI,BARSSK) >= 20 AND C= 20 AND C= 20 AND C>SKPRICE*(1+0.01*STOPLOSS) AND BBOLL;//趋势空单止损 - -IF BARPOS>N THEN BEGIN - BUYPK1,BPK; - SELLPK1,SPK; - BUYPK2,BPK; - SELLPK2,SPK; -END -BUYY1,BP(SKVOL); -BUYY2,BP(SKVOL); -BUYS2,BP(SKVOL); -SELLY1,SP(BKVOL); -SELLY2,SP(BKVOL); -SELLS2,SP(BKVOL); - - -``` - -> 策略出处 - -https://www.fmz.com/strategy/129086 - -> 更新时间 - -2018-12-06 13:39:54 diff --git "a/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245|Upgraded Thermostat Strategy.md" "b/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245|Upgraded Thermostat Strategy.md" new file mode 100644 index 00000000..270f8235 --- /dev/null +++ "b/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245|Upgraded Thermostat Strategy.md" @@ -0,0 +1,148 @@ + +> 策略名称 + +升级版恒温器策略|Upgraded Thermostat Strategy + +> 策略作者 + +littleDreamXX + +> 策略描述 + +[trans] +- 策略名称:升级版恒温器策略 +- 数据周期:1H +- 支持:商品期货、数字货币期货、数字货币现货 +- 官方网站:WWW.QUANT.LA + + ![IMG](https://www.fmz.com/upload/asset/bcf664987bac1aaff72110b1e3679d10.png) + +- 主图: + 上轨,公式:TOP^^MAC+N_TMP*TMP;//布林通道上轨 + 下轨,公式:BOTTOM^^MAC-N_TMP*TMP;//布林通道下轨 + +- 副图: + CMI,公式 : CMI:ABS(C-REF(C,N_CMI-1))/(HHV(H,N_CMI)-LLV(L,N_CMI))*100;//0-100 取值越大,说明趋势越强,CMI<20震荡模式,CMI>20为趋势 + +|| + +- Strategy Name: Upgraded Thermostat Strategy +- Data cycle: 1H +- Support: Commodity Futures, Digital Currency Futures, Digital Currency Spot + + ![IMG](https://www.fmz.com/upload/asset/0e0a008b14ac42a86128e2b86c3b990a.png) + ![IMG](https://www.fmz.com/upload/asset/925a0c3eae66fb4e6f2e94b9c775a90f.png) + +- Main chart: + upper track, formula: TOP^^MAC+N_TMPTMP; / / upper track of boll + lower track, formula: BOTTOM^^MAC-N_TMPTMP;//lower track of boll + +- Secondary chart: + CMI, formula: CMI: ABS(C-REF(C,N_CMI-1))/(HHV(H,N_CMI)-LLV(L,N_CMI))*100; + //0-100 the larger the value, the stronger the trend, CMI <20 is oscillation, CMI>20 is trend + +[/trans] + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|STOPLOSS|true|止损价格百分比|stop loss price percentage| +|N|50|布林线指标参数1|boll index parameter 1| +|N_TMP|2|布林线指标参数2|boll index parameter 2| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-11-06 00:00:00 +end: 2018-12-04 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +*) + +MAC:=MA(CLOSE,N); +TMP:=STD(CLOSE,N); +TOP^^MAC+N_TMP*TMP; // 布林通道上轨 + // upper track of ball +BOTTOM^^MAC-N_TMP*TMP; // 布林通道下轨 + // lower track of ball +BBOLL:=C>MAC; +SBOLL:=C20为趋势 + // 0-100 the larger the value, the stronger the trend, CMI <20 is oscillation mode, CMI>20 is the trend + +N_KD:=9; +M1:=3; +M2:=3; +RSV:=(CLOSE-LLV(LOW,N_KD))/(HHV(HIGH,N_KD)-LLV(LOW,N_KD))*100; // 收盘价与N周期最低值做差,N周期最高值与N周期最低值做差,两差之间做比值。 + // (1)closing price - the lowest of cycle N, (2)the highest of cycle N - the lowest of cycle N, (1)/(2) +K:=SMA(RSV,M1,1); // RSV的移动平均值 + // MA of RSV +D:=SMA(K,M2,1); // K的移动平均值 + // MA of K +MIND:=30; +BKD:=K>D AND D100-MIND; + +// 震荡模式 +// oscillation mode +BUYPK1:=CMI < 20 AND BKD; // 震荡多单买平开 + // if it's oscillation, buy to cover and buy long immediately +SELLPK1:=CMI < 20 AND SKD; // 震荡空单卖平开 + // if it's oscillation, sell to close long position and sell short to open position immediately + +// 趋势模式下原有震荡持仓的处理 +// Disposal of the original oscillating position under the trend mode +SELLY1:=REF(CMI,BARSBK) < 20 AND C>BKPRICE*(1+0.01*STOPLOSS*3) AND KD; // 震荡空单止盈 + // if it's oscillation, short position take profit + +// 趋势模式 +// trend mode +BUYPK2:=CMI >= 20 AND C > TOP; // 趋势多单买平开 + // if it's trend, buy to cover and buy long immediately +SELLPK2:=CMI >= 20 AND C < BOTTOM; // 趋势空单卖平开 + // if it's trend, sell to close long position and sell short to open position immediately + +// 趋势模式下原有震荡持仓的处理 +// Disposal of the original oscillating position under the trend mode +SELLY2:=REF(CMI,BARSBK) >= 20 AND C>BKPRICE*(1+0.01*STOPLOSS*3) AND SBOLL; // 趋势多单止盈 + // if it's trend, long position take profit +BUYY2:=REF(CMI,BARSSK) >= 20 AND C= 20 AND C= 20 AND C>SKPRICE*(1+0.01*STOPLOSS) AND BBOLL; // 趋势空单止损 + // if it's trend, short position stop loss + +IF BARPOS>N THEN BEGIN + BUYPK1,BPK; + SELLPK1,SPK; + BUYPK2,BPK; + SELLPK2,SPK; +END +BUYY1,BP(SKVOL); +BUYY2,BP(SKVOL); +BUYS2,BP(SKVOL); +SELLY1,SP(BKVOL); +SELLY2,SP(BKVOL); +SELLS2,SP(BKVOL); + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/129086 + +> 更新时间 + +2018-12-18 15:48:27 diff --git "a/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245.md" "b/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245|Double Average Lines -DDI Strategy.md" similarity index 61% rename from "\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245.md" rename to "\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245|Double Average Lines -DDI Strategy.md" index c7d1ec0b..c9bae90c 100644 --- "a/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245.md" +++ "b/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245|Double Average Lines -DDI Strategy.md" @@ -1,7 +1,7 @@ > 策略名称 -双均线DDI策略 +双均线DDI策略|Double Average Lines -DDI Strategy > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 策略思路:双均线确定方向,用DDI指标,确定进场时点,比例止损和回撤止盈 - 数据周期:15M - 数据合约:指数合约 @@ -27,29 +28,51 @@ littleDreamXX ![IMG](https://www.fmz.com/upload/asset/e83641b0567b242687792b105de8e211.png) +|| + +- Strategy idea: Use double average lines to determine the direction; +- use the DDI indicator to determine when to open position; + - proportional to determine the stop loss and take profit + + - Data cycle: 15M + + ![IMG](https://www.fmz.com/upload/asset/09e140c314c2cd3829cb03f89f502ac6.png) + + ![IMG](https://www.fmz.com/upload/asset/5a2ed54d056607b1432ae31cb5c0903d.png) + + - Main chart: + VAR2^^MA(C, PARAM2); + VAR3^^MA(VAR2, PARAM1); + +- Secondary chart: + VAR9: MA (VAR8, 2*PARAM1); + VAR10: MA (VAR9, PARAM1); + VAR8: VAR6-VAR7; + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|PARAM1|60|均线2的参数| -|PARAM2|300|均线1的参数| -|PARAM3|true|价格系数| +|PARAM1|60|均线2的参数|parameter of average line 2| +|PARAM2|300|均线1的参数|parameter of average line 1| +|PARAM3|true|价格系数|price coefficient| > 源码 (麦语言) ``` pascal (*backtest -start: 2017-01-01 00:00:00 -end: 2017-02-20 00:00:00 +start: 2018-11-01 00:00:00 +end: 2018-12-14 00:00:00 period: 15m -exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","balance":20000}] +exchanges: [{"eid":"Futures_BitMEX","currency":"XBT_USD"}] +args: [["TradeAmount",100,126961],["ContractType","XBTUSD",126961]] *) -VAR1:=MAX(1,INTPART(MONEYTOT/(O*UNIT*0.1))); - VAR2^^MA(C,PARAM2); VAR3^^MA(VAR2,PARAM1); @@ -70,21 +93,14 @@ BUYY:=C>VAR2 AND CSKPRICE*(1+PARAM3*0.01); -BKVOL=0 AND BUYK,BK(VAR1); -SKVOL=0 AND SELLK,SK(VAR1); +BKVOL=0 AND BUYK,BK; +SKVOL=0 AND SELLK,SK; SELLS,SP(BKVOL); BUYS,BP(SKVOL); SELLY,SP(BKVOL); BUYY,BP(SKVOL); - -// DRAWCOLORKLINE(BKVOL=0 AND SKVOL=0,COLORWHITE,0); -// DRAWCOLORKLINE(SKVOL>0,COLORGREEN,0); -// DRAWCOLORKLINE(BKVOL>0,COLORRED,0); -// 累计盈亏..OFFSETPROFIT1,COLORWHITE,BOLD; -// PROFITSUM..OFFSETPROFIT1,COLORWHITE,BOLD; -//TRVAR10E_OTHER('AUTO'); ``` > 策略出处 @@ -93,4 +109,4 @@ https://www.fmz.com/strategy/128133 > 更新时间 -2018-12-05 11:47:14 +2018-12-15 15:43:04 diff --git "a/\345\217\214\345\235\207\347\272\277\344\270\216\345\275\242\346\200\201\347\255\226\347\225\245|Double MA and Formation Strategy.md" "b/\345\217\214\345\235\207\347\272\277\344\270\216\345\275\242\346\200\201\347\255\226\347\225\245|Double MA and Formation Strategy.md" new file mode 100644 index 00000000..7132782e --- /dev/null +++ "b/\345\217\214\345\235\207\347\272\277\344\270\216\345\275\242\346\200\201\347\255\226\347\225\245|Double MA and Formation Strategy.md" @@ -0,0 +1,98 @@ + +> 策略名称 + +双均线与形态策略|Double MA and Formation Strategy + +> 策略作者 + +littleDreamXX + +> 策略描述 + +[trans] +- 策略名称:双均线与形态策略 +- 数据周期:15M +- 支持:商品期货,数字货币,数字货币期货 +- 官方网站:WWW.QUANT.LA + + ![IMG](https://www.fmz.com/upload/asset/cf5ac5fdf4f33ed438ed4498e1a7b142.png) + +- 主图: + MA指标,公式: VAR3^^MA(VAR2,PARAM1); + EMA指标,公式:VAR4^^EMA(VAR3,PARAM2); + +- 副图: + 无 + +|| + +- Strategy Name: Double MA and Formation Strategy +- Support: Commodity Futures, Digital Currency Spot, Digital Currency Futures +- Data cycle: 15M + + ![IMG](https://www.fmz.com/upload/asset/a11b6dffb660edef84c785a9d1d88f87.png) + ![IMG](https://www.fmz.com/upload/asset/c2498b876b57cce1e887fa052ac8a298.png) + +- Main chart: + MA index, formula: VAR3 ^^ MA (VAR2, PARAM1); + EMA index, formula: VAR4 ^ ^ EMA (VAR3, PARAM2); +- Secondary chart: + none + +[/trans] + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|PARAM1|200|MA指标参数|MA index parameter| +|PARAM2|10|EMA指标参数|EMA index parameter| +|PARAM3|true|止盈止损百分比|take profit percentage and stop loss percentage| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-05-02 00:00:00 +end: 2018-06-21 00:00:00 +period: 15m +exchanges: [{"eid":"Futures_BitMEX","currency":"XBT_USD"}] +args: [["TradeAmount",1000,126961],["SlideTick",10,126961],["ContractType","XBTUSD",126961]] +*) + +DIRECTION:=0; // 方向控制 + // Direction control + +VAR2:=(HIGH+LOW+CLOSE)/3; +VAR3^^MA(VAR2,PARAM1); +VAR4^^EMA(VAR3,PARAM2); +BOOL1:=CLOSE>REF(C,1) AND HIGH>REF(HIGH,1) AND CLOSE>OPEN; +BOOL2:=CLOSEPARAM1 AND CLOSE>VAR3 AND BOOL1 AND VAR3>VAR4; +SELLPK:=BARPOS>PARAM1 AND CLOSEBKPRICE AND BUYPK; +SELLJ:=CLOSESKPRICE*(1+PARAM3*0.01); + +BKVOL=0 AND BUYPK AND DIRECTION>=0,BPK; +SKVOL=0 AND SELLPK AND DIRECTION<=0,SPK; +BKVOL>0 AND BUYJ,BK; +SKVOL>0 AND SELLJ,SK; +SELLS,SP; +BUYS,BP; +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/129079 + +> 更新时间 + +2018-12-17 18:31:58 diff --git "a/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210.md" "b/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210|Combination of Double MA and RSI.md" similarity index 66% rename from "\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210.md" rename to "\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210|Combination of Double MA and RSI.md" index de16fbb5..ddcdb3ea 100644 --- "a/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210.md" +++ "b/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210|Combination of Double MA and RSI.md" @@ -1,7 +1,7 @@ > 策略名称 -双均线策略与相对强弱RSI指标组合 +双均线策略与相对强弱RSI指标组合|Combination of Double MA and RSI > 策略作者 @@ -9,6 +9,8 @@ littleDreamXX > 策略描述 +[trans] + - 策略名称:双均线策略与相对强弱RSI指标组合 - 数据周期:15M,30M等 - 支持:商品期货 @@ -23,15 +25,35 @@ littleDreamXX - 副图: RSI,公式:RSIVALUE:SMA(MAX(CLOSE-REF(CLOSE,1),0),LENGTH,1)/SMA(ABS(CLOSE-REF(CLOSE,1)),LENGTH,1)*100; +|| + +- Strategy Name: Combination of Double MA and RSI +- Data Cycle: 15M, 30M, etc. +- Support: Commodity Futures + + ![IMG](https://www.fmz.com/upload/asset/3115dab65deb2ed7d795cdabb32d88be.png) + ![IMG](https://www.fmz.com/upload/asset/1a352942b56f16cddab02f1692c909f2.png) + +- Main chart: + MA 1, formula: MA1 ^^ EMA (C, N1); + MA 2, formula: MA2 ^^ EMA (C, N2); + +- Secondary chart: + RSI, formula: + RSIVALUE:SMA(MAX(CLOSE-REF(CLOSE,1),0),LENGTH,1)/SMA(ABS(CLOSE-REF(CLOSE,1)),LENGTH,1)*100; + + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|SLOSS|true|止损百分比| -|N1|50|均线1参数| -|N2|300|均线2参数| +|SLOSS|true|止损百分比|Stop Loss Percentage| +|N1|50|均线1参数|MA1 parameter| +|N2|300|均线2参数|MA2 parameter| > 源码 (麦语言) @@ -73,4 +95,4 @@ https://www.fmz.com/strategy/128250 > 更新时间 -2018-12-05 18:20:59 +2018-12-15 15:44:22 diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" index 3cae1a53..b53e8b05 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" @@ -16,126 +16,107 @@ Hukybo ``` javascript var arr = []; -//下单 +//下单函数 function trade(symbol, type, unit) { - var acc = _C(exchanges[0].GetAccount).Balance; //主账户 + symbol = symbol.substring(0, symbol.length - 1); + var acc = _C(exchanges[0].GetAccount).Info.Balance; for (var i = 1; i < exchanges.length; i++) { - var ac = _C(exchanges[i].GetAccount).Balance; //子账户 - var dw = Math.floor(unit / (acc / ac)); //按资金比例下单 + var ac = _C(exchanges[i].GetAccount).Info.Balance; + var dws = unit / (acc / ac); + var dw; + if (type == "buy" || type == "sell") { + dw = Math.floor(dws); + } else { + dw = Math.round(dws); + } if (dw < 1) { Log(i, ' 号账户资金不足'); continue; } - var mp = _C(exchanges[i].GetPosition); //子持仓 - var npm = $.NewPositionManager(exchanges[i]); - if (type == 11) { - npm.OpenLong(symbol, dw); - Log(i, ' 号账户:', symbol, ':多开:', dw, ' 张'); - } else if (type == -11) { - npm.OpenShort(symbol, dw); - Log(i, ' 号账户:', symbol, ':空开:', dw, ' 张'); - } else if (type == 10 || type == -10) { - for (var v = 0; v < mp.length; v++) { - if (mp[v].ContractType == symbol) { - npm.Cover(symbol, dw); - if (type == 10) { - Log(i, ' 号账户:', symbol, ':多平:', dw, ' 张'); - } else { - Log(i, ' 号账户:', symbol, ':空平:', dw, ' 张'); - } - } - } - } else if (type == 100 || type == -100) { - for (var k = 0; k < mp.length; k++) { - if (mp[k].ContractType == symbol) { - npm.Cover(symbol, mp[k].Amount); - Log(i, ' 号账户:', symbol, ':全平'); - } - } + var ntq = $.NewTaskQueue(); + ntq.pushTask(exchanges[i], symbol, type, unit, function(task, ret) { + Log(i, ' 号账户 @ ', task.desc, "手, 成交价格:", ret.price); + }); + while (ntq.tasks.length > 0) { + ntq.poll(); } } } -//匹配 -function Comparison(arr) { +//匹配函数 +function comparison(arr) { + for (var y in arr[0]) { + if (!arr[1][y]) { + if (arr[0][y].Type == "多") { + trade(y, "closebuy", arr[0][y].Amount); + } else if (arr[0][y].Type == "空") { + trade(y, "closesell", arr[0][y].Amount); + } + } + } for (var x in arr[1]) { if (arr[0][x]) { - if (arr[1][x].Type == arr[0][x].Type) { - if (arr[1][x].Amount - arr[0][x].Amount > 0) { - if (arr[1][x].Type == "多") { - trade(x, 11, arr[1][x].Amount - arr[0][x].Amount); //多头加仓 - } else if (arr[1][x].Type == "空") { - trade(x, -11, arr[1][x].Amount - arr[0][x].Amount); //空头加仓 - } - } else if (arr[1][x].Amount - arr[0][x].Amount < 0) { - if (arr[1][x].Type == "多") { - trade(x, 10, arr[0][x].Amount - arr[1][x].Amount); //多头减仓 - } else if (arr[1][x].Type == "空") { - trade(x, -10, arr[0][x].Amount - arr[1][x].Amount); //空头减仓 - } + if (arr[1][x].Amount - arr[0][x].Amount === 0) { + continue; + } else if (arr[1][x].Amount - arr[0][x].Amount > 0) { + if (arr[1][x].Type == "多") { + trade(x, "buy", arr[1][x].Amount - arr[0][x].Amount); + } else if (arr[1][x].Type == "空") { + trade(x, "sell", arr[1][x].Amount - arr[0][x].Amount); } - } else { + } else if (arr[1][x].Amount - arr[0][x].Amount < 0) { if (arr[1][x].Type == "多") { - trade(x, -100, arr[0][x].Amount); - trade(x, 11, arr[1][x].Amount); //空头反手为多头 + trade(x, "closebuy", arr[0][x].Amount - arr[1][x].Amount); } else if (arr[1][x].Type == "空") { - trade(x, 100, arr[0][x].Amount); - trade(x, -11, arr[1][x].Amount); //多头反手为空头 + trade(x, "closesell", arr[0][x].Amount - arr[1][x].Amount); } } } else { if (arr[1][x].Type == "多") { - trade(x, 11, arr[1][x].Amount); //多开 + trade(x, "buy", arr[1][x].Amount); } else if (arr[1][x].Type == "空") { - trade(x, -11, arr[1][x].Amount); //空开 - } - } - } - for (var y in arr[0]) { - if (!arr[1][y]) { - if (arr[0][y].Type == "多") { - trade(y, 100, arr[0][y].Amount); //多平 - } else if (arr[0][y].Type == "空") { - trade(y, -100, arr[0][y].Amount); //空平 + trade(x, "sell", arr[1][x].Amount); } } } } -//数据处理 +//数据处理函数 function data() { var mp = _C(exchanges[0].GetPosition); var allDic = {}; - for (var v = 0; v < mp.length; v++) { - var name = mp[v].ContractType; - allDic[name] = {}; - allDic[name]["Amount"] = mp[v].Amount; - var bs = ""; - if (mp[v].Type == 0 || mp[v].Type == 2) { - bs = "多" - } else { - bs = "空" + for (var i = 0; i < mp.length; i++) { + var bs, name; + if (mp[i].Type == 0 || mp[i].Type == 2) { + bs = "多"; + name = mp[i].ContractType + bs; + } else if (mp[i].Type == 1 || mp[i].Type == 3) { + bs = "空"; + name = mp[i].ContractType + bs; } + allDic[name] = {}; + allDic[name]["Amount"] = mp[i].Amount; allDic[name]["Type"] = bs; } arr.push(allDic); if (arr.length > 2) { arr.shift(); - Comparison(arr); + comparison(arr); } } +// 主函数 function main() { for (var i = 0; i < exchanges.length; i++) { if (exchanges[i].GetName() !== 'Futures_CTP') { - throw '只支持 CTP !请检查第 ' + i + ' 个账户' + throw '只支持 CTP !请检查第 ' + i + ' 个账户'; } } SetErrorFilter("not login|ready|初始化"); while (true) { if (exchanges[0].IO("status")) { data(); - LogStatus("开盘时间,与交易服务器连接成功。") + LogStatus("与交易服务器连接成功"); } else { LogStatus("\n警告! 与交易服务器连接断开", "#DF0101", "\n", "\n未登录状态或该交易所已经闭市。", "#DF0101"); } @@ -150,4 +131,4 @@ https://www.fmz.com/strategy/79351 > 更新时间 -2018-07-02 20:59:56 +2018-12-20 14:35:11 diff --git "a/\345\235\207\347\272\277\345\222\214\351\253\230\344\275\216\347\202\271\347\233\270\345\257\271\345\274\272\345\274\261\347\255\226\347\225\245|Relative Strength Strategy Based on Price.md" "b/\345\235\207\347\272\277\345\222\214\351\253\230\344\275\216\347\202\271\347\233\270\345\257\271\345\274\272\345\274\261\347\255\226\347\225\245|Relative Strength Strategy Based on Price.md" new file mode 100644 index 00000000..f1d027fa --- /dev/null +++ "b/\345\235\207\347\272\277\345\222\214\351\253\230\344\275\216\347\202\271\347\233\270\345\257\271\345\274\272\345\274\261\347\255\226\347\225\245|Relative Strength Strategy Based on Price.md" @@ -0,0 +1,96 @@ + +> 策略名称 + +均线和高低点相对强弱策略|Relative Strength Strategy Based on Price + +> 策略作者 + +littleDreamXX + +> 策略描述 + +[trans] +- 策略名称:基于价格相对强的弱策略 +- 数据周期:1H +- 支持:商品期货、数字货币、数字货币期货 +- 官方网站:www.quant.la + + + ![IMG](https://www.fmz.com/upload/asset/2e346e6e3b2edda65576ffe7d35e104b.png) + + + +- 主图: + 均线,公式: MAN^^MA(C,N); + + +- 副图: + 无 + +|| + +- Strategy Name: Relative Strength Strategy Based on Price +- Data cycle: 1H +- Support: Commodity Futures, Digital Currency and Digital Currency Futures + + ![IMG](https://www.fmz.com/upload/asset/45096a9dbc8e6361219bd4957494ac60.png) + ![IMG](https://www.fmz.com/upload/asset/bcf5916794bbc6d9e5e8332b6fa9798c.png) + +- Main chart: + MA, formula: MAN^^MA(C,N); +- Secondary chart: + none + +[/trans] + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N|100|均线指标参数|MA index parameter| +|M|2|止损差价系数|stop loss difference coefficient| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-02-01 00:00:00 +end: 2018-04-27 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["ContractType","rb888",126961]] +*) + +MAN^^MA(C,N); +B_MA:=C>MAN; +S_MA:=C0.5; +B_K1:=SUM((C-L)*V,N)/SUM((H-L)*V,N)>0.5; + +CO:=IF(C>O,C-O,0); +OC:=IF(C0.5; +B_K2:=SUM(CO*V,N)/SUM(ABS(C-O)*V,N)>0.5; + +B_K1 AND B_K2 AND B_MA AND H>=HHV(H,N),BPK; +S_K1 AND S_K2 AND S_MA AND L<=LLV(L,N),SPK; + +STOPLOSS:=M*MA(H-L,N); +CSKPRICE+STOPLOSS,BP(SKVOL); + +S_MA AND BKHIGH>BKPRICE+STOPLOSS,SP(BKVOL); +B_MA AND SKLOW 策略出处 + +https://www.fmz.com/strategy/129078 + +> 更新时间 + +2018-12-18 10:25:23 diff --git "a/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245.md" "b/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245.md" deleted file mode 100644 index e6e4c5f1..00000000 --- "a/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245.md" +++ /dev/null @@ -1,56 +0,0 @@ - -> 策略名称 - -基于ATR波动率指标构建的通道策略 - -> 策略作者 - -Zero - -> 策略描述 - -思路:通道自适应策略,固定止损+浮动止盈 -适用软件:发明者最最化/文华财经 -数据周期:多周期 -数据合约:指数合约 -交易合约:商品期货/数字货币 - - - -> 源码 (麦语言) - -``` pascal -(*backtest -start: 2018-11-01 00:00:00 -end: 2018-12-01 00:00:00 -period: 1h -exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}] -args: [["ContractType","this_week",126961]] -*) - -SLOSS:=2; -N:=200; -M:=4; -X:UNIT; -TR1:=MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW)); -ATR:=MA(TR1,N); -MAC:=MA(C,N); -UBAND:=MAC+M*ATR; -DBAND:=MAC-M*ATR; -H>=HHV(H,N),BPK; -L<=LLV(L,N),SPK; -(H>=HHV(H,M*N) OR C<=UBAND) AND BKHIGH>=BKPRICE*(1+M*SLOSS*0.01),SP; -(L<=LLV(L,M*N) OR C>=DBAND) AND SKLOW<=SKPRICE*(1-M*SLOSS*0.01),BP; -//止损 -C>=SKPRICE*(1+SLOSS*0.01),BP; -C<=BKPRICE*(1-SLOSS*0.01),SP; -AUTOFILTER; -``` - -> 策略出处 - -https://www.fmz.com/strategy/127691 - -> 更新时间 - -2018-12-01 15:13:23 diff --git "a/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245|Channel strategy based on ATR volatility indicator.md" "b/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245|Channel strategy based on ATR volatility indicator.md" new file mode 100644 index 00000000..dc7b7b66 --- /dev/null +++ "b/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245|Channel strategy based on ATR volatility indicator.md" @@ -0,0 +1,76 @@ + +> 策略名称 + +基于ATR波动率指标构建的通道策略|Channel strategy based on ATR volatility indicator + +> 策略作者 + +Zero + +> 策略描述 + +[trans] +思路:通道自适应策略,固定止损+浮动止盈 +适用软件:发明者最最化/文华财经 +数据周期:多周期 +数据合约:指数合约 +交易合约:商品期货/数字货币 +|| +ATR, also known as Average true range, was invented by J. Welles Wilder. The ATR indicator is mainly used to measure the intensity of market volatility, that is, the indicator to show the market change rate. + +This indicator is mainly used to measure price fluctuations. + It is important to remember that ATR does not provide an indication of price direction, just volatility. + +This indicator is typical for long periods of sustained marginal movement, which usually occurs at the top of the market or during price consolidation. The principle of prediction according to this indicator can be expressed as: the higher the value of the indicator, the higher the possibility of the trend change; the lower the value of the indicator, the weaker the mobility of the trend. + +Idea: channel adaptive strategy, fixed stop loss + floating take profit + +Applicable software: FMZ Quant / webstock + +Data cycle: multiple cycles + +Data contract: index contract + +Trading Contract: Commodity Futures /Digital Currency +[/trans] + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-11-01 00:00:00 +end: 2018-12-01 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_BitMEX","currency":"XBT_USD"}] +args: [["ContractType","XBTUSD",126961]] +*) + +SLOSS:=2; +N:=200; +M:=4; +TR1:=MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW)); +ATR:=MA(TR1,N); +MAC:=MA(C,N); +UBAND^^MAC+M*ATR; +DBAND^^MAC-M*ATR; +NH^^HHV(H,N); +NL^^LLV(L,N); +H>=NH,BPK; +L<=NL,SPK; +(H>=HHV(H,M*N) OR C<=UBAND) AND BKHIGH>=BKPRICE*(1+M*SLOSS*0.01),SP; +(L<=LLV(L,M*N) OR C>=DBAND) AND SKLOW<=SKPRICE*(1-M*SLOSS*0.01),BP; +//止损 StopLoss +C>=SKPRICE*(1+SLOSS*0.01),BP; +C<=BKPRICE*(1-SLOSS*0.01),SP; +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/127691 + +> 更新时间 + +2018-12-21 16:13:58 diff --git "a/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245|Channel strategy based on ATR.md" "b/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245|Channel strategy based on ATR.md" new file mode 100644 index 00000000..8685f8b0 --- /dev/null +++ "b/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245|Channel strategy based on ATR.md" @@ -0,0 +1,91 @@ + +> 策略名称 + +基于ATR波动率指标构建的通道策略|Channel strategy based on ATR + +> 策略作者 + +littleDreamXX + +> 策略描述 + +[trans] +- 名称: 基于ATR波动率指标构建的通道策略 +- 思路:通道自适应策略,固定止损+浮动止盈 +- 数据周期:多周期 +- OKEX期货 +- 合约 : this_week 当周 +- 官方网站:www.quant.la + +![IMG](https://www.fmz.com/upload/asset/b2ebaacbe7dbb1bb45bb59ceb80dd37f.png) + +- 主图: + 画UBAND, 公式:UBAND^^MAC+M*ATR; + 画DBAND, 公式:DBAND^^MAC-M*ATR; + +- 副图: + 无 + +|| + +- Strategy name: Channel strategy based on ATR volatility index +- Strategy idea: Channel Adaptive Strategy, Fixed Stop + Floating Stop +- Data Cycle: Multi-Cycle + + ![IMG](https://www.fmz.com/upload/asset/24c0c7b896060cf639540b56028e8d99.png) + ![IMG](https://www.fmz.com/upload/asset/e403406e31b9a3ca04da6ce76e3abe2d.png) + +- Main chart: + Draw UBAND, formula: UBAND ^^ MAC + MATR; + Draw DBAND, formula: DBAND ^^ MAC-MATR; + +- Secondary chart: + none + +[/trans] + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|SLOSS|2|止损百分比|stop loss percentage| +|N|200|ATR指标参数|ATR index parameter| +|M|4|上下轨系数|upper and lower track coefficients| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-06-01 00:00:00 +end: 2018-07-01 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}] +args: [["TradeAmount",10,126961],["ContractType","this_week",126961]] +*) + +TR1:=MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW)); +ATR:=MA(TR1,N); +MAC:=MA(C,N); +UBAND^^MAC+M*ATR; +DBAND^^MAC-M*ATR; +H>=HHV(H,N),BPK; +L<=LLV(L,N),SPK; +(H>=HHV(H,M*N) OR C<=UBAND) AND BKHIGH>=BKPRICE*(1+M*SLOSS*0.01),SP; +(L<=LLV(L,M*N) OR C>=DBAND) AND SKLOW<=SKPRICE*(1-M*SLOSS*0.01),BP; +// 止损 +// stop loss +C>=SKPRICE*(1+SLOSS*0.01),BP; +C<=BKPRICE*(1-SLOSS*0.01),SP; +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/128126 + +> 更新时间 + +2018-12-18 12:55:34 diff --git "a/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245.md" "b/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245.md" deleted file mode 100644 index 5c3aaa12..00000000 --- "a/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245.md" +++ /dev/null @@ -1,110 +0,0 @@ - -> 策略名称 - -多级止盈趋势策略 - -> 策略作者 - -littleDreamXX - -> 策略描述 - -- 策略名称: 多级止盈趋势策略 -- 数据周期:多周期 -- 支持:商品期货、数字货币 -- 官方网站:www.quant.la - -![IMG](https://www.fmz.com/upload/asset/b8d89a704605b72bc44a56575a570bf6.png) - -- 主图: - 上线,公式 :UPPERLINE^^今开+BAND; - 下线,公式 :LOWERLINE^^今开-BAND; - 均线,公式 :均线^^MA(CLOSE,LENGTH); - -- 副图: - 无 - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|LENGTH|200|均线指标参数| -|STOPRANGE|3|止损幅度| - - -> 源码 (麦语言) - -``` pascal -(*backtest -start: 2018-01-01 00:00:00 -end: 2018-04-09 00:00:00 -period: 1d -exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] -args: [["LENGTH",80]] -*) - -STARTPER1:=5; //1级跟踪止盈,盈利5%启动 -STOPPER1:=100; //1级跟踪止盈,盈利回撤100%触发 -STARTPER2:=10; //2级跟踪止盈,盈利10%启动 -STOPPER2:=50; //2级跟踪止盈,盈利回撤50%触发 -STARTPER3:=20; //3级跟踪止盈,盈利20%启动 -STOPPER3:=20; //3级跟踪止盈,盈利回撤20%触发 - -//上下区间 -NN:=BARSLAST(DATE<>REF(DATE,1))+1;//今天开盘到目前为止的周期数 -今开:=VALUEWHEN(NN=1,O);//当天的开盘价 -今高:=HHV(H,NN);//今天全天的最高价 -今低:=LLV(L,NN);//今天全天的最低价 -昨高:=REF(今高,NN);//昨天全天的最高价 -昨低:=REF(今低,NN);//昨天全天的最低价 - -BAND:=昨高-昨低; -UPPERLINE^^今开+BAND; -LOWERLINE^^今开-BAND; - -//均线 -均线^^MA(CLOSE,LENGTH); - -//开平仓条件 -卖开条件: = CUPPERLINE AND UPPERLINE>均线; -买平空单: = C>UPPERLINE OR C>均线; -卖平多单: = C=SKLOW+(SKPRICE-SKLOW)*0.01*STOPPER3,BP;//最大盈利达到"STARTPER3"%之后盈利回撤"STOPPER3"%,平空 -BKHIGH>=BKPRICE*(1+0.01*STARTPER3) AND LOW<=BKHIGH-(BKHIGH-BKPRICE)*0.01*STOPPER3,SP;//最大盈利达到"STARTPER3"%之后盈利回撤"STOPPER3"%,平多 -SKLOW<=SKPRICE*(1-0.01*STARTPER2) AND HIGH>=SKLOW+(SKPRICE-SKLOW)*0.01*STOPPER2,BP;//最大盈利达到"STARTPER2"%之后盈利回撤"STOPPER2"%,平空 -BKHIGH>=BKPRICE*(1+0.01*STARTPER2) AND LOW<=BKHIGH-(BKHIGH-BKPRICE)*0.01*STOPPER2,SP;//最大盈利达到"STARTPER2"%之后盈利回撤"STOPPER2"%,平多 -SKLOW<=SKPRICE*(1-0.01*STARTPER1) AND HIGH>=SKLOW+(SKPRICE-SKLOW)*0.01*STOPPER1,BP;//最大盈利达到"STARTPER1"%之后盈利回撤"STOPPER1"%,平空 -BKHIGH>=BKPRICE*(1+0.01*STARTPER1) AND LOW<=BKHIGH-(BKHIGH-BKPRICE)*0.01*STOPPER1,SP;//最大盈利达到"STARTPER1"%之后盈利回撤"STOPPER1"%,平多 - -//止损 -C>=SKPRICE*(1+STOPRANGE*0.01),BP;//空头止损 -C<=BKPRICE*(1-STOPRANGE*0.01),SP;//多头止损 - -SETSIGPRICETYPE(BK,NEW_ORDER); -SETSIGPRICETYPE(SK,NEW_ORDER); -SETSIGPRICETYPE(BP,NEW_ORDER); -SETSIGPRICETYPE(SP,NEW_ORDER); - -AUTOFILTER; -``` - -> 策略出处 - -https://www.fmz.com/strategy/128122 - -> 更新时间 - -2018-12-03 11:41:22 diff --git "a/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245|Multilevel Take Profit Strategy.md" "b/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245|Multilevel Take Profit Strategy.md" new file mode 100644 index 00000000..002fd810 --- /dev/null +++ "b/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245|Multilevel Take Profit Strategy.md" @@ -0,0 +1,157 @@ + +> 策略名称 + +多级止盈趋势策略|Multilevel Take Profit Strategy + +> 策略作者 + +littleDreamXX + +> 策略描述 + +[trans] + +- 策略名称: 多级止盈趋势策略 +- 数据周期:多周期 +- 支持:商品期货、数字货币 +- 官方网站:www.quant.la + + ![IMG](https://www.fmz.com/upload/asset/b8d89a704605b72bc44a56575a570bf6.png) + +- 主图: + 上线,公式 :UPPERLINE^^今开+BAND; + 下线,公式 :LOWERLINE^^今开-BAND; + 均线,公式 :均线^^MA(CLOSE,LENGTH); + +- 副图: + 无 + +|| + +- Strategy Name: Multilevel Take Profit Strategy +- Data Cycle: Multi-Cycle +- Support: Commodity Futures, Digital Currency + + ![IMG](https://www.fmz.com/upload/asset/f5eedaf080c1616d41426efe01b6861d.png) + ![IMG](https://www.fmz.com/upload/asset/4f6ef3c138dfb6a669dcda326222520b.png) + +- Main chart: + Upper line, formula:UPPERLINE^^TODAYOPEN+BAND; + Lower line, formula:LOWERLINE^^TODAYOPEN-BAND; + MA, formula:MALINE^^MA(CLOSE,LENGTH); + +- Secondary chart: + none + +[/trans] + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|LENGTH|200|均线指标参数|MA index parameter| +|STOPRANGE|3|止损幅度|stop loss range| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-01-01 00:00:00 +end: 2018-04-09 00:00:00 +period: 1d +exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] +args: [["LENGTH",80]] +*) + +STARTPER1:=5; // 1级跟踪止盈,盈利5%启动 + // 1 level tracking take profit, if profit 5% then start + +STOPPER1:=100; // 1级跟踪止盈,盈利回撤100%触发 + // 1 level tracking take profit, if profit retracement is 100% then trigger + +STARTPER2:=10; // 2级跟踪止盈,盈利10%启动 + // 2 level tracking take profit, if profit 10% then start + +STOPPER2:=50; // 2级跟踪止盈,盈利回撤50%触发 + // 2 level tracking take profit, if profit retracement is 50% then trigger + +STARTPER3:=20; // 3级跟踪止盈,盈利20%启动 + // 3 level tracking take profit, if profit 20% then start + +STOPPER3:=20; // 3级跟踪止盈,盈利回撤20%触发 + // 3 level tracking take profit, if profit retracement is 20% then trigger + +// 上下区间 +// Upper and lower intervals + +NN:=BARSLAST(DATE<>REF(DATE,1))+1; // 今天开盘到目前为止的周期数 + // The number of cycles since the opening today + +TODAYOPEN:=VALUEWHEN(NN=1,O); // 当天的开盘价 + // Opening price of the day + +TODAYHIGH:=HHV(H,NN); // 今天全天的最高价,today’s highest price +TODAYLOW:=LLV(L,NN); // 今天全天的最低价,today’s lowest price +YESTDAYHIGH:=REF(TODAYHIGH,NN); // 昨天全天的最高价,yesterday's highest price +YESTDAYLOW:=REF(TODAYLOW,NN); // 昨天全天的最低价,yesterday's lowest price + +BAND:=YESTDAYHIGH-YESTDAYLOW; +UPPERLINE^^TODAYOPEN+BAND; +LOWERLINE^^TODAYOPEN-BAND; + +//均线 +// MA +MALINE^^MA(CLOSE,LENGTH); + +//开平仓条件 +// When to open and close position +SKCOND: = CUPPERLINE AND UPPERLINE>MALINE; +BPSHORT: = C>UPPERLINE OR C>MALINE; +SPLONG: = C=SKLOW+(SKPRICE-SKLOW)*0.01*STOPPER3,BP;// 最大盈利达到"STARTPER3"%之后盈利回撤"STOPPER3"%,平空 + // If profit get “STARTPER3”% and profit retracement get “STOPPER3”%, then close short position +BKHIGH>=BKPRICE*(1+0.01*STARTPER3) AND LOW<=BKHIGH-(BKHIGH-BKPRICE)*0.01*STOPPER3,SP;// 最大盈利达到"STARTPER3"%之后盈利回撤"STOPPER3"%,平多 + // If profit get “STARTPER3”% and profit retracement get “STOPPER3”%, then close long position +SKLOW<=SKPRICE*(1-0.01*STARTPER2) AND HIGH>=SKLOW+(SKPRICE-SKLOW)*0.01*STOPPER2,BP; // 最大盈利达到"STARTPER2"%之后盈利回撤"STOPPER2"%,平空 + // If profit get “STARTPER2”% and profit retracement get “STOPPER2”%, then close short position +BKHIGH>=BKPRICE*(1+0.01*STARTPER2) AND LOW<=BKHIGH-(BKHIGH-BKPRICE)*0.01*STOPPER2,SP;// 最大盈利达到"STARTPER2"%之后盈利回撤"STOPPER2"%,平多 + // If profit get “STARTPER2”% and profit retracement get “STOPPER2”%, then close long position +SKLOW<=SKPRICE*(1-0.01*STARTPER1) AND HIGH>=SKLOW+(SKPRICE-SKLOW)*0.01*STOPPER1,BP;// 最大盈利达到"STARTPER1"%之后盈利回撤"STOPPER1"%,平空 + // If profit get “STARTPER1”% and profit retracement get “STOPPER1”%, then close short position +BKHIGH>=BKPRICE*(1+0.01*STARTPER1) AND LOW<=BKHIGH-(BKHIGH-BKPRICE)*0.01*STOPPER1,SP;// 最大盈利达到"STARTPER1"%之后盈利回撤"STOPPER1"%,平多 + // If profit get “STARTPER1”% and profit retracement get “STOPPER1”%, then close long position + +//止损 +//stop loss +C>=SKPRICE*(1+STOPRANGE*0.01),BP; +C<=BKPRICE*(1-STOPRANGE*0.01),SP; +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/128122 + +> 更新时间 + +2018-12-15 18:44:14 diff --git "a/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245.md" "b/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245|The average of difference - combined with ATR.md" similarity index 62% rename from "\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245.md" rename to "\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245|The average of difference - combined with ATR.md" index ad2ef51b..3f728d6e 100644 --- "a/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245.md" +++ "b/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245|The average of difference - combined with ATR.md" @@ -1,7 +1,7 @@ > 策略名称 -开收盘均价差ATR策略 +开收盘均价差ATR策略|The average of difference - combined with ATR > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 策略进场:开盘价和收盘价均价差决定趋势,与ATR结合,进场点也是反向出场点; - 策略出场:开仓就定好止损点,趋势转向出场; - 数据周期:日线 @@ -26,14 +27,36 @@ littleDreamXX ![IMG](https://www.fmz.com/upload/asset/ab8d909c6464234b06ef1f116a4de200.png) +|| + +- Enter: The average of difference of opening price minus closing price determines the trend combined with ATR, + the entry point is also the exit point in reverse; +- Exit: Stop-loss point should be fixed at the opening of the position, + and if there is a reverse trend in price, close the position. +- Data Cycle: 1 Day +- Data contract: index contract +- Transaction contract: main contract + + ![IMG](https://www.fmz.com/upload/asset/0472d059ecdceca56fc7baaf5ff79deb.png) + ![IMG](https://www.fmz.com/upload/asset/aa2ad84ec198efe3c4d6afdd25753f3b.png) + +- Main chart: + none + +- Secondary chart: + ATR, formula ATR ^^ MA (TR, N); + C_O, formula C_O: EMA (C, N) - EMA (O, N); + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|N|20|ATR指标参数| -|M|5|BAND系数| +|N|20|ATR指标参数|ATR index parameter| +|M|5|BAND系数|BAND coefficient| > 源码 (麦语言) @@ -47,6 +70,8 @@ exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","balance":20000}] *) // 变量 +// variable + LOTS:=MAX(1,INTPART(MONEYTOT/(O*UNIT*0.1))); C_O:EMA(C,N)-EMA(O,N); B:=CROSSUP(C_O,0); @@ -60,10 +85,12 @@ PRICE_SPK:=VALUEWHEN(S,L-BAND); PRICE_BP:=VALUEWHEN(S,H+BAND); // 策略逻辑 +// strategy logic BARPOS>N AND C_O>0 AND C>=PRICE_BPK,BPK(LOTS); BARPOS>N AND C_O<0 AND C<=PRICE_SPK,SPK(LOTS); // 下单 +// place an order S,SP(BKVOL); B,BP(SKVOL); @@ -77,4 +104,4 @@ https://www.fmz.com/strategy/128136 > 更新时间 -2018-12-03 11:42:38 +2018-12-15 15:43:24 diff --git "a/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" "b/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|SAR and Price High and Low Strategy.md" similarity index 59% rename from "\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" rename to "\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|SAR and Price High and Low Strategy.md" index 10b93d3a..b62af9ff 100644 --- "a/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" +++ "b/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|SAR and Price High and Low Strategy.md" @@ -1,7 +1,7 @@ > 策略名称 -抛物线转向SAR与价格高低点策略 +抛物线转向SAR与价格高低点策略|SAR and Price High and Low Strategy > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 策略名称:SAR和价格高低点策略 - 数据周期:1H等 - 策略支持:商品期货、数字货币现货,数字货币期货 @@ -16,16 +17,27 @@ littleDreamXX ![IMG](https://www.fmz.com/upload/asset/4d9459b9af47702f7c2c6666212927c7.png) +|| + +- Strategy Name: SAR and Price High and Low Strategy +- Data cycle: 1H, etc. +- Strategic Support: Commodity Futures, Digital Currency Spot, Digital Currency Futures + + ![IMG](https://www.fmz.com/upload/asset/ca979cacba242461b34f320a71c2a1a9.png) + ![IMG](https://www.fmz.com/upload/asset/89ed32f65277b4b1dc6d9d420508dfcd.png) + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|SLOSS|2|止损止盈百分比| -|N|60|收盘价高低点周期| -|IsCryptoCurrency|0|选择用于商品期货或者数字货币: 商品期货|数字货币现货|数字货币期货| -|CryptoCurrencyTradeAmount|true|用于数字货币市场时的每次交易下单量| +|SLOSS|2|止损止盈百分比|stop loss percentage and take profit percentage| +|N|60|收盘价高低点周期|cycle of closing price's high and low point| +|IsCryptoCurrency|0|选择用于商品期货或者数字货币|Choose for commodity futures or digital currency: 商品期货|Commodity Futures||数字货币现货|Digital Currency Spot||数字货币期货|Digital Currency Futures| +|CryptoCurrencyTradeAmount|true|用于数字货币市场时的每次交易下单量|Order quantity per transaction used in the digital currency market| > 源码 (麦语言) @@ -39,11 +51,6 @@ exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] args: [["IsCryptoCurrency",2],["ContractType","rb888",126961]] *) -// 参数 -// N:=60; -// SLOSS:=2; -// FUND:=20000; - LOTS:=IF(IsCryptoCurrency, IF(IsCryptoCurrency=1, CryptoCurrencyTradeAmount, MAX(1, INTPART(CryptoCurrencyTradeAmount))), MAX(1,INTPART(MONEYTOT/(O*UNIT*0.1)))); SARLINE:=SAR(4,2,20); @@ -72,4 +79,4 @@ https://www.fmz.com/strategy/128251 > 更新时间 -2018-12-05 18:14:25 +2018-12-17 15:40:03 diff --git "a/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245.md" "b/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245|Simplified Version of ICHIMOKU KINKO HYO Strategy.md" similarity index 56% rename from "\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245.md" rename to "\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245|Simplified Version of ICHIMOKU KINKO HYO Strategy.md" index 7f7c2881..cbabd6bc 100644 --- "a/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245.md" +++ "b/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245|Simplified Version of ICHIMOKU KINKO HYO Strategy.md" @@ -1,7 +1,7 @@ > 策略名称 -日本云图简化版策略 +日本云图简化版策略|Simplified Version of ICHIMOKU KINKO HYO Strategy > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 策略名称:日本云图简化版策略 - 支持:商品期货 - 适用周期:多周期 @@ -22,16 +23,34 @@ littleDreamXX - 副图: 无 +|| + +- Strategy Name: Simplified Version of ICHIMOKU KINKO HYO Strategy +- Support: Commodity Futures +- Applicable cycle: multi-cycle + + ![IMG](https://www.fmz.com/upload/asset/6f4c8ca3330841b05f7fb0fcf311f7e0.png) + ![IMG](https://www.fmz.com/upload/asset/bb88fe6d9191768a71c29361ed5cc0f3.png) + ![IMG](https://www.fmz.com/upload/asset/1ce2e5d93a05cb49c0bd9a7113deeb0c.png) + +- Main chart: + none + +- Secondary chart: + none + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|N1|10|收盘价周期1| -|N4|177|收盘价周期2| -|N2|41|开盘价周期1| -|N3|52|开盘价周期2| +|N1|10|收盘价周期1|closing price Cycle 1| +|N4|177|收盘价周期2|closing price Cycle 2| +|N2|41|开盘价周期1|opening price cycle 1| +|N3|52|开盘价周期2|opening price cycle 2| > 源码 (麦语言) @@ -45,14 +64,17 @@ exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] *) //交易条件 +//Trading terms CONDITION1:=REF(CLOSE,1) > REF(CLOSE,N1) AND REF(CLOSE,8) > REF(CLOSE,N4) AND CLOSE > OPEN AND REF(CLOSE,137)>REF(OPEN,N2) AND CLOSE > REF(OPEN,N3); CONDITION2:=REF(CLOSE,1) < REF(CLOSE,N1) AND REF(CLOSE,8) < REF(CLOSE,N4) AND CLOSE < OPEN AND REF(CLOSE,137) 更新时间 -2018-12-07 10:48:01 +2018-12-17 18:41:44 diff --git "a/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245.md" "b/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245|Standard deviation price channel strategy.md" similarity index 58% rename from "\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245.md" rename to "\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245|Standard deviation price channel strategy.md" index 0e2d68ed..47208f1c 100644 --- "a/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245.md" +++ "b/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245|Standard deviation price channel strategy.md" @@ -1,7 +1,7 @@ > 策略名称 -标准差价格通道策略 +标准差价格通道策略|Standard deviation price channel strategy > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 数据周期:30分钟左右 - 支持 数字货币现货、数字货币期货 - 支持 商品期货,适合品种:热卷、焦炭、豆粕、郑醇、沪镍、郑油、聚丙烯、螺纹、橡胶、锰硅、PTA、豆油 @@ -28,14 +29,38 @@ littleDreamXX 标准差,公式:STDS:STD(C,10); 标准差,公式:STDL:STD(C,60); +|| + +- Data cycle: about 30 minutes +- Support: Digital Currency Spot, Digital currency Futures +- Support: Commodity futures + +- Digital Currency backtest: + + ![IMG](https://www.fmz.com/upload/asset/d5830a58e1b3aca111849d77173ac822.png) + + ![IMG](https://www.fmz.com/upload/asset/5bbb1e2f4030ce3116263aa6a65a4be9.png) + + ![IMG](https://www.fmz.com/upload/asset/e5a726a2bfe6570c06dd043c9ee5545c.png) + +- Main chart: + upper line, formula: UPPERBAND^^AVGVALUE + SHIFTVALUE; + lower line, formula: LOWERBAND^^AVGVALUE - SHIFTVALUE; + +- Secondary chart: + standard deviation, formula: STDS: STD (C, 10); + standard deviation, formula: STDL: STD (C, 60); + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|STOPRANGE|true|止损幅度| -|N|20|均线参数| +|STOPRANGE|true|止损幅度|Stop loss range| +|N|20|均线参数|average line index| > 源码 (麦语言) @@ -52,8 +77,11 @@ args: [["ContractType","this_week",126961]] TPRICE:=(HIGH+LOW+OPEN+CLOSE)/4; AVGVALUE:=MA(TPRICE,N); //求最高价减去最低价,一个周期前的收盘价减去最高价的绝对值,一个周期前的收盘价减去最低价的绝对值,这三个值中的最大值 +// Find the maximum of these three values: highest price minus lowest price, the absolute value of (closing price a cycle ago minus the highest price), the absolute value of (closing price a cycle ago minus the lowest price) + TR:=MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW)); -SHIFTVALUE:=MA(TR,N);//求N个周期内的TR的简单移动平均 +SHIFTVALUE:=MA(TR,N); // 求N个周期内的TR的简单移动平均 + // Find the simple moving average of TR in N cycles UPPERBAND^^AVGVALUE + SHIFTVALUE; LOWERBAND^^AVGVALUE - SHIFTVALUE; STDS:STD(C,10); @@ -65,6 +93,8 @@ BKVOL>0 AND BKHIGH-BKPRICE>=0.2*CLOSE AND C0 AND SKPRICE-SKLOW>=0.2*CLOSE AND C>UPPERBAND,BP; //止损 +//Stop loss + C>=SKPRICE*(1+STOPRANGE*0.01),BP; C<=BKPRICE*(1-STOPRANGE*0.01),SP; @@ -77,4 +107,4 @@ https://www.fmz.com/strategy/128121 > 更新时间 -2018-12-05 10:53:14 +2018-12-15 15:41:45 diff --git "a/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245.md" "b/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245|Volatility ATR - Track Breakthrough Strategy.md" similarity index 59% rename from "\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245.md" rename to "\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245|Volatility ATR - Track Breakthrough Strategy.md" index fa2b8339..fe64cf56 100644 --- "a/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245.md" +++ "b/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245|Volatility ATR - Track Breakthrough Strategy.md" @@ -1,7 +1,7 @@ > 策略名称 -波动率ATR轨道突破策略 +波动率ATR轨道突破策略|Volatility ATR - Track Breakthrough Strategy > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 公式名称:波动率轨道突破策略 - 数据周期:15M,30M等 - 支持:商品期货、数字货币现货、数字货币期货 @@ -25,15 +26,34 @@ littleDreamXX - 副图: 波动率,公式:ATR:=MA(TR,LENGTH2); +|| + +- Strategy name: Volatility ATR Track Breakthrough Strategy +- Data Cycle: 15M, 30M, etc. +- Support: Commodity Futures, Digital Currency Spot, Digital Currency Futures + + ![IMG](https://www.fmz.com/upload/asset/3ab48b24790ffa7df8578da42ee9890d.png) + ![IMG](https://www.fmz.com/upload/asset/26254e88d3af8327dc70f9e4d0797b88.png) + +- Main chart: + medium track, formula: MIDLINE ^^ MA ((H + L + C) / 3, LENGTH1); + up track, formula: UPBAND ^^ MIDLINE + NATR; + low track, formula: DOWNBAND ^ ^ MIDLINE - NATR; + +- Secondary chart: + Volatility, formula: ATR:= MA (TR, LENGTH2); + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|LENGTH2|100|ATR指标参数| -|LENGTH1|300|均线指标参数| -|N|2|上下轨系数| +|LENGTH2|100|ATR指标参数|ATR index parameter| +|LENGTH1|300|均线指标参数|MA index parameter| +|N|2|上下轨系数|Upper and lower track coefficients| > 源码 (麦语言) @@ -69,4 +89,4 @@ https://www.fmz.com/strategy/128252 > 更新时间 -2018-12-05 17:17:26 +2018-12-17 16:18:06 diff --git "a/\346\265\213\350\257\225\347\201\253\345\270\201macd\351\207\221\345\217\211.md" "b/\346\265\213\350\257\225\347\201\253\345\270\201macd\351\207\221\345\217\211.md" new file mode 100644 index 00000000..debb1e31 --- /dev/null +++ "b/\346\265\213\350\257\225\347\201\253\345\270\201macd\351\207\221\345\217\211.md" @@ -0,0 +1,175 @@ + +> 策略名称 + +测试火币macd金叉 + +> 策略作者 + +量化新人 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|FastPeriod|5|入市快线周期| +|SlowPeriod|15|入市慢线周期| +|EnterPeriod|false|入市观察期| +|ExitFastPeriod|7|离市快线周期| +|ExitSlowPeriod|15|离市慢线周期| +|ExitPeriod|false|离市观察期| +|PositionRatio|0.8|仓位比例| +|Interval|10|轮询周期(秒)| + + +> 源码 (javascript) + +``` javascript + +function adjustFloat(v) { + return Math.floor(v*100)/100; +} +function CancelPendingOrders() { + while (true) { + var orders = null; + while (!(orders = exchange.GetOrders())) { + Sleep(Interval); + } + + if (orders.length == 0) { + return; + } + + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]); + if (j < (orders.length-1)) { + Sleep(Interval); + } + } + } +} +var records=[] +function MACD_Cross() { //检测MACD指标,交叉状态的函数 + records = exchange.GetRecords(); //获取K线数据 + + while (!records && records.length < 45) { //K线数据不能为null,要大于45个柱,不符合标准 循环获取直到符合 + records = exchange.GetRecords(); + // Log("Sleep"); + Sleep(1000); + + } + // Log(records); + var macd = TA.MACD(records, 12, 26, 9); //调用指标函数, 参数为MACD 默认的参数。 + // var ma5 = TA.MA(records,5); + // var ma25 = TA.MA(records, 25); + // var ma125 = TA.MA(records, 125); + // var ma250 = TA.MA(records, 250); + + var dif = macd[0]; //dif线 + var dea = macd[1]; //dea线 + var macd = macd[2]; // MACD柱 + + var len = records.length; //K线周期长度 + // ma30[len-1]0.02 + + + if (dif[len - 1] > dea[len - 1] && dif[len - 2] < dea[len - 2] ) { + return 1; + // Log("买入",records[len-1].Time) + } + //macd[len-2] dea[len - 2])) { + // Log("卖出",records[len-1].Time) + return 2; + } + return 0; +} +function updateProfit(accountInit, accountNow, price) { + var netNow = accountNow.Balance + accountNow.FrozenBalance + ((accountNow.Stocks + accountNow.FrozenStocks) * price); + var netInit = accountInit.Balance + accountInit.FrozenBalance + ((accountInit.Stocks + accountInit.FrozenStocks) * initTicker.Buy); + LogProfit(adjustFloat(netNow - netInit)); +} +var initTicker =null; +function main() { + var initAccount = exchange.GetAccount(); + initTicker= exchange.GetTicker(); + Log(initAccount); + var buyPrice = 0; + var sellPrice = 0; + var buyFlag = true; + var sellFlag = false; + // 如果策略临时中断重启了,此时已经买到币了就要考虑卖出了 + // if(initAccount.Stocks>=1){ + // sellFlag = true + // buyFlag = false + // } + var earn = 0; + var totalEarn =0 ; + while (true) { + CancelPendingOrders() + var ma = MACD_Cross(); + var ticker = exchange.GetTicker(); + var depth = exchange.GetDepth(); + var price = 0; + var amount = 0; + var cost = 0; + var nowAccount = exchange.GetAccount() + + + if (ma == 1&&buyFlag) { + buyFlag = false; + sellFlag = true; + price = depth.Asks[0].Price; + amount = depth.Asks[0].Amount; + // cost = price*amount * 0.002 + + buyPrice = price; + // Log("买前当前账户:",nowAccount,"买价格:",buyPrice+"->@量->",0.1); + // 买的时候扣除的是 币的个数 + var realBuy = _N((nowAccount.Balance/buyPrice)*(1-0.002),2) + + exchange.Buy(buyPrice,realBuy); + nowAccount = exchange.GetAccount() + // Log("买后当前账户:",nowAccount,"买价格:",buyPrice+"->@量->",0.1); + // exchange.Log(LOG_TYPE_BUY, 123, 1,1); + Log("买入时间",new Date(records[records.length-1].Time).toLocaleTimeString()) + // Log("买入时间",new Date(records[records.length-1].Time).toLocalTimeString()) + // Log("买入时间",new Date(records[records.length-1].Time).toLocalString()) + } else if(ma==2&&sellFlag) { + sellFlag = false; + buyFlag = true; + price = depth.Bids[0].Price; + amount = depth.Bids[0].Amount; + sellPrice = price ; + // cost = price*amount * 0.002 + earn = ((sellPrice - buyPrice) / buyPrice) *100 + totalEarn+=earn; + + Log("卖出时间,",new Date(records[records.length-1].Time).toLocaleTimeString(),"当前收益:"+earn.toFixed(2)+"总收益:"+totalEarn.toFixed(2)+"%@"); + // Log("卖前当前账户:",nowAccount,"卖价格:",sellPrice,"->@当前收益",earn.toFixed(2)) + exchange.Sell(sellPrice,_N(nowAccount.Stocks,2)) + // exchange.Log(LOG_TYPE_SELL, 123, 1,1); + nowAccount = exchange.GetAccount() + // Log("卖后当前账户:",nowAccount,"卖价格:",sellPrice,"->@量->",nowAccount.Stocks) + updateProfit(initAccount,nowAccount,price) + + }else{ + // LogProfit(0); + } + Sleep(5*1000); + } +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/92839 + +> 更新时间 + +2018-12-23 14:04:05 diff --git "a/\346\267\267\346\262\214\346\223\215\344\275\234\346\263\225\347\255\226\347\225\245|Trading Chaos Strategy.md" "b/\346\267\267\346\262\214\346\223\215\344\275\234\346\263\225\347\255\226\347\225\245|Trading Chaos Strategy.md" new file mode 100644 index 00000000..d14a4919 --- /dev/null +++ "b/\346\267\267\346\262\214\346\223\215\344\275\234\346\263\225\347\255\226\347\225\245|Trading Chaos Strategy.md" @@ -0,0 +1,113 @@ + +> 策略名称 + +混沌操作法策略|Trading Chaos Strategy + +> 策略作者 + +littleDreamXX + +> 策略描述 + +[trans] +- 策略名称:混沌操作法策略 +- 支持:商品期货 , 数字货币, 数字货币期货 +- 使用周期:日线 +- 官方网站:www.quant.la + + ![IMG](https://www.fmz.com/upload/asset/a740c3a88fe1e0accb0c6a77fb11721c.png) + + +- 主图: + + Y线,公式:Y^^SMA(REF(HL,N3),N4,1); + + YRG最大,公式:MAX_YRG^^MAX(MAX(Y,R),G); + + YRG最小,公式:MIN_YRG^^MIN(MIN(Y,R),G); + + TOP_FRACTAL,公式:TOP_FRACTAL^^VALUEWHEN(H>=MAX_YRG,TOP); + + BOTTOM_FRACTAL,公式:BOTTOM_FRACTAL^^VALUEWHEN(L<=MIN_YRG,BOTTOM); + +- 副图: + + 无 + +|| + +- Strategy Name: Trading Chaos Strategy +- Support: Commodity Futures, Digital Currency, Digital Currency Futures +- Cycle: Daily + + ![IMG](https://www.fmz.com/upload/asset/a0b8ae48baf0cb4acb6b5e85c0d34e28.png) + ![IMG](https://www.fmz.com/upload/asset/5011913cd4b40176810ca8ce3067f0d3.png) + +- Main chart: + Y line, formula: Y ^^ SMA (REF (HL, N3), N4, 1); + YRG maximum, formula: MAX_YRG^^ MAX (MAX (Y, R), G); + YRG minimum, formula: MIN_YRG^^^ MIN (MIN (Y, R), G); + TOP_FRACTAL, formula: TOP_FRACTAL^^^ VALUEWHEN (H >= MAX_YRG, TOP); + BOTTOM_FRACTAL, formula: BOTTOM_FRACTAL^^^ VALUEWHEN (L<=MIN_YRG, BOTTOM); + +- Secondary chart: + none + +[/trans] + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N1|3|参数N1|parameter N1| +|N2|5|参数N2|parameter N2| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-11-13 00:00:00 +end: 2018-12-13 00:00:00 +period: 1h +exchanges: [{"eid":"Huobi","currency":"BTC_USDT","balance":10000,"stocks":3}] +*) + +N3:=N1+N2; +N4:=N2+N3; + +HL:=(H+L)/2; + +Y^^SMA(REF(HL,N3),N4,1); +R:=SMA(REF(HL,N2),N3,1); +G:=SMA(REF(HL,N1),N2,1); + +TOP_N:=BARSLAST(REF(H,2)=HHV(H,5))+2; +BOTTOM_N:=BARSLAST(REF(L,2)=LLV(L,5))+2; + +TOP:=REF(H,TOP_N); +BOTTOM:=REF(L,BOTTOM_N); + +MAX_YRG^^MAX(MAX(Y,R),G); +MIN_YRG^^MIN(MIN(Y,R),G); + +TOP_FRACTAL^^VALUEWHEN(H>=MAX_YRG,TOP); +BOTTOM_FRACTAL^^VALUEWHEN(L<=MIN_YRG,BOTTOM); + +BKVOL=0 AND C>=TOP_FRACTAL AND TOP_FRACTAL>MAX_YRG,BPK; +SKVOL=0 AND C<=BOTTOM_FRACTAL AND BOTTOM_FRACTALY,BP(SKVOL); + +``` + +> 策略出处 + +https://www.fmz.com/strategy/129077 + +> 更新时间 + +2018-12-18 10:26:10 diff --git "a/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245.md" "b/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245|PBX Strategy.md" similarity index 66% rename from "\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245.md" rename to "\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245|PBX Strategy.md" index cecfc5d3..4e74b2d5 100644 --- "a/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245.md" +++ "b/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245|PBX Strategy.md" @@ -1,7 +1,7 @@ > 策略名称 -瀑布线策略 +瀑布线策略|PBX Strategy > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 策略名称:瀑布线PUBU交易策略 - 数据周期:15M - 支持:商品期货 @@ -21,15 +22,31 @@ littleDreamXX 瀑布线2,公式:PUBU2^^(EMA(C,N2)+EMA(C,N2*2)+EMA(C,N2*4))/3; 瀑布线3,公式:PUBU3^^(EMA(C,N3)+EMA(C,N3*2)+EMA(C,N3*4))/3; +|| + +- Strategy Name: PBX Strategy +- Data cycle: 15M +- Support: Commodity Futures + + ![IMG](https://www.fmz.com/upload/asset/7a091a85a4f8af0a587ebd533b70145e.png) + ![IMG](https://www.fmz.com/upload/asset/151864a4e277271e6e9dce13515a0b4a.png) + +- Main chart: + PBX1,formula:PUBU1^^(EMA(C,N1)+EMA(C,N12)+EMA(C,N14))/3; + PBX2,formula:PUBU2^^(EMA(C,N2)+EMA(C,N22)+EMA(C,N24))/3; + PBX3,formula:PUBU3^^(EMA(C,N3)+EMA(C,N32)+EMA(C,N34))/3; + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|N1|20|瀑布线1参数| -|N2|50|瀑布线2参数| -|N3|70|瀑布线3参数| +|N1|20|瀑布线1参数|PBX1 parameter| +|N2|50|瀑布线2参数|PBX2 parameter| +|N3|70|瀑布线3参数|PBX3 parameter| > 源码 (麦语言) @@ -44,6 +61,7 @@ args: [["TradeAmount",10,126961],["ContractType","quarter",126961]] *) // 指标 +// index PUBU1^^(EMA(C,N1)+EMA(C,N1*2)+EMA(C,N1*4))/3; PUBU2^^(EMA(C,N2)+EMA(C,N2*2)+EMA(C,N2*4))/3; PUBU3^^(EMA(C,N3)+EMA(C,N3*2)+EMA(C,N3*4))/3; @@ -64,4 +82,4 @@ https://www.fmz.com/strategy/128420 > 更新时间 -2018-12-04 21:24:04 +2018-12-17 17:54:10 diff --git "a/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245.md" "b/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245|Price high and low - ROC index strategy.md" similarity index 63% rename from "\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245.md" rename to "\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245|Price high and low - ROC index strategy.md" index 1f1b1641..a20dd5cf 100644 --- "a/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245.md" +++ "b/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245|Price high and low - ROC index strategy.md" @@ -1,7 +1,7 @@ > 策略名称 -高低点与波动率ROC指标策略 +高低点与波动率ROC指标策略|Price high and low - ROC index strategy > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 策略名称:高低点与波动率ROC指标策略 - 数据周期:15M等 - 支持:商品期货 @@ -24,15 +25,33 @@ littleDreamXX - 副图: ARC指标, 公式:ARC:SMA(RC,M,1); +|| + +- Strategy Name: Price high and low - ROC index strategy +- Data cycle: 15M, etc. +- Support: Commodity Futures + + ![IMG](https://www.fmz.com/upload/asset/b2adb08374654bb533bed3f55e502592.png) + ![IMG](https://www.fmz.com/upload/asset/b10e5232882a919868802de72ba6f613.png) + +- Main chart: + The highest price of N cycle, formula: HH ^^ HHV (H, N); + The lowest price of N cycle, formula: LL ^^ LLV (L, N); + +- Secondary chart: + ARC index, formula: ARC: SMA (RC, M, 1); + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|N|200|高低点周期参数| -|SLOSS|true|止损百分比| -|M|50|ARC参数| +|N|200|高低点周期参数|high and low cycle parameter| +|SLOSS|true|止损百分比|stop loss percentage| +|M|50|ARC参数|ARC index| > 源码 (麦语言) @@ -73,4 +92,4 @@ https://www.fmz.com/strategy/128417 > 更新时间 -2018-12-04 22:06:21 +2018-12-17 16:58:17 diff --git "a/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245.md" "b/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245|Break High and Low - Volume Index Weighting Strategy.md" similarity index 58% rename from "\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245.md" rename to "\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245|Break High and Low - Volume Index Weighting Strategy.md" index edd864f3..22041d77 100644 --- "a/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245.md" +++ "b/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245|Break High and Low - Volume Index Weighting Strategy.md" @@ -1,7 +1,7 @@ > 策略名称 -高低点突破成交量指数加权策略 +高低点突破成交量指数加权策略|Break High and Low - Volume Index Weighting Strategy > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 策略名称:高低点突破成交量指数加权策略 - 数据周期:多周期 - 回测可以选择 OKEX期货 @@ -23,16 +24,33 @@ littleDreamXX - 副图 VJQ, 计算公式: VJQ:EMA(V*(C-REF(C,NC)),N);//定义成交量加权指数为VJQ +|| + +- Data cycle: multiple cycles +- Backtest can choose OKEX futures +- Contract: this_week contract + + ![IMG](https://www.fmz.com/upload/asset/7ba0592df29f0e159c4d6f090c893339.png) + ![IMG](https://www.fmz.com/upload/asset/7f9acd992f46482e5709402ae85abd77.png) + +- Main chart: + none + +- Secondary chart: + VJQ, calculation formula: VJQ: EMA (V* (C-REF (C, NC)), N) + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|SLOSS|2|止损百分比| -|N|300|EMA指标参数| -|NC|50|多少个周期前的收盘价| -|MINAMOUNT|true|最少一次下单数量| +|SLOSS|2|止损百分比|percentage of stop loss| +|N|300|EMA指标参数|EMA index parameter| +|NC|50|多少个周期前的收盘价|closing price of how many cycles ago| +|MINAMOUNT|true|最少一次下单数量|minimum order quantity at a time| > 源码 (麦语言) @@ -47,23 +65,26 @@ args: [["N",100],["MINAMOUNT",10],["TradeAmount",10,126961],["ContractType","thi *) LOTS:=MAX(MINAMOUNT,INTPART(MONEYTOT/O * 0.8)); -VJQ:EMA(V*(C-REF(C,NC)),N);//定义成交量加权指数为VJQ -B:=VJQ>0;//定义多头势 -S:=VJQ<0;//定义空头势 +VJQ:EMA(V*(C-REF(C,NC)),N); +B:=VJQ>0; +S:=VJQ<0; BUYPK:=BARPOS>N AND BKVOL=0 AND B AND H>=HHV(H,N); SELLPK:=BARPOS>N AND SKVOL=0 AND S AND L<=LLV(L,N); BUYP:=SKVOL>0 AND B; SELLP:=BKVOL>0 AND S; -//入场 +// 入场 +// Enter SELLPK,SPK(LOTS); BUYPK,BPK(LOTS); -//出场 +// 出场 +// Leave BUYP,BP(SKVOL); SELLP,SP(BKVOL); -//止损 +// 止损 +// Stop loss C>=SKPRICE*(1+SLOSS*0.01),BP(SKVOL); C<=BKPRICE*(1-SLOSS*0.01),SP(BKVOL); AUTOFILTER; @@ -75,4 +96,4 @@ https://www.fmz.com/strategy/128125 > 更新时间 -2018-12-05 10:57:07 +2018-12-15 15:42:32 diff --git "a/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245|High Winning Rate - ORB Trading Strategy.md" similarity index 70% rename from "\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245.md" rename to "\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245|High Winning Rate - ORB Trading Strategy.md" index fd584f77..29b78b1c 100644 --- "a/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245.md" +++ "b/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245|High Winning Rate - ORB Trading Strategy.md" @@ -1,7 +1,7 @@ > 策略名称 -高胜率ORB交易策略 +高胜率ORB交易策略|High Winning Rate - ORB Trading Strategy > 策略作者 @@ -9,6 +9,7 @@ littleDreamXX > 策略描述 +[trans] - 策略名称:高胜率ORB交易策略 - 数据周期:日K - 支持:商品期货 @@ -27,13 +28,34 @@ littleDreamXX - 副图: 无 +|| + +- Policy Name: High Winning Rate - ORB Trading Strategy +- Data Cycle: Daily +- Support: Commodity Futures + + ![IMG](https://www.fmz.com/upload/asset/5af37a668117bf82ffd3270e6792752f.png) + ![IMG](https://www.fmz.com/upload/asset/bdafbb088fd859227800705a1c16edca.png) + +- Main chart: + MA, formula: MAC ^^ MA (CLOSE, LENGTH); + MA of highest price, formula: MA_HH^^ MA (HHHV (HIGH, LENGTH), LENGTH; + MA of lowest price, formula: MA_LL^^ MA (LLV (LOW, LENGTH), LENGTH; + Upper track, formula: UPBAND ^^ O_TODAY + BAND; + Lower track, formula: DOWNBAND ^^ O_TODAY-BAND; + +- Secondary chart: + none + +[/trans] + > 策略参数 |参数|默认值|描述| |----|----|----| -|N_DAY|10|N日周期| +|N_DAY|10|N日周期|N day cycle| > 源码 (麦语言) @@ -86,4 +108,4 @@ https://www.fmz.com/strategy/129084 > 更新时间 -2018-12-06 17:33:27 +2018-12-18 10:46:04 From 125378c726b48cd538b7ad766c58fcc3ded2d1e8 Mon Sep 17 00:00:00 2001 From: Zero Date: Sat, 26 Jan 2019 16:10:21 +0800 Subject: [PATCH 10/19] update --- ...Bitmex position-change push(websocket).md" | 4 +- ...04\345\220\210\347\255\226\347\225\245.md" | 4 +- ...37\347\216\260\345\257\271\345\206\262.md" | 2 +- README.md | 24 +- ...10\345\210\251\345\210\251\345\231\250.md" | 402 ++++++++++++++++ ...er\345\212\240\345\274\272\347\211\210.md" | 49 ++ ...37\345\215\225\347\263\273\347\273\237.md" | 7 +- ...04ordersDetail\346\216\245\345\217\243.md" | 154 ++++++ ...26\347\225\245\347\240\224\347\251\266.md" | 77 +++ ...76\350\241\250\345\261\225\347\244\272.md" | 71 ++- ...45\270\201macd\351\207\221\345\217\211.md" | 175 ------- "\346\265\267\351\276\237.md" | 2 +- ...\345\206\262(\346\220\254\347\240\226).md" | 2 +- ...51\346\200\247\345\245\227\345\210\251.md" | 307 ++++++++++++ ...egy\342\200\235 implementations(V 1.0).md" | 220 +++++++++ ...26\347\225\245\344\275\223\351\252\214.md" | 42 +- ...46\344\271\240\346\226\207\344\273\266.md" | 445 ++++++++++++++++++ 17 files changed, 1770 insertions(+), 217 deletions(-) create mode 100644 "RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245-\347\206\212\345\270\202\347\233\210\345\210\251\345\210\251\345\231\250.md" create mode 100644 "cancelorder\345\212\240\345\274\272\347\211\210.md" create mode 100644 "\345\260\201\350\243\205Bithumb\347\232\204ordersDetail\346\216\245\345\217\243.md" create mode 100644 "\346\201\222\346\270\251\345\231\250 Thermostat \346\213\251\346\227\266\347\255\226\347\225\245\347\240\224\347\251\266.md" delete mode 100644 "\346\265\213\350\257\225\347\201\253\345\270\201macd\351\207\221\345\217\211.md" create mode 100644 "\351\200\211\346\213\251\346\200\247\345\245\227\345\210\251.md" create mode 100644 "\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214 (V 1.0)|M Language \342\200\234Turtle Trading strategy\342\200\235 implementations(V 1.0).md" create mode 100644 "\357\274\210\345\255\246\344\271\240\357\274\211API\344\270\216\346\225\231\347\250\213\345\206\205\344\273\243\347\240\201\345\255\246\344\271\240\346\226\207\344\273\266.md" diff --git "a/Bitmex\344\273\223\344\275\215\345\217\230\345\214\226\346\216\250\351\200\201\345\276\256\344\277\241\357\274\210wss\345\215\217\350\256\256,\351\234\200\350\246\201bitmex api ID\357\274\211|Bitmex position-change push(websocket).md" "b/Bitmex\344\273\223\344\275\215\345\217\230\345\214\226\346\216\250\351\200\201\345\276\256\344\277\241\357\274\210wss\345\215\217\350\256\256,\351\234\200\350\246\201bitmex api ID\357\274\211|Bitmex position-change push(websocket).md" index 08845206..7f88f9ea 100644 --- "a/Bitmex\344\273\223\344\275\215\345\217\230\345\214\226\346\216\250\351\200\201\345\276\256\344\277\241\357\274\210wss\345\215\217\350\256\256,\351\234\200\350\246\201bitmex api ID\357\274\211|Bitmex position-change push(websocket).md" +++ "b/Bitmex\344\273\223\344\275\215\345\217\230\345\214\226\346\216\250\351\200\201\345\276\256\344\277\241\357\274\210wss\345\215\217\350\256\256,\351\234\200\350\246\201bitmex api ID\357\274\211|Bitmex position-change push(websocket).md" @@ -19,7 +19,7 @@ botvsing function main() { var APIKEY = "your Access Key(Bitmex API ID)" var expires = parseInt(Date.now() / 1000) + 10 - var signature = exchange.HMAC("sha256", "hex", "GET/realtime" + expires, "{{secretkey}}") + var signature = exchange.HMAC("sha256", "hex", "GET/realtime" + expires, "{{secretkey}}")//secretkey在执行时自动替换,不用填写 var client = Dial("wss://www.bitmex.com/realtime", 60) var auth = JSON.stringify({args: [APIKEY, expires, signature], op: "authKeyExpires"}) var pos = 0 @@ -41,4 +41,4 @@ https://www.fmz.com/strategy/128624 > 更新时间 -2018-12-04 18:04:36 +2018-12-24 09:26:09 diff --git "a/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" "b/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" index 1a9f44f0..979a6348 100644 --- "a/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" +++ "b/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" @@ -72,9 +72,7 @@ SKVOL>0 AND (REF(MACDVALUE,1)>0 OR REF(DMA1,1)>REF(DMA2,1)),BP; // 启动止损 SKVOL>0 AND HIGH>=卖出开仓价*(1+STOPLOSS*0.01),BP; -SETSIGPRICETYPE(BP,MAX(O,卖出开仓价*(1+STOPLOSS*0.01))); BKVOL>0 AND LOW<=买入开仓价*(1-STOPLOSS*0.01),SP; -SETSIGPRICETYPE(SP,MIN(O,买入开仓价*(1-STOPLOSS*0.01))); AUTOFILTER; ``` @@ -84,4 +82,4 @@ https://www.fmz.com/strategy/128134 > 更新时间 -2018-12-18 15:30:12 +2019-01-04 15:37:17 diff --git "a/OKEX\346\234\237\347\216\260\345\257\271\345\206\262.md" "b/OKEX\346\234\237\347\216\260\345\257\271\345\206\262.md" index 04891a8c..a89ee1d8 100644 --- "a/OKEX\346\234\237\347\216\260\345\257\271\345\206\262.md" +++ "b/OKEX\346\234\237\347\216\260\345\257\271\345\206\262.md" @@ -618,4 +618,4 @@ https://www.fmz.com/strategy/127939 > 更新时间 -2018-11-29 11:23:51 +2019-01-26 10:44:21 diff --git a/README.md b/README.md index f5c35de6..9db44472 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,23 @@ > 开源策略 - - [测试火币macd金叉](https://www.fmz.com/strategy/92839) - - [基于ATR波动率指标构建的通道策略|Channel strategy based on ATR volatility indicator](https://www.fmz.com/strategy/127691) + - [cancelorder加强版](https://www.fmz.com/strategy/134368) + - [RSI统计套利策略-熊市盈利利器](https://www.fmz.com/strategy/131971) + - [海龟](https://www.fmz.com/strategy/128382) + - [OKEX期现对冲](https://www.fmz.com/strategy/127939) + - [现现对冲(搬砖)](https://www.fmz.com/strategy/127154) + - [测试多图表展示](https://www.fmz.com/strategy/38203) + - [选择性套利](https://www.fmz.com/strategy/134371) + - [恒温器 Thermostat 择时策略研究](https://www.fmz.com/strategy/127033) + - [MACD+MA指标组合策略](https://www.fmz.com/strategy/128134) + - [(学习)API与教程内代码学习文件](https://www.fmz.com/strategy/131864) + - [封装Bithumb的ordersDetail接口](https://www.fmz.com/strategy/132241) + - [麦语言海龟策略体验 (V 1.0)|M Language “Turtle Trading strategy” implementations(V 1.0)](https://www.fmz.com/strategy/132298) + - [麦语言海龟策略体验](https://www.fmz.com/strategy/126968) - [商品期货跟单系统](https://www.fmz.com/strategy/79351) + - [Bitmex仓位变化推送微信(wss协议,需要bitmex api ID)|Bitmex position-change push(websocket)](https://www.fmz.com/strategy/128624) + - [基于ATR波动率指标构建的通道策略|Channel strategy based on ATR volatility indicator](https://www.fmz.com/strategy/127691) - [升级版恒温器策略|Upgraded Thermostat Strategy](https://www.fmz.com/strategy/129086) - - [MACD+MA指标组合策略](https://www.fmz.com/strategy/128134) - [基于ATR波动率指标构建的通道策略|Channel strategy based on ATR](https://www.fmz.com/strategy/128126) - [三轨道波动率策略|Three-track Volatility Strategy](https://www.fmz.com/strategy/128129) - [Dual Thrust (麦语言版)|Dual Thrust (MyLanguage version)](https://www.fmz.com/strategy/128884) @@ -34,12 +46,7 @@ - [标准差价格通道策略|Standard deviation price channel strategy](https://www.fmz.com/strategy/128121) - [CTP 期货](https://www.fmz.com/strategy/130234) - [你不知道的MACD+MA指标组合策略|MACD+MA Indicator Combination Strategy](https://www.fmz.com/strategy/127101) - - [麦语言海龟策略体验](https://www.fmz.com/strategy/126968) - - [Bitmex仓位变化推送微信(wss协议,需要bitmex api ID)|Bitmex position-change push(websocket)](https://www.fmz.com/strategy/128624) - - [海龟](https://www.fmz.com/strategy/128382) - - [OKEX期现对冲](https://www.fmz.com/strategy/127939) - [商品期货交易类库(旧版)](https://www.fmz.com/strategy/127341) - - [现现对冲(搬砖)](https://www.fmz.com/strategy/127154) - [BitMEX 高级API功能 V.1.1.0 (期货:批量下单,编辑订单,冰山订单,一键撤单,定时撤单) Python2/3](https://www.fmz.com/strategy/114148) - [OkEX 高级API功能 V.1.1.0 (期货:批量下单,现货;TBD) Python2/3](https://www.fmz.com/strategy/113979) - [多交易所集合行情/下单 策略 范例](https://www.fmz.com/strategy/125569) @@ -175,7 +182,6 @@ - [知乎专栏 实例文章策略](https://www.fmz.com/strategy/40266) - [BitMEX 简单测试](https://www.fmz.com/strategy/40289) - [商品期货查看账户详细信息](https://www.fmz.com/strategy/37793) - - [测试多图表展示](https://www.fmz.com/strategy/38203) - [商品期货结算单平仓盈亏历史查询](https://www.fmz.com/strategy/38083) - [Convert_Record_Cycle](https://www.fmz.com/strategy/37678) - [转换任意K线周期](https://www.fmz.com/strategy/35986) diff --git "a/RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245-\347\206\212\345\270\202\347\233\210\345\210\251\345\210\251\345\231\250.md" "b/RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245-\347\206\212\345\270\202\347\233\210\345\210\251\345\210\251\345\231\250.md" new file mode 100644 index 00000000..9614e5ee --- /dev/null +++ "b/RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245-\347\206\212\345\270\202\347\233\210\345\210\251\345\210\251\345\231\250.md" @@ -0,0 +1,402 @@ + +> 策略名称 + +RSI统计套利策略-熊市盈利利器 + +> 策略作者 + +alinwo + +> 策略描述 + +策略介绍: + +此策略是基于RSI指标的统计套利策略,根据实测在熊市中也能有很高的胜率。策略会对行情进行RSI数据分析,一旦捕获到预定义的K线形态即进行短期套利。 + +RSI指标说明: + +RSI最早被用于期货交易中,后来人们发现用该指标来指导股票市场投资效果也十分不错,并对该指标的特点不断进行归纳和总结。现在,RSI已经成为被投资者应用最广泛的技术指标之一。投资的一般原理认为,投资者的买卖行为是各种因素综合结果的反映,行情的变化最终取决于供求关系,而RSI指标正是根据供求平衡的原理,通过测量某一个期间内股价上涨总幅度占股价变化总幅度平均值的百分比,来评估多空力量的强弱程度,进而提示具体操作的。 + +策略特点: + +支持任意级别的趋势跟踪(分钟K,小时K,日K,周K等) +支持任意交易对(ETH/BTC, BSV/BTC等) +支持任意交易所 +详细的策略报表(包括策略状态,交易历史记录等) +支持接近10个自定义个性化参数 + +使用说明: + +此策略基于Botvs实现,在使用之前需要有一个botvs账户 +上传策略并创建机器人 +配置参数并运行策略 + +参数说明: +http://www.pcclean.io/rsi%E7%BB%9F%E8%AE%A1%E5%A5%97%E5%88%A9%E7%AD%96%E7%95%A5/ + + + +> 源码 (javascript) + +``` javascript +/* +RSI策略:仅用于学习用途,用于实盘后果自负 +*/ + +var ExchangProcessor={ + createNew: function(exc_obj){ + //策略参数 + var manage_assets=1;//bch + var max_positions=4;//max=4N + var price_n={BTC_BCH:8,ETH_BCH:8,XRP_BCH:8,EOS_BCH:8,LTC_BCH:8,DASH_BCH:8,CET_BCH:8}; //价格精度 + var num_n={BTC_BCH:8,ETH_BCH:8,XRP_BCH:8,EOS_BCH:8,LTC_BCH:8,DASH_BCH:8,CET_BCH:8}; //数量精度 + var minest_buy={BTC_BCH:0.001,ETH_BCH:0.01,XRP_BCH:1,EOS_BCH:1,LTC_BCH:0.1,DASH_BCH:0.01,CET_BCH:1};//最小买入量 + var minest_sell={BTC_BCH:0.001,ETH_BCH:0.01,XRP_BCH:1,EOS_BCH:1,LTC_BCH:0.1,DASH_BCH:0.01,CET_BCH:1};//最小卖出量 + var order_wait_secs=120000; //订单的最长等待时间 毫秒 + var wait_ms=1000;//默认等待毫秒 + var sxf=0.0005;//用来计算手续费消耗 + + + //全局状态变量 + var positions=[];//记录仓位 + var init_asset=0; //初始资产 + var trades=[];//所有交易 + var trades_recorder=true;//记录所有交易 + var pre_time=null; //记录轮询间隔时间 + var approximate_profit=0;//盈亏近似值 + var add_already=0;//已经加仓次数 + + var processor={}; + //重试购买,直到成功返回 + processor.retryBuy=function(ex,price,num) + { + var currency=ex.GetCurrency(); + var r=ex.Buy(_N(price,price_n[currency]), _N(num,num_n[currency])); + while (!r){ + Log("Buy失败,正在retry。"); + Sleep(wait_ms); + var account=_C(ex.GetAccount); + var ticker=_C(ex.GetTicker); + var last=ticker.Last; + var fixedAmount=(price===-1?Math.min(account.Balance*0.95,num):Math.min(account.Balance/last*0.95,num)); + r=ex.Buy(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); + } + return r; + } + + //重试卖出,直到成功返回 + processor.retrySell=function(ex,price,num){ + var currency=ex.GetCurrency(); + var r=ex.Sell(_N(price,price_n[currency]), _N(num,num_n[currency])); + while (!r){ + Log("Sell失败,正在retry。"); + Sleep(wait_ms); + var account=_C(ex.GetAccount); + var fixedAmount=Math.min(account.Stocks,num); + r=ex.Sell(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); + } + return r; + } + + + processor.get_ChinaTimeString=function(){ + var date = new Date(); + var now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), + date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); + var cdate=new Date(now_utc); + cdate.setHours(cdate.getHours()+8); + var localstring=cdate.getFullYear()+'/'+(cdate.getMonth()+1)+'/'+cdate.getDate()+' '+cdate.getHours()+':'+cdate.getMinutes()+':'+cdate.getSeconds(); + return localstring; + } + + processor.init_obj=function(){ + _CDelay(wait_ms); + pre_time = new Date(); + + //init + { + var account=_C(exc_obj.GetAccount); + var ticker=_C(exc_obj.GetTicker); + var last=ticker.Last; + init_asset=(account.Balance+account.FrozenBalance)+(account.Stocks+account.FrozenStocks)*last; + Sleep(wait_ms); + } + } + + + processor.work=function(){ + var cur_time = new Date(); + var passedtime=cur_time-pre_time; + pre_time=cur_time; + + //计算n,头寸 + var exname=exc_obj.GetName(); + var currency=exc_obj.GetCurrency(); + var account=_C(exc_obj.GetAccount); + var ticker=_C(exc_obj.GetTicker); + var depth = _C(exc_obj.GetDepth); + var last=ticker.Last; + var ask1=depth.Asks[0].Price; + var bid1=depth.Bids[0].Price; + var bestprice=bid1+(Math.abs(ask1-bid1)/2); + var records = _C(exc_obj.GetRecords); + if (records.length<=50){ + Log("records.length is not valid."); + Sleep(wait_ms); + return; + } + var atr = TA.ATR(records, 20); + if (atr.length<=1){ + Log("atr.length is not valid."); + Sleep(wait_ms); + return; + } + var N=atr[atr.length-1]; + var position_unit=Math.min(manage_assets*0.01/N,account.Balance/last*0.95);//cet + //Log("N="+N+", 头寸单位="+position_unit+"CET"); + var highest=TA.Highest(records, 20, 'High'); + var Lowest=TA.Lowest(records, 10, 'Low'); + var cur_asset=(account.Balance+account.FrozenBalance)+(account.Stocks+account.FrozenStocks)*last; + var rsi6 = TA.RSI(records, 6); + var rsi12 = TA.RSI(records, 12); + if (rsi6.length<=5 || rsi12.length<=5){ + Log("rsi is not valid."); + Sleep(wait_ms); + return; + } + var rsi_in=false; + if (rsi6[rsi6.length-1]-rsi6[rsi6.length-2]>1 && rsi6[rsi6.length-2]<=65){ + //Log("rsi_in=true"); + rsi_in=true; + } + var rsi_out=false; + if (rsi6[rsi6.length-1]>=60){ + //Log("rsi_out=true"); + rsi_out=true; + } + + //建仓 + if (positions.length==0 && position_unit>minest_buy[currency]){ + if (rsi_in) + { + var buyID = processor.retryBuy(exc_obj,last,position_unit); + Sleep(order_wait_secs); + var buyOrder=_C(exc_obj.GetOrder,buyID); + if (buyOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(buyID); + } + if (buyOrder.DealAmount>0){ + var postion = { + amount:buyOrder.DealAmount, + buy_price:buyOrder.AvgPrice, + stoploss_price:buyOrder.AvgPrice-N}; + positions.push(postion); + + var details={ + type:"建仓", + time:processor.get_ChinaTimeString(), + RealAmount:buyOrder.DealAmount, + WantAmount:position_unit, + RealPrice:buyOrder.AvgPrice, + WantPrice:buyOrder.Price, + Memo:"" + }; + if (trades_recorder){ + trades.push(details); + } + + add_already=1; + } + } + } + + //加仓 + if (positions.length>0 && position_unit>minest_buy[currency]){ + var last_buy_price=positions[positions.length-1].buy_price; + if (add_already=0.5*N){ + var buyID = processor.retryBuy(exc_obj,last,position_unit); + Sleep(order_wait_secs); + var buyOrder=_C(exc_obj.GetOrder,buyID); + if (buyOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(buyID); + } + if (buyOrder.DealAmount>0){ + var postion = { + amount:buyOrder.DealAmount, + buy_price:buyOrder.AvgPrice, + stoploss_price:buyOrder.AvgPrice-N}; + positions.push(postion); + + var details={ + type:"加仓", + time:processor.get_ChinaTimeString(), + RealAmount:buyOrder.DealAmount, + WantAmount:position_unit, + RealPrice:buyOrder.AvgPrice, + WantPrice:last, + Memo:"" + }; + if (trades_recorder){ + trades.push(details); + } + + add_already=add_already+1; + } + } + } + } + + //止损 + if (positions.length>0){ + var positions_new=[]; + for (var i=0; i < positions.length; i++){ + if (last<=positions[i].stoploss_price){ + account=_C(exc_obj.GetAccount); + var fixedAmount=Math.min(account.Stocks,positions[i].amount); + if (fixedAmount>minest_sell[currency]){ + var sellID = processor.retrySell(exc_obj, last, fixedAmount); + Sleep(order_wait_secs); + var sellOrder=_C(exc_obj.GetOrder,sellID); + approximate_profit+=(sellOrder.AvgPrice*sellOrder.DealAmount*(1-sxf)-positions[i].buy_price*sellOrder.DealAmount*(1+sxf)); + Log("定价卖出: 数量-"+sellOrder.DealAmount+",approximate_profit="+approximate_profit); + if (sellOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(sellID); + if (Math.min(account.Stocks,fixedAmount-sellOrder.DealAmount)>minest_sell[currency]){ + var marketsellOrderID=processor.retrySell(exc_obj, -1, fixedAmount-sellOrder.DealAmount); + Sleep(order_wait_secs); + var marketsellOrderData=_C(exc_obj.GetOrder,marketsellOrderID); + approximate_profit+=(marketsellOrderData.AvgPrice*marketsellOrderData.DealAmount*(1-sxf)-positions[i].buy_price*marketsellOrderData.DealAmount*(1+sxf)); + Log("市价卖出: 数量-"+marketsellOrderData.DealAmount+",approximate_profit="+approximate_profit); + } + } + + var details={ + type:"止损", + time:processor.get_ChinaTimeString(), + RealAmount:-1, + WantAmount:fixedAmount, + RealPrice:-1, + WantPrice:last, + Memo:(last>positions[i].buy_price?"盈利":"亏损") + }; + if (trades_recorder){ + trades.push(details); + } + } + }else{ + positions_new.push(positions[i]); + } + } + positions=positions_new; + } + + //清仓 + if (positions.length>0){ + if (rsi_out){ + var positions_new=[]; + for (var i=0; i < positions.length; i++){ + account=_C(exc_obj.GetAccount); + var fixedAmount=Math.min(account.Stocks,positions[i].amount); + if (fixedAmount>minest_sell[currency]){ + var sellID = processor.retrySell(exc_obj, last, fixedAmount); + Sleep(order_wait_secs); + var sellOrder=_C(exc_obj.GetOrder,sellID); + approximate_profit+=(sellOrder.AvgPrice*sellOrder.DealAmount*(1-sxf)-positions[i].buy_price*sellOrder.DealAmount*(1+sxf)); + Log("定价卖出: 数量-"+sellOrder.DealAmount+",approximate_profit="+approximate_profit); + if (sellOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(sellID); + if (Math.min(account.Stocks,fixedAmount-sellOrder.DealAmount)>minest_sell[currency]){ + var marketsellOrderID=processor.retrySell(exc_obj, -1, fixedAmount-sellOrder.DealAmount); + Sleep(order_wait_secs); + var marketsellOrderData=_C(exc_obj.GetOrder,marketsellOrderID); + approximate_profit+=(marketsellOrderData.AvgPrice*marketsellOrderData.DealAmount*(1-sxf)-positions[i].buy_price*marketsellOrderData.DealAmount*(1+sxf)); + Log("市价卖出: 数量-"+marketsellOrderData.DealAmount+",approximate_profit="+approximate_profit); + } + } + + var details={ + type:"清仓", + time:processor.get_ChinaTimeString(), + RealAmount:-1, + WantAmount:fixedAmount, + RealPrice:-1, + WantPrice:last, + Memo:(last>positions[i].buy_price?"盈利":"亏损") + }; + if (trades_recorder){ + trades.push(details); + } + } + } + positions=positions_new; + } + } + + + //显示状态 + var table1 = {type: 'table', title: '仓位-'+exname+'('+currency+')', cols: ['数量', '成交价','止损价'], rows: []}; + var table2 = {type: 'table', title: '状态-'+exname+'('+currency+')', cols: ['平均真实波幅(N)','头寸单位','初始资产','当前资产','轮询时间','最新价','Highest','Lowest','加仓次数','【近似盈亏】'], rows: []}; + var table3 = {type: 'table', title: '交易历史-'+exname+'('+currency+')', cols: ['日期','类型', '成交数量','发单数量','成交价','发单价','备注'], rows: []}; + for (var i=0; i < positions.length; i++){ + table1.rows.push([positions[i].amount,positions[i].buy_price,positions[i].stoploss_price]); + } + table2.rows.push([N,position_unit,init_asset,cur_asset,passedtime+'ms',last,highest,Lowest,add_already,approximate_profit]); + for (i=0; i < trades.length; i++){ + table3.rows.push([trades[i].time,trades[i].type,trades[i].RealAmount,trades[i].WantAmount,trades[i].RealPrice,trades[i].WantPrice,trades[i].Memo]); + } + processor.logstatus=('`' + JSON.stringify([table1, table2, table3])+'`'+'\n'); + + //记录盈利 + processor.logprofit=approximate_profit; + + //rest + Sleep(wait_ms); + } + + return processor; + } +}; + + + +//主函数 +function main(){ + var exchange_num=exchanges.length; + var processors=[]; + for (var i=0; i 策略出处 + +https://www.fmz.com/strategy/131971 + +> 更新时间 + +2019-01-26 10:44:40 diff --git "a/cancelorder\345\212\240\345\274\272\347\211\210.md" "b/cancelorder\345\212\240\345\274\272\347\211\210.md" new file mode 100644 index 00000000..79bc4371 --- /dev/null +++ "b/cancelorder\345\212\240\345\274\272\347\211\210.md" @@ -0,0 +1,49 @@ + +> 策略名称 + +cancelorder加强版 + +> 策略作者 + +alinwo + +> 策略描述 + +botvs提供的api函数cancelorder只负责把指令发送到交易所,至于交易所是否真的执行成功与否并不会做判断和检测,所以我们需要在自己的程序中做这个检测工作,保证cancelorder能执行成功。 + +以下函数会重试cancelorder直到交易所成功执行,调用cancelorder的地方替换为此函数即可 + +函数源码分析:http://www.pcclean.io/%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3botvs%E4%B8%8A%E6%89%A7%E8%A1%8Ccancelorder%E5%87%BD%E6%95%B0%E5%A4%B1%E8%B4%A5%E7%9A%84%E9%97%AE%E9%A2%98%EF%BC%9F/ + + + +> 源码 (javascript) + +``` javascript +$.retry_cancelorder=function(ex,order_id){ + Log("取消订单"+order_id); + ex.CancelOrder(order_id); + Sleep(3000); + var orders=_C(ex.GetOrders); + var find=false; + for (var i=0;i 策略出处 + +https://www.fmz.com/strategy/134368 + +> 更新时间 + +2019-01-26 10:44:53 diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" index b53e8b05..7f5b603f 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" @@ -35,7 +35,9 @@ function trade(symbol, type, unit) { } var ntq = $.NewTaskQueue(); ntq.pushTask(exchanges[i], symbol, type, unit, function(task, ret) { - Log(i, ' 号账户 @ ', task.desc, "手, 成交价格:", ret.price); + if (ret) { + Log(i, ' 号账户 @ ', task.desc, "手, 成交价格:", ret.price); + } }); while (ntq.tasks.length > 0) { ntq.poll(); @@ -105,7 +107,6 @@ function data() { } } -// 主函数 function main() { for (var i = 0; i < exchanges.length; i++) { if (exchanges[i].GetName() !== 'Futures_CTP') { @@ -131,4 +132,4 @@ https://www.fmz.com/strategy/79351 > 更新时间 -2018-12-20 14:35:11 +2018-12-24 10:29:54 diff --git "a/\345\260\201\350\243\205Bithumb\347\232\204ordersDetail\346\216\245\345\217\243.md" "b/\345\260\201\350\243\205Bithumb\347\232\204ordersDetail\346\216\245\345\217\243.md" new file mode 100644 index 00000000..dbc5a96e --- /dev/null +++ "b/\345\260\201\350\243\205Bithumb\347\232\204ordersDetail\346\216\245\345\217\243.md" @@ -0,0 +1,154 @@ + +> 策略名称 + +封装Bithumb的ordersDetail接口 + +> 策略作者 + +小小梦 + +> 策略描述 + +应部分用户需求,使用bithumb 的时候希望查询 某个ID 的订单信息, +封装了 交易所的这个接口 : https://api.bithumb.com/info/order_detail +只能查询完全成交的订单,其它状态的订单是查询不到的。 + +接口信息如下: +``` + /* + https://api.bithumb.com/info/order_detail + order_id : + type : bid : Buy ask : sell + currency : Currency code ,Default : BTC + */ +``` + + +``` +function main() { + var id = exchange.Sell(-1, 0.01) // 下市价单 成交,因为 $.GetOrder 只能查询 完全成交的订单。 + // 下限价单不成交的话,去查询这个ID ,会报错 Futures_OP 4: status: 5600, message: 거래 체결내역이 존재하지 않습니다. (在交易中不存在), ,意思是查询不到这个订单 + Sleep(5000) + var order = $.GetOrder(exchange, id) // 传入交易所 Bithumb 的交易所对象, 传入ID ,查询不到 返回 null + Log(order) +} +``` + + + +> 源码 (javascript) + +``` javascript +function GetOrder(e, id, type){ + /* + https://api.bithumb.com/info/order_detail + order_id : + type : bid : Buy ask : sell + currency : Currency code ,Default : BTC + */ + var symbol = e.GetCurrency() + var arr = symbol.split("_") + var currency = arr[0] + + var ret = e.IO("api", "POST", "/info/order_detail", "order_id=" + id + "&type=" + type + "¤cy=" + currency) + + // ret + /* + { + "status":"0000", + "data":[ + { + "order_currency":"BTC", + "payment_currency":"KRW", + "units_traded":"0.01", + "price":"4322000", + "cont_no":"32314118", + "transaction_date":"1546054726834326", + "type":"Buy", + "fee":"64.83", + "total":"43220" + } + ] + } + */ + + /* order 结构 + { + Id :交易单唯一标识 + Price :下单价格 + Amount :下单数量 + DealAmount :成交数量 + AvgPrice :成交均价, # 注意 ,有些交易所不提供该数据,不提供的设置为 0 。 + Status :订单状态, 参考常量里的订单状态 + Type :订单类型, 参考常量里的订单类型 + } + */ + + var order = null + var typeValue = null + if(type == "Buy"){ + typeValue = ORDER_TYPE_BUY + } else { + typeValue = ORDER_TYPE_SELL + } + if(ret){ + order = { + Info : ret, // 原始信息 + Id : id, // 交易单唯一标识 + Price : ret.data[0].price, // 下单价格 + Amount : ret.data[0].units_traded, // 下单数量 + DealAmount: ret.data[0].units_traded, // 成交数量 + AvgPrice : ret.data[0].price, // 成交均价, # 注意 ,有些交易所不提供该数据,不提供的设置为 0 。 + Status : ORDER_STATE_CLOSED, // 订单状态, 参考常量里的订单状态 + Type : typeValue, // 类型 + } + } + + return order +} + +$.GetOrder = function(e, id, type){ + if(e.GetName() != "Bithumb"){ + Log("the parameter e is not bithumb!") + return null + } + + if(typeof(id) == "undefined"){ + Log("id 参数错误!") + return null + } + + if(type == "Buy"){ + GetOrder(e, id, type) + } else if (type == "Sell") { + GetOrder(e, id, type) + } else { + var buyOrder = GetOrder(e, id, "Buy") + if(buyOrder){ + return buyOrder + } + var sellOrder = GetOrder(e, id, "Sell") + if(sellOrder){ + return sellOrder + } else { + return null + } + } +} + +function main() { + var id = exchange.Sell(-1, 0.01) // 下市价单 成交,因为 $.GetOrder 只能查询 完全成交的订单。 + // 下限价单不成交的话,去查询这个ID ,会报错 Futures_OP 4: status: 5600, message: 거래 체결내역이 존재하지 않습니다. (在交易中不存在), ,意思是查询不到这个订单 + Sleep(5000) + var order = $.GetOrder(exchange, id) // 传入交易所 Bithumb 的交易所对象, 传入ID ,查询不到 返回 null + Log(order) +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/132241 + +> 更新时间 + +2018-12-29 12:06:11 diff --git "a/\346\201\222\346\270\251\345\231\250 Thermostat \346\213\251\346\227\266\347\255\226\347\225\245\347\240\224\347\251\266.md" "b/\346\201\222\346\270\251\345\231\250 Thermostat \346\213\251\346\227\266\347\255\226\347\225\245\347\240\224\347\251\266.md" new file mode 100644 index 00000000..8a8e6df9 --- /dev/null +++ "b/\346\201\222\346\270\251\345\231\250 Thermostat \346\213\251\346\227\266\347\255\226\347\225\245\347\240\224\347\251\266.md" @@ -0,0 +1,77 @@ + +> 策略名称 + +恒温器 Thermostat 择时策略研究 + +> 策略作者 + +Hukybo + + + + + +> 源码 (麦语言) + +``` pascal +// 回测配置 +(*backtest +start: 2011-01-01 09:00:00 +end: 2019-01-01 15:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","minfee":0,"fee":[0,0]}] +args: [["SlideTick",0,126961],["ContractType","rb000",126961]] +*) + +// 计算CMI指标用以区分震荡市与趋势市 +CMI:=ABS(C-REF(C,29))/(HHV(H,30)-LLV(L,30))*100; + +// 定义关键价格 +KOD:=(H+L+C)/3; + +// 震荡市中收盘价大于关键价格为宜卖市,否则为宜买市 +BE:=IFELSE(C>KOD,1,0); +SE:=IFELSE(C<=KOD,1,0); + +// 定义10日 ATR 指标 +TR:=MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW)); +ATR10:=MA(TR,10); + +// 定义最高价与最低价3日均线 +AVG3HI:=MA(H,3); +AVG3LO:=MA(L,3); + +// 计算震荡市的进场价格 +LEP:=IFELSE(C>KOD,O+ATR10*0.5,O+ATR10*0.75); +SEP:=IFELSE(C>KOD,O-ATR10*0.75,O-ATR10*0.5); +LEP1:=MAX(LEP,AVG3LO); +SEP1:=MIN(SEP,AVG3HI); + +// 计算趋势市的进场价格 +UPBAND:=MA(C,50)+STD(C,50)*2; +DNBAND:=MA(C,50)-STD(C,50)*2; + +// 计算趋势市的出场价格 +MA50:=MA(C,50); + +// 震荡策略逻辑 +CMI<20&&C>=LEP1,BK; +CMI<20&&C<=SEP1,SK; +CMI<20&&C>=AVG3HI,SP; +CMI<20&&C<=AVG3LO,BP; + +// 趋势策略逻辑 +CMI>=20&&C>=UPBAND,BK; +CMI>=20&&C<=DNBAND,SK; +CMI>=20&&C<=MA50,SP; +CMI>=20&&C>=MA50,BP; +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/127033 + +> 更新时间 + +2019-01-05 17:21:13 diff --git "a/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.md" "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.md" index d42d11c7..91abfd74 100644 --- "a/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.md" +++ "b/\346\265\213\350\257\225\345\244\232\345\233\276\350\241\250\345\261\225\347\244\272.md" @@ -16,8 +16,19 @@ BotVS支持策略同时展现多个图表, 这是一个简单的例子. 如果 > 源码 (javascript) ``` javascript +/*backtest +start: 2019-01-22 00:00:00 +end: 2019-01-23 00:00:00 +period: 30m +exchanges: [{"eid":"OKCoin_EN","currency":"BTC_USD"}] +*/ + function main() { var cfgA = { + extension: { + layout: 'single', // 不参于分组,单独显示, 默认为分组 'group' + height: 300, // 指定高度 + }, title: { text: '盘口图表' }, @@ -51,6 +62,47 @@ function main() { title: { text: '饼图' }, + series: [{ + type: 'pie', + name: 'one', + data: [ + ["A", 25], + ["B", 25], + ["C", 25], + ["D", 25], + ] // 指定初始数据后不需要用add函数更新, 直接更改图表配置就可以更新序列. + }] + }; + var cfgD = { + extension: { + layout: 'single', + col: 8, // 指定宽度占的单元值, 总值 为12 + height: '300px', + }, + title: { + text: '盘口图表' + }, + xAxis: { + type: 'datetime' + }, + series: [{ + name: '买一', + data: [], + }, { + name: '卖一', + data: [], + }] + } + var cfgE = { + __isStock: false, + extension: { + layout: 'single', + col: 4, + height: '300px', + }, + title: { + text: '饼图2' + }, series: [{ type: 'pie', name: 'one', @@ -63,8 +115,7 @@ function main() { }] }; - - var chart = Chart([cfgA, cfgB, cfgC]); + var chart = Chart([cfgA, cfgB, cfgC, cfgD, cfgE]); chart.reset() // 为饼图清加一个数点,add只能更新通过add方式添加的数据点, 内置的数据点无法后期更新 chart.add(3, { @@ -84,17 +135,17 @@ function main() { cfgB.subtitle = { text: '价差 ' + diff, }; - // update实际上等于重置了图表的配置 - chart.update([cfgA, cfgB, cfgC]); + chart.add([0, [new Date().getTime(), ticker.Buy]]); chart.add([1, [new Date().getTime(), ticker.Sell]]); // 相当于更新第二个图表的第一个数据序列 chart.add([2, [new Date().getTime(), diff]]); - // 相当于更新了第三个图表的第一个数据序列 - chart.add(3, { - name: "ZZ", - y: Math.random() * 100 - }, -1); + chart.add(4, [new Date().getTime(), ticker.Buy]); + chart.add(5, [new Date().getTime(), ticker.Buy]); + cfgC.series[0].data[0][1] = Math.random() * 100; + cfgE.series[0].data[0][1] = Math.random() * 100; + // update实际上等于重置了图表的配置 + chart.update([cfgA, cfgB, cfgC, cfgD, cfgE]); } } ``` @@ -105,4 +156,4 @@ https://www.fmz.com/strategy/38203 > 更新时间 -2017-03-24 20:45:59 +2019-01-24 17:33:12 diff --git "a/\346\265\213\350\257\225\347\201\253\345\270\201macd\351\207\221\345\217\211.md" "b/\346\265\213\350\257\225\347\201\253\345\270\201macd\351\207\221\345\217\211.md" deleted file mode 100644 index debb1e31..00000000 --- "a/\346\265\213\350\257\225\347\201\253\345\270\201macd\351\207\221\345\217\211.md" +++ /dev/null @@ -1,175 +0,0 @@ - -> 策略名称 - -测试火币macd金叉 - -> 策略作者 - -量化新人 - - - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|FastPeriod|5|入市快线周期| -|SlowPeriod|15|入市慢线周期| -|EnterPeriod|false|入市观察期| -|ExitFastPeriod|7|离市快线周期| -|ExitSlowPeriod|15|离市慢线周期| -|ExitPeriod|false|离市观察期| -|PositionRatio|0.8|仓位比例| -|Interval|10|轮询周期(秒)| - - -> 源码 (javascript) - -``` javascript - -function adjustFloat(v) { - return Math.floor(v*100)/100; -} -function CancelPendingOrders() { - while (true) { - var orders = null; - while (!(orders = exchange.GetOrders())) { - Sleep(Interval); - } - - if (orders.length == 0) { - return; - } - - for (var j = 0; j < orders.length; j++) { - exchange.CancelOrder(orders[j].Id, orders[j]); - if (j < (orders.length-1)) { - Sleep(Interval); - } - } - } -} -var records=[] -function MACD_Cross() { //检测MACD指标,交叉状态的函数 - records = exchange.GetRecords(); //获取K线数据 - - while (!records && records.length < 45) { //K线数据不能为null,要大于45个柱,不符合标准 循环获取直到符合 - records = exchange.GetRecords(); - // Log("Sleep"); - Sleep(1000); - - } - // Log(records); - var macd = TA.MACD(records, 12, 26, 9); //调用指标函数, 参数为MACD 默认的参数。 - // var ma5 = TA.MA(records,5); - // var ma25 = TA.MA(records, 25); - // var ma125 = TA.MA(records, 125); - // var ma250 = TA.MA(records, 250); - - var dif = macd[0]; //dif线 - var dea = macd[1]; //dea线 - var macd = macd[2]; // MACD柱 - - var len = records.length; //K线周期长度 - // ma30[len-1]0.02 - - - if (dif[len - 1] > dea[len - 1] && dif[len - 2] < dea[len - 2] ) { - return 1; - // Log("买入",records[len-1].Time) - } - //macd[len-2] dea[len - 2])) { - // Log("卖出",records[len-1].Time) - return 2; - } - return 0; -} -function updateProfit(accountInit, accountNow, price) { - var netNow = accountNow.Balance + accountNow.FrozenBalance + ((accountNow.Stocks + accountNow.FrozenStocks) * price); - var netInit = accountInit.Balance + accountInit.FrozenBalance + ((accountInit.Stocks + accountInit.FrozenStocks) * initTicker.Buy); - LogProfit(adjustFloat(netNow - netInit)); -} -var initTicker =null; -function main() { - var initAccount = exchange.GetAccount(); - initTicker= exchange.GetTicker(); - Log(initAccount); - var buyPrice = 0; - var sellPrice = 0; - var buyFlag = true; - var sellFlag = false; - // 如果策略临时中断重启了,此时已经买到币了就要考虑卖出了 - // if(initAccount.Stocks>=1){ - // sellFlag = true - // buyFlag = false - // } - var earn = 0; - var totalEarn =0 ; - while (true) { - CancelPendingOrders() - var ma = MACD_Cross(); - var ticker = exchange.GetTicker(); - var depth = exchange.GetDepth(); - var price = 0; - var amount = 0; - var cost = 0; - var nowAccount = exchange.GetAccount() - - - if (ma == 1&&buyFlag) { - buyFlag = false; - sellFlag = true; - price = depth.Asks[0].Price; - amount = depth.Asks[0].Amount; - // cost = price*amount * 0.002 - - buyPrice = price; - // Log("买前当前账户:",nowAccount,"买价格:",buyPrice+"->@量->",0.1); - // 买的时候扣除的是 币的个数 - var realBuy = _N((nowAccount.Balance/buyPrice)*(1-0.002),2) - - exchange.Buy(buyPrice,realBuy); - nowAccount = exchange.GetAccount() - // Log("买后当前账户:",nowAccount,"买价格:",buyPrice+"->@量->",0.1); - // exchange.Log(LOG_TYPE_BUY, 123, 1,1); - Log("买入时间",new Date(records[records.length-1].Time).toLocaleTimeString()) - // Log("买入时间",new Date(records[records.length-1].Time).toLocalTimeString()) - // Log("买入时间",new Date(records[records.length-1].Time).toLocalString()) - } else if(ma==2&&sellFlag) { - sellFlag = false; - buyFlag = true; - price = depth.Bids[0].Price; - amount = depth.Bids[0].Amount; - sellPrice = price ; - // cost = price*amount * 0.002 - earn = ((sellPrice - buyPrice) / buyPrice) *100 - totalEarn+=earn; - - Log("卖出时间,",new Date(records[records.length-1].Time).toLocaleTimeString(),"当前收益:"+earn.toFixed(2)+"总收益:"+totalEarn.toFixed(2)+"%@"); - // Log("卖前当前账户:",nowAccount,"卖价格:",sellPrice,"->@当前收益",earn.toFixed(2)) - exchange.Sell(sellPrice,_N(nowAccount.Stocks,2)) - // exchange.Log(LOG_TYPE_SELL, 123, 1,1); - nowAccount = exchange.GetAccount() - // Log("卖后当前账户:",nowAccount,"卖价格:",sellPrice,"->@量->",nowAccount.Stocks) - updateProfit(initAccount,nowAccount,price) - - }else{ - // LogProfit(0); - } - Sleep(5*1000); - } -} - -``` - -> 策略出处 - -https://www.fmz.com/strategy/92839 - -> 更新时间 - -2018-12-23 14:04:05 diff --git "a/\346\265\267\351\276\237.md" "b/\346\265\267\351\276\237.md" index a8770324..1af505b6 100644 --- "a/\346\265\267\351\276\237.md" +++ "b/\346\265\267\351\276\237.md" @@ -405,4 +405,4 @@ https://www.fmz.com/strategy/128382 > 更新时间 -2018-12-01 13:50:55 +2019-01-26 10:44:29 diff --git "a/\347\216\260\347\216\260\345\257\271\345\206\262(\346\220\254\347\240\226).md" "b/\347\216\260\347\216\260\345\257\271\345\206\262(\346\220\254\347\240\226).md" index c708c04b..92b1aaee 100644 --- "a/\347\216\260\347\216\260\345\257\271\345\206\262(\346\220\254\347\240\226).md" +++ "b/\347\216\260\347\216\260\345\257\271\345\206\262(\346\220\254\347\240\226).md" @@ -402,4 +402,4 @@ https://www.fmz.com/strategy/127154 > 更新时间 -2018-11-23 10:39:59 +2019-01-26 10:44:09 diff --git "a/\351\200\211\346\213\251\346\200\247\345\245\227\345\210\251.md" "b/\351\200\211\346\213\251\346\200\247\345\245\227\345\210\251.md" new file mode 100644 index 00000000..b6438c61 --- /dev/null +++ "b/\351\200\211\346\213\251\346\200\247\345\245\227\345\210\251.md" @@ -0,0 +1,307 @@ + +> 策略名称 + +选择性套利 + +> 策略作者 + +风云 + + + + + +> 源码 (cpp) + +``` cpp +//常量值 +const int MARGIN = 10; +const string DIRECTION = "buy"; +const int THRESHOLD = -1; +const double POSITION = 100;//下单量 +const double SELL_AT = 47; +const double PROFIT = 0.062 / MARGIN; //卖一半的盈利比 +enum operation { + open_buy, open_sell, nothing +}; +class Test_BM { +private: + //账户数量 + double amount; + //进行的操作 + operation op; + //购买时的价格和当前的价格 + double current_price; + double buy_price; + //表示交点 + int cross_plus_minus; + int cross_adx_plus; + int cross_adx_minus; + //表示当前的DI值 + double plus_di_now; + double minus_di_now; + double adx_now; + double sub_di;//DI间差值 + //对过去的一次记录 + double plus_di_last; + double minus_di_last; + double adx_last; + //私有操作 + void tick(); + int plus_order(string direction); + int minus_order(string direction); + +public: + Test_BM(); + double get_amount() + { + return amount; + } + void bm_00() { + //仅测试函数的正确性 + tick(); + plus_order("buy"); + Sleep(6000); + } + void bm_01();//套利策略 + +}; +Test_BM::Test_BM() { + amount = 0; + op = nothing; + current_price = -1; + buy_price = -1; + cross_plus_minus = -1; + cross_adx_plus = -1; + cross_adx_minus = -1; + plus_di_now = -1; + minus_di_now = -1; + adx_now = -1; +} +void Test_BM::tick() +{ //获取大部分数值,用于策略 + auto ticker = _C(exchange.GetTicker); //获取当前市场行情,_C容错处理 +// auto records = exchange.GetRecords(); //获取K线数据 + auto records = exchange.GetRecords(); +//Log(records); + auto plus_di = talib.PLUS_DI(records); //C++11 auto自动推断类型 + auto minus_di = talib.MINUS_DI(records); + auto adx = talib.ADX(records, 14); + cross_plus_minus = _Cross(plus_di, minus_di); + cross_adx_minus = _Cross(adx, minus_di); + cross_adx_plus = _Cross(adx, plus_di); + plus_di_now = plus_di[plus_di.size() - 1]; + minus_di_now = minus_di[minus_di.size() - 1]; + adx_now = adx[adx.size() - 1]; + sub_di = plus_di_now - minus_di_now; + current_price = ticker.Last; //最新价格 +} +int Test_BM::plus_order(string direction) +{ + double price = current_price; + int rv = 0; + if (direction == "buy") { + //操作多单时增加AMOUNT + exchange.SetDirection("buy"); //买入开多 + auto orderId = exchange.Buy(price, POSITION); + if (orderId.Valid)rv = 1; + } + else if (direction == "sell") { + //操作空单时增加AMOUNT + exchange.SetDirection("sell"); //卖出开空 + auto orderId = exchange.Sell(price, POSITION); + if (orderId.Valid)rv = 1; + } + return rv; +} +int Test_BM::minus_order(string direction) +{ + double price = current_price; + int rv = 0; + if (direction == "buy") { + exchange.SetDirection("closebuy"); //卖出平多 多单减少 + auto orderId = exchange.Sell(price, get_amount()); + if (orderId.Valid)rv = 1; + } + else if (direction == "sell") { + exchange.SetDirection("closesell"); //卖出Sell 开多‘sell’ 买入平空 + auto orderId = exchange.Buy(price, get_amount()); + if (orderId.Valid)rv = 1; + } + return rv; +} + +void Test_BM::bm_01() { + while (true) { + //op =nothing ,采取做多或做空,测试是否有交点存在 + tick(); + if (op == nothing) { + if (cross_plus_minus == 1 && plus_di_now < SELL_AT && sub_di<=0.618 ) { + if (plus_order("buy") == 0) break; + else { + plus_di_last = plus_di_now; + buy_price = current_price; + amount += POSITION; + op = open_buy; + Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now); + break; + } + } + if (cross_plus_minus == -1 && minus_di_now < SELL_AT && sub_di >= -0.618) + { + if (plus_order("sell") == 0)break; + else { + minus_di_last = minus_di_now; + buy_price = current_price; + amount += POSITION; + op = open_sell; + Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now); + break; + } + } + } + //op = open_buy 做空套利 + if (op == open_buy) + { + + //可以全卖 + if (plus_di_now >= SELL_AT) + { + if (minus_order("buy") == 0) break; + else { + amount = 0;//卖完,amount=0 + Log("全卖止盈"); + op = nothing; + Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now); + break; + } + } + //可以套利 + if ((current_price - buy_price) / (buy_price) > PROFIT) + { + if (minus_order("buy") == 0) break; + else { + amount = 0;//卖完,amount=0 + Log("全卖套利"); + op = nothing; + Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now); + break; + } + } + //可以止损 + if ((buy_price - current_price) / (buy_price) > PROFIT*0.375) + { + if (minus_order("buy") == 0) break; + else { + amount = 0;//卖完,amount=0 + Log("全卖止损"); + op = nothing; + Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now); + break; + } + } + //改方向,先全卖,再买空 + if (cross_plus_minus == -1 && minus_di_now < SELL_AT && sub_di >= -0.618) + { + if (minus_order("buy") == 0) break; + else { + amount = 0;//卖完,amount=0 + Log("全卖改方向"); + op = nothing; //先改变op + if (plus_order("sell") == 0)break; + else { + minus_di_last = minus_di_now; + buy_price = current_price; + amount += POSITION; + op = open_sell; + Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now); + break; + } + } + } + } + //op==open_sell + if (op == open_sell) + { + + //可以全卖 + if (minus_di_now >= SELL_AT) + { + if (minus_order("sell") == 0) break; + else { + amount = 0;//卖完,amount=0 + Log("全卖止盈"); + op = nothing; + Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now); + break; + } + } + //可以套利 + if ((buy_price - current_price) / (buy_price) > PROFIT) + { + if (minus_order("sell") == 0) break; + else { + amount = 0;//卖完,amount=0 + Log("全卖套利"); + op = nothing; + Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now); + break; + } + } + //可以止损 + if ((current_price - buy_price) / (buy_price) > PROFIT*0.375) + { + if (minus_order("sell") == 0) break; + else { + amount = 0;//卖完,amount=0 + Log("全卖止损"); + op = nothing; + Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now); + break; + } + } + //改方向,先全卖,再买多 + if (cross_plus_minus == 1 && plus_di_now < SELL_AT && sub_di <= 0.618) + { + if (minus_order("sell") == 0) break; + else { + amount = 0;//卖完,amount=0 + Log("全卖改方向"); + op = nothing; //先改变op + if (plus_order("buy") == 0) break; + else { + plus_di_last = plus_di_now; + buy_price = current_price; + amount += POSITION; + op = open_buy; + Log("plus_di:", plus_di_now, "minus_di:", minus_di_now, "adx:", adx_now); + break; + } + } + } + } + Sleep(6180); + } + +} + +void main() { + Log("Who care the bullshit"); + Log(_C(exchange.GetAccount)); + exchange.SetContractType("XBTUSD"); // 设置交易所期货类型 + exchange.SetMarginLevel(MARGIN); // 设置杠杆倍数 + exchange.SetDirection(DIRECTION); // 设置期货方向 + Test_BM *bm = new Test_BM(); + while (true) { + bm->bm_01(); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/134371 + +> 更新时间 + +2019-01-12 13:55:44 diff --git "a/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214 (V 1.0)|M Language \342\200\234Turtle Trading strategy\342\200\235 implementations(V 1.0).md" "b/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214 (V 1.0)|M Language \342\200\234Turtle Trading strategy\342\200\235 implementations(V 1.0).md" new file mode 100644 index 00000000..f7d02a50 --- /dev/null +++ "b/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214 (V 1.0)|M Language \342\200\234Turtle Trading strategy\342\200\235 implementations(V 1.0).md" @@ -0,0 +1,220 @@ + +> 策略名称 + +麦语言海龟策略体验 (V 1.0)|M Language “Turtle Trading strategy” implementations(V 1.0) + +> 策略作者 + +小小梦 + +> 策略描述 + +[trans] +> 尝个鲜 + +* 完全兼容文华麦语言语法 +* 基于发明者强大的低层, 完全支持数字货币现货期货与国内大宗商品期货 +* 兼容工作会一直持续, 目前兼容度90%大部分策略可以直接运行, 无需修改 +* API文档 https://www.fmz.com/bbs-topic/2569 + +>语言增强 + +发明者量化不单实现了麦语言的解释器, 而且还增强让其能与高级语言Javascript混合编程,放个例子 + +``` +%% +// 这里面可以调用发明者量化的任何API +scope.TEST = function(obj) { + return obj.val * 100; +} +%% +收盘价:C; +收盘价放大100倍:TEST(C); +上一个收盘价放大100倍:TEST(REF(C, 1)); // 鼠标移动到回测的K线上就会提示变量值 +``` + + ![IMG](https://www.fmz.com/upload/asset/81cecb83b47ecca04ddd63c3206eb0db.png) + +| + +> Background + + In 1994, Covel picked up an issue ofFinancial World and skimmed through an article titled "Wall Street's TopPlayers." Amongst famous investors like George Soros and Julian + Robertson,Covel noticed a name he did not recognize at 25th on the list: R. Jerry Parker,who stated that he was trained as a "Turtle" by Richard Dennis(another name Covel did not recognize). Parker was the only investor in the tophundred advertised as being "trained," and as an investor himself,Covel found this story intriguing. + +> Synopsis + + Richard Dennis made over $200 million as a trader. After having a debate with his partner, William Eckhardt, about whether trading is learnable or an inborn talent, they proposed + an experiment where they would spend two weeks training novices in the science of trading and then give them each $1 million to invest. The inspiration came from a trip Dennis + took to a turtle-breeding farm in Singapore, stating, "We are going to grow traders just like they grow turtles." + + Although each of the 1,000 applicants went through a rigorous application process designed to test their intelligence, ability to manage risk and mathematical skills, the makeup of + the chosen Turtles differed greatly; they included a Czechoslovakian-born blackjack master, a Dungeons and Dragons game designer, an evangelical accountant, a Harvard MBA, + a U.S. Air Force pilot and a former pianist. The Turtles would go on to gross over $150 million in four years. + +> Trading rules: + + In the capture of trend signals, the Turtle Trading Law uses a very important technical indicator, the Donchian channel. This channel is very similar to the familiar Bollinger Bands, + but it is somewhat different in terms of specific calculations. + + Richard Donchian invented this indicator. It consists of three curves of different colors. The indicator uses the highest price within the period (usually 20, some platform system + settings can be changed, some can not be set) And the lowest price to show the volatility of the market price, when the channel is narrow, it means that the market volatility is + small, otherwise the channel width means that the market volatility is relatively large. + + When the price breaks through the upper track of the channel, it is a possible buy signal; on the contrary, it is a possible sell signal when breaking the lower track. + + The calculation methods of the Donchian channel are as follows: + + Upper rail = Max (highest, n), the highest value of the highest price of n days + + Lower rail = Min (lowest price, n), the minimum value of the lowest price of n days + + Middle rail = (upper rail + lower rail)/2 + + Within the framework of multi-factor analysis in the financial sector, this strategy predicts the price trend after the breakthrough is based on the validity hypothesis of the + momentum factor. Of course, the effectiveness of this factor has indeed been rigorously verified and complemented by the Fama-French three-factor model and is widely used in + financial markets. + + Of course, we can optimize and use more reasonable trend-breaking indicators. + + So, since the momentum factor is a factor that has been publicly and widely used, then why can the Turtle Trading Law stand out from the crowd? The answer is simple. The Turtle + Trading Rules define a set of very strict rules for position control and stop-loss. Let's take a look at each one. + +- 1. The basic unit of the position N + + The principle of the Turtle Rule is to define a small unit (Unit) so that the expected value fluctuation of the position corresponds to 1% of the total net assets. In other words, if you + buy the assets of this small unit, the market value of the position on that day will not change by more than 1% of the total net assets. + + So how do you define this small unit? How do you estimate the value fluctuations that this small unit can bring? First, in predicting the value volatility of this small unit (this value + volatility is called N), the Turtle Strategy uses a method of statistically averaging historical price volatility. The specific calculation formula is as follows: + + TrueRange = Max(High−Low, High−PreClose, PreClose−Low) + + N = (the sum of the N values ​​of the previous 19 days + the TrueRange at the time) / 20 + + Among them, High indicates the highest price of the day, Low indicates the lowest price of the day, and PreClose indicates the closing price of the previous day. We can see from + the definition that the value of N can indeed properly express the recent fluctuations in the price of the asset. + + Thus, a Unit should be calculated like this: + + Unit = (1%*Total_net)/N, Total_net is the total net asset value + + It can be seen that the price volatility of a Unit's assets = 1% of the total net assets + +- 2. When to open a position + + The action of opening a position comes from the generation of a trend breakthrough signal. If the current price breaks through the upper track, it will generate a buy position + signal. If the current price falls below the lower track, it will generate a short position signal (the cryptocurrency market is supported by the short sale!) + + Initial build size = 1 Unit + +- 3. When is the adding position? + + If the holding position is long positions and the price of the asset has increased by 0.5N based on the last holding position (or adding position), then add a unit of long position; + + If the holding position is short position and the price of the asset has dropped by 0.5N based on the last position (or adding position), then add a unit of short position. + + We have seen that the Turtle Strategy is actually a strategy of chasing up and down. + +- 4. How to do dynamic stop loss + + If the holding position is long positions and the price of the asset falls by 2N based on the last holding position (or adding position), then stop loss for all positions; + + If the holding position is short position and the price of the asset has increased by 2N based on the last holding position (or adding position), then the entire position must be closed. + + Of course, the user can customize the dynamic stop loss plan, such as a 0.5N drop to start partial closing position, instead of waiting for a 2N decline after a rush to close the + position; after all, the impact cost is there. + +- 5. How to make a profit, can you customizethe dynamic take profit? + + In the Turtle Rule, the Take Profit signal is generated like this: + + If the holding position is long positions and the current asset price falls below the lower track of the 10th Donchian channel, all position closed; + + If the holding position is short position and the current asset price rises above the upper track of the 10th Donchian channel, all position closed. + + Of course, users can customize the dynamic take profit plan, such as when the total net assets / initial net assets > 1.5, just take the profit. + +> Advantage + + The biggest advantage of the Turtle Trading Law is to help us establish an effective method of controlling the size of the position. + +> Disadvantage + + The turtle trading system has a common problem with the trend tracking strategy, which is the withdrawal of floating profit. The floating profit that is chasing up is likely to be spit + out due to a sudden drop. It is very strong in the big trend, and it is not perform very well in the shock market. + + Enough talk, let’s make it happen! + +> M language + + After 6 years of development, it has absorbed feedback from hundreds of thousands of users. It is a mature and stable model development platform. M language is the most + widely used programmatic model development platform in China. + + The M language advocates the building block programming concept, which encapsulates complex algorithms into individual functions and adopts the construction mode of “small + syntax, large function”. Although the grammar is simple, it can also support logical and complex financial applications with a special programmatic data structure and a rich financial statistical function library. + + The function library of the M language is updated frequently, and new functions can be added at any time according to the new requirements of the customer to support the new + ideas and new applications of the programmer. + + The FMZ Quant not only realized the interpreter of the grammar of M language, but also enhanced its ability to mix programming with high-level language such as JavaScript. + +> For example: + + // here you can call any API function from FMZ Quant + scope.TEST = function(obj) { + return obj.val * 100; + } + Closing price: C; + + The closing price is magnified 100 times: TEST(C); + + The previous closing price is magnified 100 times: TEST(REF(C, 1)); // The mouse moves to the backtest K line and the variable value is displayed. + +![IMG](https://www.fmz.com/upload/asset/4df7045852493754488aeae0a7bf6234.png) +![IMG](https://www.fmz.com/upload/asset/610e6778a210ed806a8526a6091b06d6.png) + +[/trans] + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2018-06-01 00:00:00 +end: 2018-11-21 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","balance":500000,"minfee":0,"fee":[0,0]}] +*) + +// this demonstration mainly uses the Turtle Trading Rules to demonstrate the method of writing "position management, maximum position control and other fund management". +// only the demonstration key content statement is annotated, other statements please consult customer service +//This model is only used to demonstrate the use of this strategy, and enters the market accordingly, at your own risk. + +TR:=MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW));// True volatility +ATR:MA(TR,26); // Find a simple moving average of the true amplitude in 26 cycles, shown in the figure +ZOOM:=IFELSE(ISCONTRACT('@Futures_(?!CTP).*'), CLOSE, 1); // Compatible with cryptocurrency futures as margin +LOT:=((MONEYTOT*0.01*ZOOM)/(UNIT*ATR))*ZOOM;// Calculate the number of one hand based on 1% of equity +TC..IFELSE(ISCONTRACT('@Futures.*'), INTPART(LOT), LOT); // Compatible futures and spot ISCONTRACT starts with @ to indicate matching exchange name, support +MTC..4*TC; // Total position +HH^^HV(H,20); // Attached to the main image display +LL^^LV(L,20); // Attached to the main image display +CROSSUP(C,HH)&&ISLASTBK=0&&ISLASTSK=0&&BARPOS>=26,BK(TC);// The latest price exceeds the highest value of 20 cycles, the first time to buy long, the quality is TC hands +CROSSDOWN(C,LL)&&ISLASTBK=0&&ISLASTSK=0,SK(TC); // The latest price fell below the lowest value of 20 cycles, the first time to sell short, the quality is TC hands +C>=BKPRICE+0.5*ATR&&BKVOL0,SP(BKVOL);// The latest price is less than the opening price minus 2 times of ATR, stop loss and close position +C>=(SKPRICE+2*ATR)&&SKVOL>0,BP(SKVOL); // The latest price is greater than the opening price plus 2 times of ATR, stop loss and close position +CROSSUP(H,HV(H,10))&&SKVOL>0,BP(SKVOL);// The highest price up-cross the highest price of 10 cycles, closing the position +CROSSDOWN(L,LV(L,10))&&BKVOL>0,SP(BKVOL); // The lowest price down-cross the lowest price of 10 cycles, closing position +TRADE_AGAIN(10); +``` + +> 策略出处 + +https://www.fmz.com/strategy/132298 + +> 更新时间 + +2018-12-29 09:53:01 diff --git "a/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214.md" "b/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214.md" index 37c405e7..771e39c7 100644 --- "a/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214.md" +++ "b/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214.md" @@ -34,6 +34,13 @@ scope.TEST = function(obj) { ![IMG](https://www.fmz.com/upload/asset/81cecb83b47ecca04ddd63c3206eb0db.png) +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|RATIO|0.01|资金比率| > 源码 (麦语言) @@ -49,24 +56,35 @@ exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","balance":500000,"minfee": //该示范主要用海龟交易法则,演示“头寸计算,最大仓位控制等资金管理”的编写方法 //编写示范中,只对示范重点内容语句进行了注释,其他语句请自行翻译,或者咨询客服 //该模型仅仅用来示范演示使用,依此入市,风险自负。 - +ATRPERIOD:=20; // ATR波动周期 +SHORTPERIOD:=20; // 入市短周期 +LONGPERIOD:= 55; // 入市长周期 +VARIABLE:ISLASTFAILURE:=1; // 上次是否止损离场, 全局变量过滤信号 TR:=MAX(MAX((HIGH-LOW),ABS(REF(CLOSE,1)-HIGH)),ABS(REF(CLOSE,1)-LOW));//真实波幅 -ATR:MA(TR,26); //求26个周期内真实波幅的简单移动平均, 在附图显示 +ATR:MA(TR,ATRPERIOD); //求20个周期内真实波幅的简单移动平均, 在附图显示 ZOOM:=IFELSE(ISCONTRACT('@Futures_(?!CTP).*'), CLOSE, 1); // 兼容数字货币期货币为保证金 -LOT:=((MONEYTOT*0.01*ZOOM)/(UNIT*ATR))*ZOOM;//根据权益的1%计算下单手数 +LOT:=((MONEYTOT*RATIO*ZOOM)/(UNIT*ATR))*ZOOM;//根据权益的1%计算下单手数 TC..IFELSE(ISCONTRACT('@Futures.*'), INTPART(LOT), LOT); // 兼容期货与现货ISCONTRACT以@开头表示匹配交易所名子, 支持正则 MTC..4*TC; //总的持仓头寸 -HH^^HV(H,20); // 附加到主图显示 -LL^^LV(L,20); // 附加到主图显示 -CROSSUP(C,HH)&&ISLASTBK=0&&ISLASTSK=0&&BARPOS>=26,BK(TC);//最新价超过20周期的最高值,首次买入开仓,手数为TC手 -CROSSDOWN(C,LL)&&ISLASTBK=0&&ISLASTSK=0,SK(TC); //最新价跌破20周期的最低值,首次卖出开仓,手数为TC手 +HH^^HV(H,SHORTPERIOD); // 附加到主图显示 +LL^^LV(L,SHORTPERIOD); +HHH^^HV(H,LONGPERIOD); +LLL^^LV(L,LONGPERIOD); +ISEMPTY:=ISLASTBK=0&&ISLASTSK=0; +CROSSUP(C,HH)&&ISEMPTY&&ISLASTFAILURE,BK(TC);//最新价超过短周期的最高值,首次买入开仓,手数为TC手 +CROSSDOWN(C,LL)&&ISEMPTY&&ISLASTFAILURE,SK(TC); //最新价跌破短周期的最低值,首次卖出开仓,手数为TC手 +CROSSUP(C,HHH)&&ISEMPTY,BK(TC);//最新价超过长周期的最高值,首次买入开仓,手数为TC手 +CROSSDOWN(C,LLL)&&ISEMPTY,SK(TC); //最新价跌破长周期的最低值,首次卖出开仓,手数为TC手 C>=BKPRICE+0.5*ATR&&BKVOL0,SP(BKVOL);//最新价小于开仓价减去2倍的ATR,止损平仓 -C>=(SKPRICE+2*ATR)&&SKVOL>0,BP(SKVOL); //最新价大于开仓价加上2倍的ATR,止损平仓 -CROSSUP(H,HV(H,10))&&SKVOL>0,BP(SKVOL);//最高价上穿10周期最高价,平仓 -CROSSDOWN(L,LV(L,10))&&BKVOL>0,SP(BKVOL); //最低价下穿10周期的最低价,平仓 +NEEDSTOP:=(C<=(BKPRICE-2*ATR)&&BKVOL>0) OR (C>=(SKPRICE+2*ATR)&&SKVOL>0); +NEEDLEAVE:=(CROSSUP(H,HV(H,10))&&SKVOL>0) OR (CROSSDOWN(L,LV(L,10))&&BKVOL>0); +NEEDSTOP OR NEEDLEAVE,CLOSEOUT; +ISLASTFAILURE..IF(NEEDSTOP OR NEEDLEAVE, NEEDSTOP, ISLASTFAILURE); +INFO(NEEDSTOP, '止损离场'); +INFO(NEEDLEAVE, '成功离场'); TRADE_AGAIN(10); +MULTSIG(1, 1, 10); ``` > 策略出处 @@ -75,4 +93,4 @@ https://www.fmz.com/strategy/126968 > 更新时间 -2018-12-06 16:01:33 +2018-12-24 13:35:31 diff --git "a/\357\274\210\345\255\246\344\271\240\357\274\211API\344\270\216\346\225\231\347\250\213\345\206\205\344\273\243\347\240\201\345\255\246\344\271\240\346\226\207\344\273\266.md" "b/\357\274\210\345\255\246\344\271\240\357\274\211API\344\270\216\346\225\231\347\250\213\345\206\205\344\273\243\347\240\201\345\255\246\344\271\240\346\226\207\344\273\266.md" new file mode 100644 index 00000000..d6461e82 --- /dev/null +++ "b/\357\274\210\345\255\246\344\271\240\357\274\211API\344\270\216\346\225\231\347\250\213\345\206\205\344\273\243\347\240\201\345\255\246\344\271\240\346\226\207\344\273\266.md" @@ -0,0 +1,445 @@ + +> 策略名称 + +(学习)API与教程内代码学习文件 + +> 策略作者 + +中本大料 + + + + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2018-11-26 00:00:00 +end: 2018-12-26 00:00:00 +period: 1h +exchanges: [{"eid":"OKCoin_EN","currency":"BTC_USD"}] +*/ + +// +// +// +var tradeAmount = 0.1; +var wave = 5 +var tide = 20 +//------------------------- +var bars = null; +var newbar = null; +var Stock = null; +var Balance = null; +var depth = null; +var accountData = null; +var triggerofTrade = null; +var bidPrice = null +var askPrice = null +var oldtime = "oldtime" +var newtime = "newtime" + +var next = false + +function Data(){ //数据预处理 + depth = _C(exchange.GetDepth); + accountData = _C(exchange.GetAccount); //尽量是取一个数组回来拆分,避免数据差异 + Stock = accountData.Stocks; + Balance = accountData.Balance; + bars = _C(exchange.GetRecords); + // newtime = bars[bars.length-1].Time + // if(newtime == oldtime){ + // return next = true + // } + // newbar = bars + // oldtime = newtime + Log(bars[bars.length-1]) +} + + +function main() { + while(true){ + // next = false + Data() + // Log(next) + // Log("!!!" + newbar[newbar.length-1].Time); + // if(next = true){ + // continue + // // Log("!!!" + newbar[newbar.length-1].Time); + // } + + // // Log("!!!"+ newbar) + // //Sleep(1000) + // Log("!!!" + newbar[newbar.length-1].Time); + Sleep(10000) + } + // var begintime = new Date().getTime() + + // Log("测试1 ^"); + // var s ="hello "+"world!"; + // Log(s[0]); + // Log(s); + // Log(s.length) + // Log(exchange.GetAccount()); + + // Log("\n"); + // Log("测试2 ^"); + // var symbol = "BTC_USDT" + // if(symbol.endsWith('USDT')){ + // Log("当前计价币为USDT") + // } + // var a = symbol.split('_')[0]; //?!数组里面取第一个是如何操作的 + // Log(a,typeof(a)); + // Log(a[0]); + // var b = "USDT"; //测试单引号和双引号的区别,看起来并没有区别 + // var c = 'USDT'; + // Log(b,typeof(b),c,typeof(c)); + + // Log("\n"); + // Log("测试3 对象的操作1^"); + // var xiaoming = {name:"大傻",birth:1990}; + // var key = "birth"; + // Log(xiaoming.name); + // Log(xiaoming[key]); + // xiaoming.score = 80; + // if('score' in xiaoming){ + // Log(xiaoming) + // } + + // Log("\n"); + // Log("测试4 对象的操作2^"); + // var ticker = exchange.GetTicker(); + // Log(ticker); + // var price = ticker.Last; + // Log(price); + // Log(ticker.Last); + + // Log("\n"); + // Log("测试5 布尔值操作^"); + // var x = 1.5; + // var y = 2; + // var z = 3; + // if(x > y){ + // Log("X > Y, 算对了"); + // } + // else{ + // Log("X < Y, 算错了"); + // } + // if(x < y || x == 1){ + // Log("算对了") //==等于 !=不等于 &&且 + // } + + // Log("\n"); + // Log("^学习6 数组操作^"); + // var arr = [1,2,3.14,"hello",'hello']; + // Log(arr.length,"_",arr[5],arr[4].length); + // Log(arr.indexOf("hello")); + // var records = exchange.GetRecords(); + // Log(records); + // var ma = null + // //if(records && records.length > 20 ){ + // //Log("K线Bar的数量大于20,可以生成均线") + // //var ma10 = TA.MA(records,10) + // //Log("ma10",ma10) + // //var ma20 = TA.MA(records,20) + // //Log("ma20",ma20) + // //Log(ma10[11]); + // //$.PlotLine('MA10', ma[11]);/ + // //} + // //else{ + // //Log("K线数量不足,请获取更多K线或者重新调整均线周期") + // // } + + // Log("\n"); + // Log("^学习7 数据常用操作^"); + // var d; + // Log(d); //?为何没有出现undefine + // var tom = {name:"tom",age:10}; + // Log(tom.name,tom.gender); + + // Log("\n"); + // Log("^学习8 定义、调用函数^"); + // function test(a,b){ + // Log(a,b,a+b); + // return; + // } + // test(1); //null NaN分别是什么意思? + + // Log("\n"); + // Log("^学习9 数据之间的转换^"); + // var xa = 123; + // Log(String(xa),typeof(String(xa))); + // Log(xa.toString(),typeof(xa.toString())); + // var xb = '{"free":1,"frozen":2}'; //注意这个单引号 + // Log(xb,typeof(xb)); + // object_xb = JSON.parse(xb); //将JSON字符串转化为对象 + // Log(object_xb,typeof(object_xb)); + // var obj ={address:"ABC",name:"123"} + // var jsonstr = JSON.stringify(obj); + // Log(obj,typeof(obj),jsonstr,typeof(jsonstr)); + + // Log("\n"); + // Log("^学习10 条件语句判断^"); + // var ticker1 = exchange.GetTicker(); + // Log(ticker1.Last) + // if(ticker1.Last < 3000){ + // Log("ticker1 小于 3000") + // }else if(ticker1.Last > 3000 && ticker1.Last<3500){ + // Log("ticker1 大于3000 小于3500") + // }else{ + // Log("ticker1 大于 > 3500"); + // } + // var symbol10 = "ETH"; + // switch(symbol10){ //使用switch+case+break + // case "ETH": + // Log("当前交易对象为ETH") + // break; + // case "BTC": + // Log("当前交易对象为BTC") + // break; + // //case "ETH": + // //Log("当前交易对象为BTC") + // //break; + // } + + // Log("\n"); + // Log("^学习11 java循环^"); + // var records11 = exchange.GetRecords(); + // Log(records11.length) + // if(records11){ + // for(i=0;i<29;i++){ + // Log(records11[i]) + // } + // } + // $.PlotRecords(records11, 'BTC'); + // Log("v学习结束v"); + // Log("\n"); + + // Log("\n"); + // Log("^学习12 遍历对象^"); + // var assets12 ={"BTC":1.2,"BCH":1,"ETH":12}; + // for(var a12 in assets12){ + // Log(a12,assets12[a12]) + // } + // Log("-----------------------------"); + // var assets121 ={"BTC":1.2,"BCH":1,"ETH":12}; + // for(var a121 in assets121){ + // if(a121 == "ETH"){ + // continue //如果满足条件则绕开这次循环 + // } + // Log(a121,assets121) + // } + // Log("v学习结束v"); + // Log("\n"); + + // Log("^学习13 while循环^"); + // var a13 = 0 + // while(a13 == 10){ //若这里为 a13 = 0 则一次都没有执行 + // Log("while",a13); + // a13 ++ ; + // } + // var a131 = 0 + // do{ //使用do while 循环至少会执行一次 + // Log("do",a131); + // a131++; + // }while(a131 == 0) + // Log("-----------------------------"); + // var n13 = 0 + // var sum13 = 0 + // while(true){ + // sum13 += n13 + // n13++ + // if(n13 > 10){ + // Log("朕的气数尽了,先走一步",n13,sum13) + // break + // } + // } + // Log("v学习结束v"); + // Log("\n"); + + // Log("^学习14 定义一个函数^"); + // function go1s(){ + // var time14 = new Date().getTime() + // Log(time14) + // Sleep(1000) + // var endtime14 =new Date().getTime() + // Log(endtime14 - time14) + // } + // go1s() + // function timenow(){ + // Log("当前时间:",_D()) //_D()为平台封装好的函数 + // } + // timenow() + // function lastrecords(){ + // var records14 = exchange.GetRecords() //Getrecords传入的是一个时间段 + // var bar14 = records14[records14.length-1] + // Log(bar14.Time) //.Time是bar的一个属性 + // Log("最后一根 bar的时间是",_D(bar14.Time)) + // } + // lastrecords() + + // Log("v学习结束v"); + // Log("\n"); + + // Log("^学习15 获取账户信息^"); + // var account15 = exchange.GetAccount() + // Log(account15) + // exchange.Buy(3700,2) + // var accountstate = exchange.GetAccount() + // Log(accountstate) + // Log(exchange.GetOrders()) //看看取消订单里面是怎么做的 + // var trade15 = exchange.GetTrades() + // Log(trade15) //Log(order15) + // Log("v学习结束v"); + // Log("\n"); + + // //LogReset() + // Log("^学习16 使用指标函数,用函数判断均线交叉^"); + // var records16 = null + // while(1){ + // records16 = exchange.GetRecords() + // if(records16.length>30){ + // break + // } + // Sleep(100) + // } + // var ma167 = TA.MA(records,7) + // var ma1630 = TA.MA(records,30) + // var cross16 = _Cross(ma167,ma1630) + // Log("crosspoint",cross16,"#FF0000") + // Log("v学习结束v"); + // Log("\n"); + + // LogReset() + // Log("^学习17 可视化^"); + // var i17 = 0 + // while(1){ + // var random17 = Math.random() + // var num17 = random17 * 10 + // LogProfit(num17,_D()) + // Sleep(5000) + // i17 ++ + // if(i17 > 50){ + // break + // } + // } + // Log(i17,num17) + // LogStatus("当前时间:",_D(),"随机值:",num17,"\n","乘以10之前的随机数:",random17) + // Log("v学习结束v"); + // Log("\n"); + + // LogReset() + // Log("^学习18 循环测试^"); + // var i18 =1 + // while(i18<50){ + // var orders18 = 1; + // // while (!(orders18 - 50 < 0)){ + // // Sleep(1000); + // // orders18++ + // // } + // while(orders18<50){ + // orders18++ + // } + // i18++ + // //Log(i18) + // Log(orders18) + // } + // Log("v学习结束v"); + // Log("\n"); + + // LogReset() + // Log("^学习19 获取K线信息的时间间隔^"); + // for(var i20 = 0; i20 < 10; i20++){ + // var records20 = exchange.GetRecords(); + // Log(records20) + // } + // for(var i21 = 0; i21 < 10; i21++){ + // var ticker20 = exchange.GetTicker(); + // Log(ticker20) + // } + // Log("v学习结束v"); + // Log("\n"); + + // LogReset() + // Log("^学习20 持续获取数组,防止获取过短^"); + //function Data(){ + // var Stock = null; + // var Balance = null; + // var tide =65; + // var accountData = _C(exchange.GetAccount); + // Stock = accountData.Stocks; + // Balance = accountData.Balance; + // bars = _C(exchange.GetRecords); + // Log(bars); + // Log(bars.length) + // var bars = "0" + // Log(bars.length) + // bars = _C(exchange.GetRecords) + // // if (bars.length < tide+1){ + // // bars = _C(exchange.GetRecords); + // // } + // // while(bars.length < tide){ + // // bars = _C(exchange.GetRecords) + // // } + // Log(bars.length) + + // // while(true){ + // // var bars = _C(exchange.GetRecords); + // // if(bars.length < tide + 1){ + // // continue + // // } + // // return bars + // Log(bars,bars.length) + + + // } + // for (iii20 = 1; iii20<30; iii20++){ + // Data() + // ; + // Sleep(500); + //} + + // Data() + // Log(bars) + // Log(bars.length) + // while(bars.length < tide+1){ + // bars = _C(exchange.GetRecords); //可以在main循环中再增加一个 if 验证 e.g. if bars.length < 10,msg = "K线数据获取失败,自动重试" return + // Sleep(500); + // } + //在 均线策略等需要通过K线形态判断买卖时机和方向的策略中, 在回测模式中, 如何保证一直是用最新的K线来进行判断指标? + + + + + + + + + + + + + + + + + + + Log("+++++++++++++++++++++++++++++"); + // var endtime = new Date().getTime() + // Log("执行程序总耗时为:",endtime-begintime,"毫秒") + Log("+++++++++++++++++++++++++++++") + + + +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/131864 + +> 更新时间 + +2019-01-02 15:41:01 From 484531576aec88cbcef31a708995eeadf0f1d358 Mon Sep 17 00:00:00 2001 From: Zero Date: Sun, 10 Mar 2019 14:59:52 +0800 Subject: [PATCH 11/19] init --- "CTP \346\234\237\350\264\247.md" | 2 +- ...egy\342\200\235 implementations(V 1.0).md" | 15 +- ...04\345\220\210\347\255\226\347\225\245.md" | 2 +- ...3\350\257\225\344\275\277\347\224\250).md" | 564 ------------------ README.md | 14 +- ...\347\255\226\347\225\245|RUMI Strategy.md" | 2 +- ...5|Three-MA Price Breakthrough Strategy.md" | 2 +- ...44\344\272\222\346\250\241\346\235\277.md" | 118 ++++ ...high and low - Ichimoku trend strategy.md" | 2 +- ...y of Traditional MA Index and KD Index.md" | 2 +- ...\347\225\245|DMI and High-Low Strategy.md" | 2 +- ...50\346\234\237\345\245\227\345\210\251.md" | 8 +- ...63\350\241\241\347\255\226\347\225\245.md" | 10 +- ...7\225\245|Upgraded Thermostat Strategy.md" | 2 +- ...245|Double Average Lines -DDI Strategy.md" | 2 +- ...5\245|Double MA and Formation Strategy.md" | 2 +- ...0\210|Combination of Double MA and RSI.md" | 2 +- ...37\345\215\225\347\263\273\347\273\237.md" | 2 +- ...ative Strength Strategy Based on Price.md" | 2 +- ...\225\245|Channel strategy based on ATR.md" | 2 +- ...6\347\225\245 \350\214\203\344\276\213.md" | 11 +- ...11\350\241\250\346\240\274\357\274\211.md" | 337 +++++++++++ ...25\245|Multilevel Take Profit Strategy.md" | 2 +- ...rage of difference - combined with ATR.md" | 2 +- ...45|SAR and Price High and Low Strategy.md" | 2 +- ...Version of ICHIMOKU KINKO HYO Strategy.md" | 2 +- ...ndard deviation price channel strategy.md" | 2 +- ...lity ATR - Track Breakthrough Strategy.md" | 2 +- ...37\346\261\244\347\255\226\347\225\245.md" | 281 +++++++++ ...226\347\225\245|Trading Chaos Strategy.md" | 2 +- ...7\347\255\226\347\225\245|PBX Strategy.md" | 2 +- ...ce announcements and sell Delist coin.md" | 99 +++ ...26\347\225\245\346\241\206\346\236\266.md" | 4 +- ...347\233\212 (\345\244\215\345\210\266).md" | 88 +++ ...rice high and low - ROC index strategy.md" | 2 +- ... Low - Volume Index Weighting Strategy.md" | 2 +- ...gh Winning Rate - ORB Trading Strategy.md" | 2 +- 37 files changed, 985 insertions(+), 614 deletions(-) rename "\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214 (V 1.0)|M Language \342\200\234Turtle Trading strategy\342\200\235 implementations(V 1.0).md" => "M Language \342\200\234Turtle Trading strategy\342\200\235 implementations(V 1.0).md" (96%) delete mode 100644 "OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245(\346\250\241\346\235\277\346\265\213\350\257\225\344\275\277\347\224\250).md" create mode 100644 "\344\272\244\344\272\222\346\250\241\346\235\277.md" create mode 100644 "\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211.md" create mode 100644 "\346\265\267\351\276\237\346\261\244\347\255\226\347\225\245.md" create mode 100644 "\347\210\254\345\217\226\345\270\201\345\256\211\345\205\254\345\221\212\350\207\252\345\212\250\345\207\272\345\224\256\345\260\206\350\246\201\344\270\213\346\236\266\345\270\201|crawl Binance announcements and sell Delist coin.md" rename "\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.md" => "\347\255\226\347\225\245\346\241\206\346\236\266.md" (99%) create mode 100644 "\347\273\237\350\256\241\346\224\266\347\233\212 (\345\244\215\345\210\266).md" diff --git "a/CTP \346\234\237\350\264\247.md" "b/CTP \346\234\237\350\264\247.md" index 767ecdf5..70fdbbc4 100644 --- "a/CTP \346\234\237\350\264\247.md" +++ "b/CTP \346\234\237\350\264\247.md" @@ -5,7 +5,7 @@ CTP 期货 > 策略作者 -tyz +bbsang > 策略描述 diff --git "a/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214 (V 1.0)|M Language \342\200\234Turtle Trading strategy\342\200\235 implementations(V 1.0).md" "b/M Language \342\200\234Turtle Trading strategy\342\200\235 implementations(V 1.0).md" similarity index 96% rename from "\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214 (V 1.0)|M Language \342\200\234Turtle Trading strategy\342\200\235 implementations(V 1.0).md" rename to "M Language \342\200\234Turtle Trading strategy\342\200\235 implementations(V 1.0).md" index f7d02a50..6e0111be 100644 --- "a/\351\272\246\350\257\255\350\250\200\346\265\267\351\276\237\347\255\226\347\225\245\344\275\223\351\252\214 (V 1.0)|M Language \342\200\234Turtle Trading strategy\342\200\235 implementations(V 1.0).md" +++ "b/M Language \342\200\234Turtle Trading strategy\342\200\235 implementations(V 1.0).md" @@ -1,7 +1,7 @@ > 策略名称 -麦语言海龟策略体验 (V 1.0)|M Language “Turtle Trading strategy” implementations(V 1.0) +M Language “Turtle Trading strategy” implementations(V 1.0) > 策略作者 @@ -171,8 +171,8 @@ scope.TEST = function(obj) { The previous closing price is magnified 100 times: TEST(REF(C, 1)); // The mouse moves to the backtest K line and the variable value is displayed. -![IMG](https://www.fmz.com/upload/asset/4df7045852493754488aeae0a7bf6234.png) -![IMG](https://www.fmz.com/upload/asset/610e6778a210ed806a8526a6091b06d6.png) + ![IMG](https://www.fmz.com/upload/asset/16ad22541f647db833cf.png) + ![IMG](https://www.fmz.com/upload/asset/168d0e609175942064c3.png) [/trans] @@ -182,10 +182,11 @@ scope.TEST = function(obj) { ``` pascal (*backtest -start: 2018-06-01 00:00:00 -end: 2018-11-21 00:00:00 +start: 2018-11-01 00:00:00 +end: 2018-12-19 00:00:00 period: 1d -exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","balance":500000,"minfee":0,"fee":[0,0]}] +exchanges: [{"eid":"Futures_BitMEX","currency":"XBT_USD"}] +args: [["ContractType","XBTUSD",126961]] *) // this demonstration mainly uses the Turtle Trading Rules to demonstrate the method of writing "position management, maximum position control and other fund management". @@ -217,4 +218,4 @@ https://www.fmz.com/strategy/132298 > 更新时间 -2018-12-29 09:53:01 +2019-01-28 11:16:10 diff --git "a/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" "b/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" index 979a6348..8c42fb4b 100644 --- "a/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" +++ "b/MACD+MA\346\214\207\346\240\207\347\273\204\345\220\210\347\255\226\347\225\245.md" @@ -14,7 +14,7 @@ littleDreamXX - 数据合约:指数合约 - 交易合约:主力合约 - 适合品种:商品期货 -- 官方网站:WWW.QUANT.LA +- 官方网站:www.quantinfo.com - 副图 副图显示:MACDDIFF,公式 MACDDIFF:MACDVALUE-AVGMACD; diff --git "a/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245(\346\250\241\346\235\277\346\265\213\350\257\225\344\275\277\347\224\250).md" "b/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245(\346\250\241\346\235\277\346\265\213\350\257\225\344\275\277\347\224\250).md" deleted file mode 100644 index 292d613d..00000000 --- "a/OKCoin\346\234\237\350\264\247\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245(\346\250\241\346\235\277\346\265\213\350\257\225\344\275\277\347\224\250).md" +++ /dev/null @@ -1,564 +0,0 @@ - -> 策略名称 - -OKCoin期货跨期对冲策略(模板测试使用) - -> 策略作者 - -小小梦 - -> 策略描述 - -OKCoin期货跨期对冲策略(模板) - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|OpMode|0|现货-下单方式: 吃单|挂单| -|MaxSpace|0.5|现货-挂单失效距离| -|SlidePrice|0.1|现货-下单滑动价(元)| -|MaxAmount|0.8|现货-开仓最大单次下单量| -|RetryDelay|500|现货-失败重试(毫秒)| -|MAType|0|现货-均线算法: EMA|MA|AMA(自适应均线)| -|Interval|300|期货—失败重试间隔(毫秒)| -|F_SlidePrice|2|期货—下单滑价(元)| -|lv|0.5|期货—滑价增长率| -|max_open_lv|true|期货—开仓滑价最大增长率| -|max_cover_lv|true|期货—平仓滑价最大增长率| - - -> 源码 (javascript) - -``` javascript -// 现货部分 -function CancelPendingOrders(e, orderType) { - while (true) { - var orders = e.GetOrders(); - if (!orders) { - Sleep(RetryDelay); - continue; - } - var processed = 0; - for (var j = 0; j < orders.length; j++) { - if (typeof(orderType) === 'number' && orders[j].Type !== orderType) { - continue; - } - e.CancelOrder(orders[j].Id, orders[j]); - processed++; - if (j < (orders.length - 1)) { - Sleep(RetryDelay); - } - } - if (processed === 0) { - break; - } - } -} - -function GetAccount(e, waitFrozen) { - if (typeof(waitFrozen) == 'undefined') { - waitFrozen = false; - } - var account = null; - var alreadyAlert = false; - while (true) { - account = _C(e.GetAccount); - if (!waitFrozen || (account.FrozenStocks < e.GetMinStock() && account.FrozenBalance < 0.01)) { - break; - } - if (!alreadyAlert) { - alreadyAlert = true; - Log("发现账户有冻结的钱或币", account); - } - Sleep(RetryDelay); - } - return account; -} - - -function StripOrders(e, orderId) { - var order = null; - if (typeof(orderId) == 'undefined') { - orderId = null; - } - while (true) { - var dropped = 0; - var orders = _C(e.GetOrders); - for (var i = 0; i < orders.length; i++) { - if (orders[i].Id == orderId) { - order = orders[i]; - } else { - var extra = ""; - if (orders[i].DealAmount > 0) { - extra = "成交: " + orders[i].DealAmount; - } else { - extra = "未成交"; - } - e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); - dropped++; - } - } - if (dropped === 0) { - break; - } - Sleep(RetryDelay); - } - return order; -} - -// mode = 0 : direct buy, 1 : buy as buy1 -function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, retryDelay) { - var initAccount = GetAccount(e, true); - var nowAccount = initAccount; - var orderId = null; - var prePrice = 0; - var dealAmount = 0; - var diffMoney = 0; - var isFirst = true; - var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell; - var isBuy = tradeType == ORDER_TYPE_BUY; - while (true) { - var ticker = _C(e.GetTicker); - var tradePrice = 0; - if (isBuy) { - tradePrice = _N((mode === 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4); - } else { - tradePrice = _N((mode === 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4); - } - if (!orderId) { - if (isFirst) { - isFirst = false; - } else { - nowAccount = GetAccount(e, true); - } - var doAmount = 0; - if (isBuy) { - diffMoney = _N(initAccount.Balance - nowAccount.Balance, 4); - dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 4); - doAmount = Math.min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance - 10) / tradePrice, 4)); - } else { - diffMoney = _N(nowAccount.Balance - initAccount.Balance, 4); - dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); - doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); - } - if (doAmount < e.GetMinStock()) { - break; - } - prePrice = tradePrice; - orderId = tradeFunc(tradePrice, doAmount, ticker); - if (!orderId) { - CancelPendingOrders(e, tradeType); - } - } else { - if (mode === 0 || (Math.abs(tradePrice - prePrice) > maxSpace)) { - orderId = null; - } - var order = StripOrders(e, orderId); - if (!order) { - orderId = null; - } - } - Sleep(retryDelay); - } - - if (dealAmount <= 0) { - return null; - } - - return { - price: _N(diffMoney / dealAmount, 4), - amount: dealAmount - }; -} - -$.Buy = function(e, amount) { - if (typeof(e) === 'number') { - amount = e; - e = exchange; - } - return Trade(e, ORDER_TYPE_BUY, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); -}; - -$.Sell = function(e, amount) { - if (typeof(e) === 'number') { - amount = e; - e = exchange; - } - return Trade(e, ORDER_TYPE_SELL, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); -}; - -$.CancelPendingOrders = function(e, orderType) { - if (typeof(orderType) === 'undefined') { - if (typeof(e) === 'number') { - orderType = e; - e = exchange; - } else if (typeof(e) === 'undefined') { - e = exchange; - } - } - return CancelPendingOrders(e, orderType); -}; - -$.GetAccount = function(e) { - if (typeof(e) === 'undefined') { - e = exchange; - } - return _C(e.GetAccount); -}; - -var _MACalcMethod = [TA.EMA, TA.MA, talib.KAMA][MAType]; - -// 返回上穿的周期数. 正数为上穿周数, 负数表示下穿的周数, 0指当前价格一样 -$.Cross = function(a, b) { - var crossNum = 0; - var arr1 = []; - var arr2 = []; - if (Array.isArray(a)) { - arr1 = a; - arr2 = b; - } else { - var records = null; - while (true) { - records = exchange.GetRecords(); - if (records && records.length > a && records.length > b) { - break; - } - Sleep(RetryDelay); - } - arr1 = _MACalcMethod(records, a); - arr2 = _MACalcMethod(records, b); - } - if (arr1.length !== arr2.length) { - throw "array length not equal"; - } - for (var i = arr1.length-1; i >= 0; i--) { - if (typeof(arr1[i]) !== 'number' || typeof(arr2[i]) !== 'number') { - break; - } - if (arr1[i] < arr2[i]) { - if (crossNum > 0) { - break; - } - crossNum--; - } else if (arr1[i] > arr2[i]) { - if (crossNum < 0) { - break; - } - crossNum++; - } else { - break; - } - } - return crossNum; -}; - -// 期货部分 -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) && direction == PD_LONG) || ((positions[i].Type == PD_SHORT) && 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; - var step = 0; - while (true) { - var needOpen = opAmount; - if (isFirst) { - isFirst = false; - } else { - positionNow = GetPosition(e, contractType, direction); - if (positionNow) { - needOpen = opAmount - (positionNow.Amount - initAmount); - } - } - if (needOpen < e.GetMinStock()) { - break; - } - if (step > max_open_lv) { - break; - } - var amount = needOpen; - e.SetDirection(direction == PD_LONG ? "buy" : "sell"); - var orderId; - if (direction == PD_LONG) { - orderId = e.Buy(price + F_SlidePrice * (1 + step), amount, "开多仓", contractType, price); - } else { - orderId = e.Sell(price - F_SlidePrice * (1 + step), amount, "开空仓", contractType, price); - } - - Sleep(Interval) // 增加延迟 避免 调用间隔过小导致 API 反应不过来,调换一下位置,写在合适的位置上, GetOrders 之前,避免刚下单就获取 未完成订单 导致问题。 - - while (true) { - var orders = _C(e.GetOrders); - if (orders.length === 0) { - break; - } - Sleep(Interval); - for (var j = 0; j < orders.length; j++) { - e.CancelOrder(orders[j].Id); - if (j < (orders.length - 1)) { - Sleep(Interval); - } - } - } - step += lv; - // Sleep(Interval) // 增加延迟 避免 调用间隔过小导致 API 反应不过来,调换一下位置,写在合适的位置上, GetOrders 之前,避免刚下单就获取 未完成订单 导致问题。 - } - 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, OP_amount, direction) { - var initP = null; - var positions = null; - var isFirst = true; - var ID = null; - var step = 0; - var index = 0; - var initP_contractTypeAmount = 0 - while (true) { - var n = 0; - positions = _C(e.GetPosition); - if (isFirst === true) { - if (typeof(direction) === 'undefined' && positions.length > 1 || (direction !== PD_LONG && direction !== PD_SHORT && typeof(direction) !== 'undefined')) { - throw "有多,空双向持仓,并且参数direction未明确方向!或 direction 参数异常:" + direction; - } - initP = positions; - isFirst = false; - // 修改BUG - for(var m = 0 ; m < initP.length; m++){ - if(initP[m].ContractType == contractType){ - initP_contractTypeAmount = initP[m].Amount - } - } - } - for (var i = 0; i < positions.length; i++) { - if (positions[i].ContractType != contractType || (positions[i].Type !== direction && typeof(direction) !== 'undefined')) { - continue; - } - var amount = 0; - if (typeof(OP_amount) === 'undefined') { - amount = positions[i].Amount; - } else { - amount = OP_amount - (/*initP[i].Amount*/ initP_contractTypeAmount - positions[i].Amount); - } - - if (amount <= 0) { // 修改为 小于 等于 0 - continue; - } - if (positions[i].Type == PD_LONG) { - e.SetDirection("closebuy"); - ID = e.Sell(price - F_SlidePrice * (1 + step), amount, "平多仓", contractType, price); - n++; - } else if (positions[i].Type == PD_SHORT) { - e.SetDirection("closesell"); - ID = e.Buy(price + F_SlidePrice * (1 + step), amount, "平空仓", contractType, price); - n++; - } - index = i; - } - if (n === 0) { - break; - } - Sleep(Interval); - if (typeof(ID) !== 'number') { - CancelPendingOrders(e); // 测试 - Log("ID:", ID); - continue; - } - - //_C(e.CancelOrder, ID); // 测试修改 e.CancelOrder(ID); - CancelPendingOrders(e); // 测试 - step += lv; - if (step > max_cover_lv) { - break; - } - } - - var nowP = _C(e.GetPosition); - if (!nowP[index] || nowP[index].Type !== initP[index].Type) { - return initP.length === 0 ? 0 : initP[index].Amount; - } else { - var diff = initP[index].Amount - nowP[index].Amount; - return diff; - } -} - -var PositionManager = (function() { - function PositionManager(e) { - if (typeof(e) === 'undefined') { - e = exchange; - } - if (e.GetName() !== 'Futures_OKCoin' && e.GetName() !== 'Futures_BitVC') { - throw 'Only support Futures_OKCoin & Futures_BitVC'; - } - 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); - }; - - 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, OP_amount, direction) { - if (!this.account) { - this.account = _C(exchange.GetAccount); - } - return Cover(this.e, contractType, price, OP_amount, direction); - }; - - PositionManager.prototype.Profit = function(contractType) { - var accountNow = _C(this.e.GetAccount); - Log("NOW:", accountNow, "--account:", this.account); - return _N(accountNow.Balance - this.account.Balance); - }; - - return PositionManager; -})(); - -$.NewPositionManager = function(e) { - return new PositionManager(e); -}; - - -// 测试代码 -function main() { - if (exchange.GetName() === 'Futures_OKCoin') { - var info = exchange.SetContractType("this_week"); - Log("info 返回值:", info); - Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); - var depth = exchange.GetDepth(); - var p = $.NewPositionManager(); - p.OpenShort("this_week", 10, depth.Bids[0].Price - 2); - Log(exchange.GetPosition()); - Sleep(500 * 1000); - depth = exchange.GetDepth(); - var ret = p.Cover("this_week", depth.Bids[0].Price + 2, 5); - Log("cover ret:", ret); - //LogProfit(p.Profit()); - Log(exchange.GetPosition()); - Log("-----------------------------测试分割线----------------------------------------"); - var depth = exchange.GetDepth(); - p.OpenLong("this_week", 20, depth.Bids[0].Price + 2); - Log(exchange.GetPosition()); - Sleep(500 * 1000); - depth = exchange.GetDepth(); - var ret = p.Cover("this_week", depth.Bids[0].Price - 2, 10, PD_LONG); - Log("cover ret:", ret); - Log(exchange.GetPosition()); - Log("-----------------------------测试分割线----------------------------------------"); - var ret = p.Cover("this_week", depth.Bids[0].Price - 3, 10, PD_LONG); - Log("cover ret:", ret); - var ret = p.Cover("this_week", depth.Bids[0].Price + 3, 5, PD_SHORT); - Log("cover ret:", ret); - Log(exchange.GetPosition()); - } else if (exchange.GetName() === 'Futures_BitVC') { - var info = exchange.SetContractType("week"); - Log("info 返回值:", info); - Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); - var depth = exchange.GetDepth(); - var p = $.NewPositionManager(); - p.OpenLong("week", 500, depth.Bids[0].Price + 2); - Log(exchange.GetPosition()); - Sleep(500 * 1000); - depth = exchange.GetDepth(); - var ret = p.Cover("week", depth.Bids[0].Price - 2, 500); - Log("cover ret:", ret); - Log(exchange.GetPosition()); - Log("-----------------------------测试分割线----------------------------------------"); - var info = exchange.SetContractType("week"); - Log("info 返回值:", info); - Log("当前持仓信息", exchange.GetPosition(), _C(exchange.GetTicker)); - var depth = exchange.GetDepth(); - p.OpenShort("week", 600, depth.Bids[0].Price - 2); - Log(exchange.GetPosition()); - Sleep(500 * 1000); - depth = exchange.GetDepth(); - var ret = p.Cover("week", depth.Bids[0].Price + 2, 500, PD_SHORT); - Log("cover ret:", ret); - Log(exchange.GetPosition()); - Log("-----------------------------测试分割线----------------------------------------"); - var ret = p.Cover("week", depth.Bids[0].Price + 3, 100, PD_SHORT); - Log("cover ret:", ret); - //p.Cover("week", depth.Asks[0].Price - 3, 300, PD_LONG); - Log(exchange.GetPosition()); - } else if(exchange.GetName() === 'huobi' || exchange.GetName() === 'OKCoin'){ - Log($.GetAccount()); - Log($.Buy(0.5)); - Log($.Sell(0.5)); - exchange.Buy(1000, 3); - $.CancelPendingOrders(exchanges[0]); - Log($.Cross(30, 7)); - Log($.Cross([1,2,3,2.8,3.5], [3,1.9,2,5,0.6])); - } -} - -``` - -> 策略出处 - -https://www.fmz.com/strategy/36762 - -> 更新时间 - -2017-10-22 23:14:09 diff --git a/README.md b/README.md index 9db44472..ef202686 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,14 @@ > 开源策略 + - [爬取币安公告自动出售将要下架币|crawl Binance announcements and sell Delist coin](https://www.fmz.com/strategy/137450) + - [多交易所集合行情/下单 策略 范例](https://www.fmz.com/strategy/125569) + - [海龟汤策略](https://www.fmz.com/strategy/139249) + - [策略框架](https://www.fmz.com/strategy/20663) + - [商品期货跟单系统](https://www.fmz.com/strategy/79351) + - [交互模板](https://www.fmz.com/strategy/137403) + - [多图表例子(数据可下载为csv等表格)](https://www.fmz.com/strategy/136056) + - [M Language “Turtle Trading strategy” implementations(V 1.0)](https://www.fmz.com/strategy/132298) - [cancelorder加强版](https://www.fmz.com/strategy/134368) - [RSI统计套利策略-熊市盈利利器](https://www.fmz.com/strategy/131971) - [海龟](https://www.fmz.com/strategy/128382) @@ -15,9 +23,7 @@ - [MACD+MA指标组合策略](https://www.fmz.com/strategy/128134) - [(学习)API与教程内代码学习文件](https://www.fmz.com/strategy/131864) - [封装Bithumb的ordersDetail接口](https://www.fmz.com/strategy/132241) - - [麦语言海龟策略体验 (V 1.0)|M Language “Turtle Trading strategy” implementations(V 1.0)](https://www.fmz.com/strategy/132298) - [麦语言海龟策略体验](https://www.fmz.com/strategy/126968) - - [商品期货跟单系统](https://www.fmz.com/strategy/79351) - [Bitmex仓位变化推送微信(wss协议,需要bitmex api ID)|Bitmex position-change push(websocket)](https://www.fmz.com/strategy/128624) - [基于ATR波动率指标构建的通道策略|Channel strategy based on ATR volatility indicator](https://www.fmz.com/strategy/127691) - [升级版恒温器策略|Upgraded Thermostat Strategy](https://www.fmz.com/strategy/129086) @@ -49,7 +55,6 @@ - [商品期货交易类库(旧版)](https://www.fmz.com/strategy/127341) - [BitMEX 高级API功能 V.1.1.0 (期货:批量下单,编辑订单,冰山订单,一键撤单,定时撤单) Python2/3](https://www.fmz.com/strategy/114148) - [OkEX 高级API功能 V.1.1.0 (期货:批量下单,现货;TBD) Python2/3](https://www.fmz.com/strategy/113979) - - [多交易所集合行情/下单 策略 范例](https://www.fmz.com/strategy/125569) - [使用画线类库画K线以及均线图表范例](https://www.fmz.com/strategy/125770) - [MA5](https://www.fmz.com/strategy/125474) - [设定价格微信推送(教学)](https://www.fmz.com/strategy/125482) @@ -75,7 +80,6 @@ - [动态平衡 做市策略](https://www.fmz.com/strategy/113618) - [OKEX交易对信息](https://www.fmz.com/strategy/117000) - [简单网格测试](https://www.fmz.com/strategy/116289) - - [(13)策略框架](https://www.fmz.com/strategy/20663) - [跨平台套利新手测试](https://www.fmz.com/strategy/115574) - [Fomo3D 智能合约监控 / Fomo3D Smart Contract Monitoring](https://www.fmz.com/strategy/107916) - [动态平衡alpha](https://www.fmz.com/strategy/115321) @@ -160,7 +164,6 @@ - [python版 画线类库 (兼容2/3)](https://www.fmz.com/strategy/39066) - [BotVS 商品期货 量化 测试入门 策略](https://www.fmz.com/strategy/59120) - [如何找出一定Bar数量的 K线前期高点、低点 及 Demo 程序](https://www.fmz.com/strategy/58179) - - [OKCoin期货跨期对冲策略(模板测试使用)](https://www.fmz.com/strategy/36762) - [python版现货数字货币交易类库](https://www.fmz.com/strategy/21104) - [一目均衡](https://www.fmz.com/strategy/55839) - [StochRSI(和okcoin一致)](https://www.fmz.com/strategy/56119) @@ -231,6 +234,7 @@ - [平台价格比较1.0](https://www.fmz.com/strategy/8266) - [多平台账户统计](https://www.fmz.com/strategy/7827) - [阶梯下单 - 可设置触发价格](https://www.fmz.com/strategy/639) + - [统计收益 (复制)](https://www.fmz.com/strategy/4489) - [796期货反手加倍算法](https://www.fmz.com/strategy/3648) - [多线程获取多个交易的深度信息](https://www.fmz.com/strategy/3651) - [账户余额变动邮箱提醒, 支持添加多个交易所](https://www.fmz.com/strategy/2006) diff --git "a/RUMI\347\255\226\347\225\245|RUMI Strategy.md" "b/RUMI\347\255\226\347\225\245|RUMI Strategy.md" index 60858302..5225693a 100644 --- "a/RUMI\347\255\226\347\225\245|RUMI Strategy.md" +++ "b/RUMI\347\255\226\347\225\245|RUMI Strategy.md" @@ -13,7 +13,7 @@ littleDreamXX - 策略名称:RUMI策略 - 适用周期:多周期 - 支持:商品期货、数字货币期货、数字货币现货 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/df2427683a93f2c896c853c89e3ae494.png) diff --git "a/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245|Three-MA Price Breakthrough Strategy.md" "b/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245|Three-MA Price Breakthrough Strategy.md" index 9c2d4b50..e85dd9db 100644 --- "a/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245|Three-MA Price Breakthrough Strategy.md" +++ "b/\344\270\211\345\235\207\347\272\277\351\241\272\345\212\277\344\273\267\346\240\274\347\252\201\347\240\264\347\255\226\347\225\245|Three-MA Price Breakthrough Strategy.md" @@ -15,7 +15,7 @@ littleDreamXX - 数据合约:指数合约 - 交易合约:主力合约 - 适合品种:商品期货 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/4327c3e54a8618bb6f5b0ac3ea54dfc2.png) diff --git "a/\344\272\244\344\272\222\346\250\241\346\235\277.md" "b/\344\272\244\344\272\222\346\250\241\346\235\277.md" new file mode 100644 index 00000000..a9c61511 --- /dev/null +++ "b/\344\272\244\344\272\222\346\250\241\346\235\277.md" @@ -0,0 +1,118 @@ + +> 策略名称 + +交互模板 + +> 策略作者 + +小小梦 + +> 策略描述 + +- 测试代码 + + ``` + // 测试代码 + function main() { + $.BindingFunc("test1", function(cmd, param){ // 绑定 控件名称为 test1 的按钮,function(cmd, param){...} 为该按钮的响应函数, 响应函数 第一个参数为 触发响应函数的控件名称即:test1 + var ticker = exchange.GetTicker() // 第二个 param 参数是 控件点击时 附带的 参数(数值类型、字符串类型、布尔类型、下拉框 都有附带参数,按钮类型没有附带参数) + Log("控件:", cmd, "ticker:", ticker, " 参数:", param) + }) + $.BindingFunc("test3", function(cmd, param){ // 绑定 test3 ... + var account = exchange.GetAccount() + Log("account:", account, "cmd:", cmd, "param:", param) + }) + $.BindingFunc("test5", function(){ // 绑定 test5 ... + Log(exchange.GetName()) + }) + while(1){ + $.GetCommand() // 主循环中 检测 交互命令。 + Sleep(2000) + } + } + ``` + +- 接口函数 + + - 绑定控件响应函数 + $.BindingFunc(cmdControlName, function(cmd, param){...}) + + - 交互检测函数 + 代替 平台API GetCommand() 函数 + $.GetCommand() + +- 测试代码 配置的 控件截图 + ![IMG](https://www.fmz.com/upload/asset/166da027c40813fe1311.png) + +- 如有问题欢迎提出,留言。 + + + +> 源码 (javascript) + +``` javascript +var _CmdMap = {} + +$.BindingFunc = function(cmdName, cmdFunc) { + _CmdMap[cmdName] = cmdFunc +} + +$.GetCommand = function() { + var cmd = GetCommand() + if(cmd) { + strArr = cmd.split(":") + func = _CmdMap[strArr[0]] + if(strArr.length == 1) { + // 调用对应 命令的响应函数 + if(func) { + func(strArr[0]) + } + } else if(strArr.length == 2) { + // 调用对应 命令的响应函数 + if(func) { + func(strArr[0], strArr[1]) + } + } else { + var param = strArr[1] + for(var i = 2; i < strArr.length; i++) { + param += (":" + strArr[i]) + } + + // 调用对应 命令的响应函数 + if(func) { + func(strArr[0], param) + } + } + if(!func) { + Log(strArr[0], "该命令未注册响应函数.", "#FF0000") + } + } +} + +// 测试代码 +function main() { + $.BindingFunc("test1", function(cmd, param){ // 绑定 控件名称为 test1 的按钮,function(cmd, param){...} 为该按钮的响应函数, 响应函数 第一个参数为 触发响应函数的控件名称即:test1 + var ticker = exchange.GetTicker() // 第二个 param 参数是 控件点击时 附带的 参数(数值类型、字符串类型、布尔类型、下拉框 都有附带参数,按钮类型没有附带参数) + Log("控件:", cmd, "ticker:", ticker, " 参数:", param) + }) + $.BindingFunc("test3", function(cmd, param){ // 绑定 test3 ... + var account = exchange.GetAccount() + Log("account:", account, "cmd:", cmd, "param:", param) + }) + $.BindingFunc("test5", function(){ // 绑定 test5 ... + Log(exchange.GetName()) + }) + while(1){ + $.GetCommand() // 主循环中 检测 交互命令。 + Sleep(2000) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/137403 + +> 更新时间 + +2019-02-15 11:49:52 diff --git "a/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245|Price high and low - Ichimoku trend strategy.md" "b/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245|Price high and low - Ichimoku trend strategy.md" index ce797f13..dc96b026 100644 --- "a/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245|Price high and low - Ichimoku trend strategy.md" +++ "b/\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\344\270\216\344\270\200\347\233\256\345\235\207\347\272\277\345\217\214\351\207\215\350\266\213\345\212\277\347\255\226\347\225\245|Price high and low - Ichimoku trend strategy.md" @@ -13,7 +13,7 @@ littleDreamXX - 策略名称:价格高低点与一目均线双重趋势策略 - 数据周期:15M等 - 支持:商品期货 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/487949c7affb8521d9c041610551c3cd.png) diff --git "a/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245|Trading Strategy of Traditional MA Index and KD Index.md" "b/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245|Trading Strategy of Traditional MA Index and KD Index.md" index 87421702..7abdc97b 100644 --- "a/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245|Trading Strategy of Traditional MA Index and KD Index.md" +++ "b/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245|Trading Strategy of Traditional MA Index and KD Index.md" @@ -14,7 +14,7 @@ littleDreamXX - 数据周期:15M,30M等 - 支持:商品期货 - 指标使用了EMA,KD线,其中KD线使用的是默认参数(指标参数固定3,3,9) -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/f842e44b0b8451cb562b8d5bd888e4c0.png) diff --git "a/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|DMI and High-Low Strategy.md" "b/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|DMI and High-Low Strategy.md" index 5613c28c..833c736f 100644 --- "a/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|DMI and High-Low Strategy.md" +++ "b/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|DMI and High-Low Strategy.md" @@ -13,7 +13,7 @@ littleDreamXX - 策略名称:动向指数(DMI)与高低点策略 - 数据周期:5M - 支持:商品期货 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com diff --git "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" index 92531a78..ccbf5ebd 100644 --- "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" +++ "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" @@ -9,7 +9,7 @@ Hukybo > 策略描述 -阅读原文:[区块链量化投资系列课程(3) - 跨期套利](https://quant.la/Article/View/816/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%283%29---%E8%B7%A8%E6%9C%9F%E5%A5%97%E5%88%A9.html) +阅读原文:[区块链量化投资系列课程(3) - 跨期套利](https://quantinfo.com/Article/View/816/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%283%29---%E8%B7%A8%E6%9C%9F%E5%A5%97%E5%88%A9.html) ### NO.1 索罗斯在1987年撰写的《金融炼金术》 一书中,曾经提出过一个重要的命题:I believe the market prices are always wrong in the sense that they present a biased view of the future. []( https://dn-filebox.qbox.me/ff79e72d5042d66611bb87f552cb8413238bee41.jpg ) @@ -148,9 +148,9 @@ var oldTime = 0 放眼望去,数字货币市场俨然已经脱离了区块链,就像当年的郁金香一样,价格始终来自于人们的预期和信心,信心又来源于价格... 延伸阅读: -[区块链量化投资系列课程(1) - 简介](https://quant.la/Article/View/818/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%281%29---%E7%AE%80%E4%BB%8B.html) -[区块链量化投资系列课程(2) - 认识数字货币](https://quant.la/Article/View/819/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%282%29---%E8%AE%A4%E8%AF%86%E6%95%B0%E5%AD%97%E8%B4%A7%E5%B8%81.html) -[区块链量化投资系列课程(4) - 动态平衡策略](https://quant.la/Article/View/1573/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%284%29---%E5%8A%A8%E6%80%81%E5%B9%B3%E8%A1%A1%E7%AD%96%E7%95%A5.html) +[区块链量化投资系列课程(1) - 简介](https://quantinfo.com/Article/View/818/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%281%29---%E7%AE%80%E4%BB%8B.html) +[区块链量化投资系列课程(2) - 认识数字货币](https://quantinfo.com/Article/View/819/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%282%29---%E8%AE%A4%E8%AF%86%E6%95%B0%E5%AD%97%E8%B4%A7%E5%B8%81.html) +[区块链量化投资系列课程(4) - 动态平衡策略](https://quantinfo.com/Article/View/1573/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%284%29---%E5%8A%A8%E6%80%81%E5%B9%B3%E8%A1%A1%E7%AD%96%E7%95%A5.html) diff --git "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" index 82a9b4d8..019f4aee 100644 --- "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" +++ "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" @@ -9,10 +9,10 @@ Hukybo > 策略描述 -阅读原文:[区块链量化投资系列课程(4) - 动态平衡策略](https://quant.la/Article/View/1573/[1-4]%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B---%E5%8A%A8%E6%80%81%E5%B9%B3%E8%A1%A1%E7%AD%96%E7%95%A5.html) +阅读原文:[区块链量化投资系列课程(4) - 动态平衡策略](https://quantinfo.com/Article/View/1573/[1-4]%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B---%E5%8A%A8%E6%80%81%E5%B9%B3%E8%A1%A1%E7%AD%96%E7%95%A5.html) ### 前言 -沃伦 · 巴菲特的导师本杰明 · 格雷厄姆曾经在[《聪明的投资者》](https://quant.la/Download/View/2742/%E8%81%AA%E6%98%8E%E7%9A%84%E6%8A%95%E8%B5%84%E8%80%85%EF%BC%88%E7%AC%AC4%E7%89%88%EF%BC%89.html)一书中,曾经提到过一种股票债券动态平衡的交易模式。 +沃伦 · 巴菲特的导师本杰明 · 格雷厄姆曾经在[《聪明的投资者》](https://quantinfo.com/Download/View/2742/%E8%81%AA%E6%98%8E%E7%9A%84%E6%8A%95%E8%B5%84%E8%80%85%EF%BC%88%E7%AC%AC4%E7%89%88%EF%BC%89.html)一书中,曾经提到过一种股票债券动态平衡的交易模式。 []( https://dn-filebox.qbox.me/71666050bcdc809d074f5cfa3499650045306c5d.png ) 这种交易模式非常简单: - 把手中 50% 的资金投资于股票基金,剩下 50% 投资于债券基金。即股票和债券两者各占一半。 @@ -103,9 +103,9 @@ BTC 已经持续了长达 8 个月下跌,甚至最大跌幅超过70%,这造 延伸阅读: -[区块链量化投资系列课程(1) - 简介](https://quant.la/Article/View/818/Empty.html) -[区块链量化投资系列课程(2) - 认识数字货币](https://quant.la/Article/View/819/Empty.html) -[区块链量化投资系列课程(3) - 跨期套利](https://quant.la/Article/View/816/Empty.html) +[区块链量化投资系列课程(1) - 简介](https://quantinfo.com/Article/View/818/Empty.html) +[区块链量化投资系列课程(2) - 认识数字货币](https://quantinfo.com/Article/View/819/Empty.html) +[区块链量化投资系列课程(3) - 跨期套利](https://quantinfo.com/Article/View/816/Empty.html) > 策略参数 diff --git "a/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245|Upgraded Thermostat Strategy.md" "b/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245|Upgraded Thermostat Strategy.md" index 270f8235..7a7d1489 100644 --- "a/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245|Upgraded Thermostat Strategy.md" +++ "b/\345\215\207\347\272\247\347\211\210\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245|Upgraded Thermostat Strategy.md" @@ -13,7 +13,7 @@ littleDreamXX - 策略名称:升级版恒温器策略 - 数据周期:1H - 支持:商品期货、数字货币期货、数字货币现货 -- 官方网站:WWW.QUANT.LA +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/bcf664987bac1aaff72110b1e3679d10.png) diff --git "a/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245|Double Average Lines -DDI Strategy.md" "b/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245|Double Average Lines -DDI Strategy.md" index c9bae90c..0e670b21 100644 --- "a/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245|Double Average Lines -DDI Strategy.md" +++ "b/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245|Double Average Lines -DDI Strategy.md" @@ -15,7 +15,7 @@ littleDreamXX - 数据合约:指数合约 - 交易合约:主力合约 - 适合品种:沪银/沪镍/热卷/铁矿石/焦煤/焦炭/鸡蛋/郑醇/PP/螺纹/橡胶/锰硅/郑煤等 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com - 主图指标线: VAR2^^MA(C,PARAM2); diff --git "a/\345\217\214\345\235\207\347\272\277\344\270\216\345\275\242\346\200\201\347\255\226\347\225\245|Double MA and Formation Strategy.md" "b/\345\217\214\345\235\207\347\272\277\344\270\216\345\275\242\346\200\201\347\255\226\347\225\245|Double MA and Formation Strategy.md" index 7132782e..38bc278d 100644 --- "a/\345\217\214\345\235\207\347\272\277\344\270\216\345\275\242\346\200\201\347\255\226\347\225\245|Double MA and Formation Strategy.md" +++ "b/\345\217\214\345\235\207\347\272\277\344\270\216\345\275\242\346\200\201\347\255\226\347\225\245|Double MA and Formation Strategy.md" @@ -13,7 +13,7 @@ littleDreamXX - 策略名称:双均线与形态策略 - 数据周期:15M - 支持:商品期货,数字货币,数字货币期货 -- 官方网站:WWW.QUANT.LA +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/cf5ac5fdf4f33ed438ed4498e1a7b142.png) diff --git "a/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210|Combination of Double MA and RSI.md" "b/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210|Combination of Double MA and RSI.md" index ddcdb3ea..08a8aad1 100644 --- "a/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210|Combination of Double MA and RSI.md" +++ "b/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210|Combination of Double MA and RSI.md" @@ -14,7 +14,7 @@ littleDreamXX - 策略名称:双均线策略与相对强弱RSI指标组合 - 数据周期:15M,30M等 - 支持:商品期货 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/9955a36cca1be0e9d73f99fa8bdb4ac8.png) diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" index 7f5b603f..d0584c44 100644 --- "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\267\237\345\215\225\347\263\273\347\273\237.md" @@ -132,4 +132,4 @@ https://www.fmz.com/strategy/79351 > 更新时间 -2018-12-24 10:29:54 +2019-02-16 13:55:06 diff --git "a/\345\235\207\347\272\277\345\222\214\351\253\230\344\275\216\347\202\271\347\233\270\345\257\271\345\274\272\345\274\261\347\255\226\347\225\245|Relative Strength Strategy Based on Price.md" "b/\345\235\207\347\272\277\345\222\214\351\253\230\344\275\216\347\202\271\347\233\270\345\257\271\345\274\272\345\274\261\347\255\226\347\225\245|Relative Strength Strategy Based on Price.md" index f1d027fa..3021eb40 100644 --- "a/\345\235\207\347\272\277\345\222\214\351\253\230\344\275\216\347\202\271\347\233\270\345\257\271\345\274\272\345\274\261\347\255\226\347\225\245|Relative Strength Strategy Based on Price.md" +++ "b/\345\235\207\347\272\277\345\222\214\351\253\230\344\275\216\347\202\271\347\233\270\345\257\271\345\274\272\345\274\261\347\255\226\347\225\245|Relative Strength Strategy Based on Price.md" @@ -13,7 +13,7 @@ littleDreamXX - 策略名称:基于价格相对强的弱策略 - 数据周期:1H - 支持:商品期货、数字货币、数字货币期货 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/2e346e6e3b2edda65576ffe7d35e104b.png) diff --git "a/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245|Channel strategy based on ATR.md" "b/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245|Channel strategy based on ATR.md" index 8685f8b0..c8ebd51a 100644 --- "a/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245|Channel strategy based on ATR.md" +++ "b/\345\237\272\344\272\216ATR\346\263\242\345\212\250\347\216\207\346\214\207\346\240\207\346\236\204\345\273\272\347\232\204\351\200\232\351\201\223\347\255\226\347\225\245|Channel strategy based on ATR.md" @@ -15,7 +15,7 @@ littleDreamXX - 数据周期:多周期 - OKEX期货 - 合约 : this_week 当周 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/b2ebaacbe7dbb1bb45bb59ceb80dd37f.png) diff --git "a/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" "b/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" index 9250f62a..0f0958fd 100644 --- "a/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" +++ "b/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" @@ -15,6 +15,11 @@ +|参数|默认值|描述| +|----|----|----| +|StrProxy|socks5://|代理配置| + + |按钮|默认值|描述| @@ -76,7 +81,9 @@ function CreateExchanges(){ rows : null, } - + // 设置代理 + exchanges[i].SetProxy(StrProxy) + exs.ex_objs.push(obj) } @@ -260,4 +267,4 @@ https://www.fmz.com/strategy/125569 > 更新时间 -2018-11-12 12:34:34 +2019-03-02 13:49:51 diff --git "a/\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211.md" "b/\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211.md" new file mode 100644 index 00000000..0708de0b --- /dev/null +++ "b/\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211.md" @@ -0,0 +1,337 @@ + +> 策略名称 + +多图表例子(数据可下载为csv等表格) + +> 策略作者 + +botvsing + + + + + +> 源码 (javascript) + +``` javascript +var tradeHistory = {buyData:{amount:0, money:0}, sellData:{amount:0, money:0}, a:0, b:0, c:0, d:0, total:0} +var updateB = 0 +var lastNet = 0 +var updateD = 0 +if(_G('tradeHistory')){ + tradeHistory = _G('tradeHistory') +} +function getDepth(){ + var asks = [] + var bids = [] + var temp = 0 + var depth = JSON.parse(HttpQuery('https://api.binance.com/api/v1/depth?symbol=BTCUSDT')) + if(!depth){ + return false + } + depth.bids.reverse() + for(i=0;iPrice: {point.key}
', + valueDecimals: 2 + }, + series: [{ + name: 'Bids', + data: [], + color: '#03a7a8' + }, { + name: 'Asks', + data: [], + color: '#fc5857' + }] +}; +var chartE = { + __isStock: false, + extension: { + layout: 'single', // 不参于分组,单独显示, 默认为分组 'group' + col: 6, + height: 500, // 指定高度 // 指定宽度占的单元值, 总值 为12 + }, + chart: { + plotBackgroundColor: null, + plotBorderWidth: 0, + plotShadow: false + }, + title: { + text: '成交数量
分布
', + align: 'center', + verticalAlign: 'middle', + y: 40 + }, + tooltip: { + pointFormat: '{series.name}: {point.percentage:.1f}%' + }, + plotOptions: { + pie: { + dataLabels: { + enabled: true, + distance: -50, + style: { + fontWeight: 'bold', + color: 'white' + } + }, + startAngle: -90, + endAngle: 90, + center: ['50%', '75%'], + size: '110%' + } + }, + series: [{ + type: 'pie', + name: '占比', + innerSize: '50%', + data: [] + }] +} +var chartF = { + extension: { + layout: 'single', // 不参于分组,单独显示, 默认为分组 'group' + col: 6, + height: 300, // 指定高度 // 指定宽度占的单元值, 总值 为12 + }, + title: { + text: '总净买入' + }, + xAxis: { + type: 'datetime' + }, + series: [{ + name: 'last', + data: [], + }] +} +var chart = Chart([chartB,chartC,chartD,chartA,chartF,chartE]); +//chart.reset() +function main() { + var client = Dial("wss://stream.binance.com:9443/ws/" + 'btcusdt' + "@trade", 60) + var updateTime = new Date().getTime() + while(true){ + var trade = JSON.parse(client.read()) + if(trade.m){ + tradeHistory.sellData.amount += parseFloat(trade.q) + tradeHistory.sellData.money += parseFloat(trade.q) * parseFloat(trade.p) + }else{ + tradeHistory.buyData.amount += parseFloat(trade.q) + tradeHistory.buyData.money += parseFloat(trade.q) * parseFloat(trade.p) + } + var buyNet = _N(tradeHistory.buyData.money - tradeHistory.sellData.money, 3) + var tradeAmount = _N(parseFloat(trade.q),2)>1 ? 1 : _N(parseFloat(trade.q),2) + if(parseFloat(trade.q)<0.01){ + tradeHistory.a += 1 + }else if(parseFloat(trade.q)<0.1){ + tradeHistory.b += 1 + }else if(parseFloat(trade.q)<1){ + tradeHistory.c += 1 + }else{ + tradeHistory.d += 1 + } + tradeHistory.total +=1 + chartE.series[0].data = [ + ['小于0.01', _N(tradeHistory.a/tradeHistory.total,4)], + ['小于0.1', _N(tradeHistory.b/tradeHistory.total,4)], + ['小于1', _N(tradeHistory.c/tradeHistory.total,4)], + ['大于1', _N(tradeHistory.d/tradeHistory.total,4)], + ] + if(tradeAmount>0.01){ + while(chartA.series[1].data.length>2000){ + chartA.series[1].data.shift() + } + chartA.series[1].data.push(tradeAmount) + } + if(Date.now() - updateB > 60*1000){ + chart.add(0,[Date.now(), _N(buyNet-lastNet,2)]) + lastNet = buyNet + updateB = Date.now() + chart.add(1, [Date.now(), _N(parseFloat(trade.p),2)]) + chart.add(6, [Date.now(), _N(buyNet,2)]) + }else{ + chart.add(0, [Date.now(), _N(buyNet-lastNet,2)], -1) + chart.add(1, [Date.now(), _N(parseFloat(trade.p),2)], -1) + chart.add(6, [Date.now(), _N(buyNet,2)],-1) + } + if(Date.now() - updateD > 6*1000){ + var depth = getDepth() + if(!depth){ + continue + } + chartD.series[0].data = depth.bids + chartD.series[1].data = depth.asks + updateD = Date.now() + } + chart.update([chartB,chartC,chartD,chartA,chartF,chartE]) + } + +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/136056 + +> 更新时间 + +2019-01-31 10:31:25 diff --git "a/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245|Multilevel Take Profit Strategy.md" "b/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245|Multilevel Take Profit Strategy.md" index 002fd810..76bce79c 100644 --- "a/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245|Multilevel Take Profit Strategy.md" +++ "b/\345\244\232\347\272\247\346\255\242\347\233\210\350\266\213\345\212\277\347\255\226\347\225\245|Multilevel Take Profit Strategy.md" @@ -14,7 +14,7 @@ littleDreamXX - 策略名称: 多级止盈趋势策略 - 数据周期:多周期 - 支持:商品期货、数字货币 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/b8d89a704605b72bc44a56575a570bf6.png) diff --git "a/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245|The average of difference - combined with ATR.md" "b/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245|The average of difference - combined with ATR.md" index 3f728d6e..7308d0f2 100644 --- "a/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245|The average of difference - combined with ATR.md" +++ "b/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245|The average of difference - combined with ATR.md" @@ -16,7 +16,7 @@ littleDreamXX - 数据合约:指数合约 - 交易合约:主力合约 - 适合品种:沪铝、沥青、淀粉、热卷、铁矿石、焦炭、鸡蛋、郑醇、螺纹、橡胶、锰硅、郑煤等 -- 官方网站:[WWW.QUANT.LA](WWW.QUANT.LA) +- 官方网站:[www.quantinfo.com](www.quantinfo.com) - 主图: 无 diff --git "a/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|SAR and Price High and Low Strategy.md" "b/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|SAR and Price High and Low Strategy.md" index b62af9ff..e88b057d 100644 --- "a/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|SAR and Price High and Low Strategy.md" +++ "b/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|SAR and Price High and Low Strategy.md" @@ -13,7 +13,7 @@ littleDreamXX - 策略名称:SAR和价格高低点策略 - 数据周期:1H等 - 策略支持:商品期货、数字货币现货,数字货币期货 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/4d9459b9af47702f7c2c6666212927c7.png) diff --git "a/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245|Simplified Version of ICHIMOKU KINKO HYO Strategy.md" "b/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245|Simplified Version of ICHIMOKU KINKO HYO Strategy.md" index cbabd6bc..87c993f0 100644 --- "a/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245|Simplified Version of ICHIMOKU KINKO HYO Strategy.md" +++ "b/\346\227\245\346\234\254\344\272\221\345\233\276\347\256\200\345\214\226\347\211\210\347\255\226\347\225\245|Simplified Version of ICHIMOKU KINKO HYO Strategy.md" @@ -13,7 +13,7 @@ littleDreamXX - 策略名称:日本云图简化版策略 - 支持:商品期货 - 适用周期:多周期 -- 官方网站:WWW.QUANT.LA +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/8f499518ffb1876478917e564e9b7a71.png) diff --git "a/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245|Standard deviation price channel strategy.md" "b/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245|Standard deviation price channel strategy.md" index 47208f1c..05bd0ea9 100644 --- "a/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245|Standard deviation price channel strategy.md" +++ "b/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245|Standard deviation price channel strategy.md" @@ -13,7 +13,7 @@ littleDreamXX - 数据周期:30分钟左右 - 支持 数字货币现货、数字货币期货 - 支持 商品期货,适合品种:热卷、焦炭、豆粕、郑醇、沪镍、郑油、聚丙烯、螺纹、橡胶、锰硅、PTA、豆油 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com 商品期货回测 ![IMG](https://www.fmz.com/upload/asset/f58bc64ccfc4dca7cc1905b238f07dd7.png) diff --git "a/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245|Volatility ATR - Track Breakthrough Strategy.md" "b/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245|Volatility ATR - Track Breakthrough Strategy.md" index fe64cf56..400bc8bd 100644 --- "a/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245|Volatility ATR - Track Breakthrough Strategy.md" +++ "b/\346\263\242\345\212\250\347\216\207ATR\350\275\250\351\201\223\347\252\201\347\240\264\347\255\226\347\225\245|Volatility ATR - Track Breakthrough Strategy.md" @@ -13,7 +13,7 @@ littleDreamXX - 公式名称:波动率轨道突破策略 - 数据周期:15M,30M等 - 支持:商品期货、数字货币现货、数字货币期货 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/36b0e279ae314411a9d6b7e94a0623f0.png) diff --git "a/\346\265\267\351\276\237\346\261\244\347\255\226\347\225\245.md" "b/\346\265\267\351\276\237\346\261\244\347\255\226\347\225\245.md" new file mode 100644 index 00000000..454a3752 --- /dev/null +++ "b/\346\265\267\351\276\237\346\261\244\347\255\226\347\225\245.md" @@ -0,0 +1,281 @@ + +> 策略名称 + +海龟汤策略 + +> 策略作者 + +alinwo + +> 策略描述 + +海龟之汤,简称“龟汤”,是个与海龟交易法则相反的交易策略,它利用了跟势交易(特别是海龟方式)在很多假突破方面的缺陷来获利(把海龟做成汤吃掉)。 + +上世纪八十年代早期,有个非常著名的交易员团体——叫做“海龟”。缔造了交易传奇的市场大师理查德·丹尼斯在训练一组新交易员的时候起了这个有趣的名字。因为理查德相信,培训交易员,其实就像新加坡人养海龟一样。这个交易方法被称作海龟方法,这个简单的趋势跟随技巧方法曾令他们的导师理查德取得了巨大的成功。 + +二十多年过去了,海龟方法现在已不再是个秘密,很多人已经了解它。尽管如此,那为何仍没多少人用它交易取得成功呢?那是因为趋势跟随策略通常需要忍受大幅度和长时间的回撤。很多投资者或交易员没有足够的资本或者愿意坚持这些长期的亏损。通常大多数人在交易转向对他们有利之前就已经退出了。 + +琳达·华斯基和拉利·康诺在他们的书《华尔街精灵——屡试不爽的短期交易策略》(Street Smarts)中命名了这个与“海龟”交易法则相反的“龟汤”交易法则。大多数策略不能保持盈利的原因是,一旦很多市场参与者使用它们,这些策略的盈利能力就将退化。这是市场用来平衡那些不平衡现象的方法。华斯基通过与海龟方法相反的交易,发现更多成功和获利的结果。因为海龟法需要很多失败的交易和坐等坏的交易变得盈利。通常当它获利时,它会抵消那些所有的亏损才盈利,而且这个现象周而复始。很显然,华斯基创造这个策略“海龟之汤”的名字是种美式幽默,它利用海龟交易者的成本来获利(把海龟做成汤吃掉)。 + +原始的“海龟”交易规则至少是波段交易或更久的交易,时间跨度在一周到一个月之间。华斯基女士使用“龟汤”策略做更短期的日内或波段交易,集中地利用了假突破的高频发生现象。一般来说,“海龟”法使用的20天周期突破:突破20日高则买入,跌破20日低则抛售。而“龟汤”交易法则采用完全相反的方法。 + +策略参数说明: +http://www.pcclean.io/%E3%80%90%E6%B5%B7%E9%BE%9F%E6%B1%A4%E7%AD%96%E7%95%A5%E3%80%91%E5%8F%8D%E8%B6%8B%E5%8A%BF%E4%BA%A4%E6%98%93%E7%AD%96%E7%95%A5%E6%BA%90%E4%BB%A3%E7%A0%81%E5%88%86%E4%BA%AB%E5%9F%BA%E4%BA%8Ebotvs/ + + + +> 源码 (javascript) + +``` javascript + + +var strategy_version="1.0.0.0(new release 仅供学习研究使用,实盘后果自负)"; + +var price_n={Futures_OKCoin_BSV_USD:2}; +var num_n={Futures_OKCoin_BSV_USD:0}; +var minestbuy={Futures_OKCoin_BSV_USD:1}; +var price_step={Futures_OKCoin_BSV_USD:0.05}; +var contract_min={Futures_OKCoin_BSV_USD:10}; +var wait_ms=3000; +var max_wait_order=15000; +var max_positions=4; + +//gloabl variables +var positions_duo=[]; +var positions_kong=[]; +var total_loop=0; +var bet_duo=0; +var bet_kong=0; + +function main(){ + Log("strategy_version="+strategy_version); + $.set_params(price_n,num_n,minestbuy,price_step,wait_ms,max_wait_order); + while(true){ + var exname=exchange.GetName(); + var currency=exchange.GetCurrency(); + var account=_C(exchange.GetAccount); + var ticker=_C(exchange.GetTicker); + var depth=_C(exchange.GetDepth); + var sell1=depth.Asks[0].Price; + var buy1=depth.Bids[0].Price; + var records=_C(exchange.GetRecords); + if (records.length<=50){ + Log("records.length无效,跳过此次执行..."); + Sleep(wait_ms); + continue; + } + var atr = TA.ATR(records, 20); + if (atr.length<=1){ + Log("atr.length无效,跳过此次执行..."); + Sleep(wait_ms); + continue; + } + var N=atr[atr.length-1]; + var position_unit=account.Stocks/(max_positions*2); + var highest20=TA.Highest(records, 20, 'High'); + var lowest20=TA.Lowest(records, 20, 'Low'); + var highest10=TA.Highest(records, 10, 'High'); + var lowest10=TA.Lowest(records, 10, 'Low'); + + //建仓 + if (positions_duo.length===0){ + if (sell1<=lowest20){ + var heyuefenshu=_N(position_unit*sell1/contract_min[$.get_exchange_id(exchange)],0); + exchange.SetDirection("buy"); + var dealamount=$.perform_limited_order("buy",exchange,sell1,heyuefenshu,false,"futures","buy"); + if (dealamount>0){ + var postion = { + amount:dealamount, + price:sell1, + stoploss_price:sell1-2.5*N, + stopwin_price:sell1+2.5*N, + }; + positions_duo.push(postion); + bet_duo=1; + } + } + } + if (positions_kong.length===0){ + if (buy1>=highest20){ + var heyuefenshu=_N(position_unit*buy1/contract_min[$.get_exchange_id(exchange)],0); + exchange.SetDirection("sell"); + var dealamount=$.perform_limited_order("buy",exchange,buy1,heyuefenshu,false,"futures","sell"); + if (dealamount>0){ + var postion = { + amount:dealamount, + price:buy1, + stoploss_price:buy1+2.5*N, + stopwin_price:buy1-2.5*N, + }; + positions_kong.push(postion); + bet_kong=1; + } + } + } + //加仓 + if (positions_duo.length>0){ + var last_price=positions_duo[positions_duo.length-1].price; + if (bet_duo=0.5*N){ + var heyuefenshu=_N(position_unit*sell1/contract_min[$.get_exchange_id(exchange)],0); + exchange.SetDirection("buy"); + var dealamount=$.perform_limited_order("buy",exchange,sell1,heyuefenshu,false,"futures","buy"); + if (dealamount>0){ + var postion = { + amount:dealamount, + price:sell1, + stoploss_price:sell1-2.5*N, + stopwin_price:sell1+2.5*N, + }; + positions_duo.push(postion); + bet_duo+=1; + } + } + } + } + if (positions_kong.length>0){ + var last_price=positions_kong[positions_kong.length-1].price; + if (bet_kong=0.5*N){ + var heyuefenshu=_N(position_unit*buy1/contract_min[$.get_exchange_id(exchange)],0); + exchange.SetDirection("sell"); + var dealamount=$.perform_limited_order("buy",exchange,buy1,heyuefenshu,false,"futures","sell"); + if (dealamount>0){ + var postion = { + amount:dealamount, + price:buy1, + stoploss_price:buy1+2.5*N, + stopwin_price:buy1-2.5*N, + }; + positions_kong.push(postion); + bet_kong+=1; + } + } + } + } + //止损 + if (positions_duo.length>0){ + var positions_duo_new=[]; + for (var i=0; i < positions_duo.length; i++){ + if (buy1<=positions_duo[i].stoploss_price){ + exchange.SetDirection("closebuy"); + $.perform_limited_order("sell",exchange,buy1,positions_duo[i].amount,true,"futures","closebuy"); + }else{ + positions_duo_new.push(positions_duo[i]); + } + } + positions_duo=positions_duo_new; + } + if (positions_kong.length>0){ + var positions_kong_new=[]; + for (var i=0; i < positions_kong.length; i++){ + if (sell1>=positions_kong[i].stoploss_price){ + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,sell1,positions_kong[i].amount,true,"futures","closesell"); + }else{ + positions_kong_new.push(positions_kong[i]); + } + } + positions_kong=positions_kong_new; + } + //止盈 + if (positions_duo.length>0){ + var positions_duo_new=[]; + for (var i=0; i < positions_duo.length; i++){ + if (buy1>=positions_duo[i].stopwin_price){ + exchange.SetDirection("closebuy"); + $.perform_limited_order("sell",exchange,buy1,positions_duo[i].amount,true,"futures","closebuy"); + }else{ + positions_duo_new.push(positions_duo[i]); + } + } + positions_duo=positions_duo_new; + } + if (positions_kong.length>0){ + var positions_kong_new=[]; + for (var i=0; i < positions_kong.length; i++){ + if (sell1<=positions_kong[i].stopwin_price){ + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,sell1,positions_kong[i].amount,true,"futures","closesell"); + }else{ + positions_kong_new.push(positions_kong[i]); + } + } + positions_kong=positions_kong_new; + } + //清仓 + if (positions_duo.length>0){ + if (buy1>=highest10){ + for (var i=0; i < positions_duo.length; i++){ + exchange.SetDirection("closebuy"); + $.perform_limited_order("sell",exchange,buy1,positions_duo[i].amount,true,"futures","closebuy"); + } + positions_duo=[]; + } + } + if (positions_kong.length>0){ + if (sell1<=lowest10){ + for (var i=0; i < positions_kong.length; i++){ + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,sell1,positions_kong[i].amount,true,"futures","closesell"); + } + positions_kong=[]; + } + } + //交易所强平 + var current_ok_position=_C(exchange.GetPosition);//must update here + if (current_ok_position.length===0){ + positions_duo=[]; + positions_kong=[]; + } + + //chart + var table1={type: 'table', title: '期货仓位', cols: ['交易所','持仓量','冻结量','持仓均价','实现盈余','类型','合约代码'], rows: []}; + var table2={type: 'table', title: '跟踪仓位', cols: ['交易所','类型','数量','价格','止损价','止盈价'], rows: []}; + for (var i=0; i < current_ok_position.length; i++){ + table1.rows.push([exname, + current_ok_position[i].Amount, + current_ok_position[i].FrozenAmount, + current_ok_position[i].Price, + current_ok_position[i].Profit, + current_ok_position[i].Type, + current_ok_position[i].ContractType]); + } + for (i=0; i 策略出处 + +https://www.fmz.com/strategy/139249 + +> 更新时间 + +2019-03-02 13:32:26 diff --git "a/\346\267\267\346\262\214\346\223\215\344\275\234\346\263\225\347\255\226\347\225\245|Trading Chaos Strategy.md" "b/\346\267\267\346\262\214\346\223\215\344\275\234\346\263\225\347\255\226\347\225\245|Trading Chaos Strategy.md" index d14a4919..a880bee1 100644 --- "a/\346\267\267\346\262\214\346\223\215\344\275\234\346\263\225\347\255\226\347\225\245|Trading Chaos Strategy.md" +++ "b/\346\267\267\346\262\214\346\223\215\344\275\234\346\263\225\347\255\226\347\225\245|Trading Chaos Strategy.md" @@ -13,7 +13,7 @@ littleDreamXX - 策略名称:混沌操作法策略 - 支持:商品期货 , 数字货币, 数字货币期货 - 使用周期:日线 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/a740c3a88fe1e0accb0c6a77fb11721c.png) diff --git "a/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245|PBX Strategy.md" "b/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245|PBX Strategy.md" index 4e74b2d5..086784dd 100644 --- "a/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245|PBX Strategy.md" +++ "b/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245|PBX Strategy.md" @@ -13,7 +13,7 @@ littleDreamXX - 策略名称:瀑布线PUBU交易策略 - 数据周期:15M - 支持:商品期货 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/3ba2dba0c6b01773b2c296438ff77d25.png) diff --git "a/\347\210\254\345\217\226\345\270\201\345\256\211\345\205\254\345\221\212\350\207\252\345\212\250\345\207\272\345\224\256\345\260\206\350\246\201\344\270\213\346\236\266\345\270\201|crawl Binance announcements and sell Delist coin.md" "b/\347\210\254\345\217\226\345\270\201\345\256\211\345\205\254\345\221\212\350\207\252\345\212\250\345\207\272\345\224\256\345\260\206\350\246\201\344\270\213\346\236\266\345\270\201|crawl Binance announcements and sell Delist coin.md" new file mode 100644 index 00000000..5c7c1072 --- /dev/null +++ "b/\347\210\254\345\217\226\345\270\201\345\256\211\345\205\254\345\221\212\350\207\252\345\212\250\345\207\272\345\224\256\345\260\206\350\246\201\344\270\213\346\236\266\345\270\201|crawl Binance announcements and sell Delist coin.md" @@ -0,0 +1,99 @@ + +> 策略名称 + +爬取币安公告自动出售将要下架币|crawl Binance announcements and sell Delist coin + +> 策略作者 + +botvsing + + + + + +> 源码 (javascript) + +``` javascript +var exchangeInfo = JSON.parse(HttpQuery('https://api.binance.com/api/v1/exchangeInfo')) +var pairInfo = {} +var downList = [] +if(exchangeInfo){ + for (var i=0; i pairInfo[symbol].minQty && sellPrice*sellAmount > pairInfo[symbol].minNotional){ + var id = exchange.Sell(sellPrice, sellAmount, symbol) + exchange.CancelOrder(order.orderId) + } +} +function cancellOrder(){ + var openOrders = exchange.IO('api', 'GET', '/api/v3/openOrders') + for (var i=0; i-1 && parseFloat(account.Info.balances[i].free)>pairInfo[account.Info.balances[i].asset+'BTC'].minQty){ + Log('this coin will be dumped', account.Info.balances[i].asset) + sellAll(account.Info.balances[i].asset, parseFloat(account.Info.balances[i].free)) + done = false + } + } + Sleep(1000) + } + Log('sell done') +} +function main() { + var title = '' + while(true){ + var html = HttpQuery('https://support.binance.com/hc/en-us/sections/115000202591-Latest-News') + html = html.slice(html.indexOf('Delist '),html.length) + if(html){ + if(html.slice(7,html.indexOf('')) != title){ + title = html.slice(7,html.indexOf('')) + downList = html.slice(7,html.indexOf('')).replace(' and ', ',').split(',') + Log('new announcement,will delist:', downList) + cancellOrder() + checkAccount() + }else{ + Log('new announcement was not found') + } + }else{ + Log('web spider wrong') + } + Sleep(60*1000) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/137450 + +> 更新时间 + +2019-03-07 11:31:36 diff --git "a/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.md" "b/\347\255\226\347\225\245\346\241\206\346\236\266.md" similarity index 99% rename from "\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.md" rename to "\347\255\226\347\225\245\346\241\206\346\236\266.md" index 033d9db5..225f5174 100644 --- "a/\357\274\21013\357\274\211\347\255\226\347\225\245\346\241\206\346\236\266.md" +++ "b/\347\255\226\347\225\245\346\241\206\346\236\266.md" @@ -1,7 +1,7 @@ > 策略名称 -(13)策略框架 +策略框架 > 策略作者 @@ -276,4 +276,4 @@ https://www.fmz.com/strategy/20663 > 更新时间 -2018-09-13 12:06:44 +2019-02-18 16:44:55 diff --git "a/\347\273\237\350\256\241\346\224\266\347\233\212 (\345\244\215\345\210\266).md" "b/\347\273\237\350\256\241\346\224\266\347\233\212 (\345\244\215\345\210\266).md" new file mode 100644 index 00000000..f7b610bc --- /dev/null +++ "b/\347\273\237\350\256\241\346\224\266\347\233\212 (\345\244\215\345\210\266).md" @@ -0,0 +1,88 @@ + +> 策略名称 + +统计收益 (复制) + +> 策略作者 + +总值约: 23938.37 元 + +> 策略描述 + +统计OK和Bitvc期货总收益;OK为主交易所; + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|LXT|20|循环周期(秒)| + + +> 源码 (javascript) + +``` javascript +var okrights=0; +var vcright=0; +var InitRights=0; +var totalrights=0; +var profit=0; +var oldprofit=0; + +SetErrorFilter("502:|503:|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF"); + + + +function Rights() { + + var accountok; + var accountvc; + while (!(accountok = exchanges[0].GetAccount())) { + Sleep(500); + } + while (!(accountvc = exchanges[1].GetAccount())) { + Sleep(500); + } + var objok; + var objvc; + + objok=JSON.parse(exchanges[0].GetRawJSON()); + objvc=JSON.parse(exchanges[1].GetRawJSON()); + + okrights=objok.info["btc"].rights; + vcrights=objvc.dynamicRights; + totalrights=okrights+vcrights; + + +} + +function main(){ + Rights(); + InitRights=totalrights; + Log("初始权益合计_BTC",InitRights); + while(true){ + Rights(); + profit=totalrights-InitRights; + if(profit!==oldprofit){ + LogProfit(profit,"BTC"); + oldprofit=profit; + } + Sleep(LXT*1000); + } + + +} + + + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/4489 + +> 更新时间 + +2015-02-28 19:17:29 diff --git "a/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245|Price high and low - ROC index strategy.md" "b/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245|Price high and low - ROC index strategy.md" index a20dd5cf..c447bb7d 100644 --- "a/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245|Price high and low - ROC index strategy.md" +++ "b/\351\253\230\344\275\216\347\202\271\344\270\216\346\263\242\345\212\250\347\216\207ROC\346\214\207\346\240\207\347\255\226\347\225\245|Price high and low - ROC index strategy.md" @@ -13,7 +13,7 @@ littleDreamXX - 策略名称:高低点与波动率ROC指标策略 - 数据周期:15M等 - 支持:商品期货 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/1f5e3caa65a3871ae9c9d99f9c11bdf0.png) ![IMG](https://www.fmz.com/upload/asset/ec4cbcbb036925739a04de90cadf1d8d.png) diff --git "a/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245|Break High and Low - Volume Index Weighting Strategy.md" "b/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245|Break High and Low - Volume Index Weighting Strategy.md" index 22041d77..c00c4a4d 100644 --- "a/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245|Break High and Low - Volume Index Weighting Strategy.md" +++ "b/\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\346\210\220\344\272\244\351\207\217\346\214\207\346\225\260\345\212\240\346\235\203\347\255\226\347\225\245|Break High and Low - Volume Index Weighting Strategy.md" @@ -14,7 +14,7 @@ littleDreamXX - 数据周期:多周期 - 回测可以选择 OKEX期货 - 合约:this_week 当周合约 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/efa8dad9db6b13862283a69ee8255934.png) diff --git "a/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245|High Winning Rate - ORB Trading Strategy.md" "b/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245|High Winning Rate - ORB Trading Strategy.md" index 29b78b1c..e0449b17 100644 --- "a/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245|High Winning Rate - ORB Trading Strategy.md" +++ "b/\351\253\230\350\203\234\347\216\207ORB\344\272\244\346\230\223\347\255\226\347\225\245|High Winning Rate - ORB Trading Strategy.md" @@ -13,7 +13,7 @@ littleDreamXX - 策略名称:高胜率ORB交易策略 - 数据周期:日K - 支持:商品期货 -- 官方网站:www.quant.la +- 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/860ae7cefa35c714a7f3c028ad77e656.png) From 9091792f243a5275cded620ae87c23e505c96c9a Mon Sep 17 00:00:00 2001 From: Zero Date: Fri, 12 Apr 2019 12:01:39 +0800 Subject: [PATCH 12/19] update --- ...60\346\211\213\345\205\245\351\227\250.md" | 2 +- KDJ Cpp Demo.md | 74 ++++ MACD Cpp Demo.md | 74 ++++ ...altime.md => OkEX Websocket Realtime v2.md | 4 +- README.md | 14 +- ...10\251\345\210\251\345\231\250 (Copy).md" | 417 ++++++++++++++++++ ...13\345\212\277\347\255\226\347\225\245.md" | 87 ++++ ...45\237\272\347\202\2711000\357\274\211.md" | 70 +++ ...26\347\225\245\347\240\224\347\251\266.md" | 4 +- ...1(\346\225\231\345\255\246\357\274\211.md" | 51 --- ...Push the price information to telegram.md" | 56 +++ ...21\346\240\274\347\255\226\347\225\245.md" | 45 ++ 12 files changed, 838 insertions(+), 60 deletions(-) create mode 100644 KDJ Cpp Demo.md create mode 100644 MACD Cpp Demo.md rename OkEX Websocket Realtime.md => OkEX Websocket Realtime v2.md (98%) create mode 100644 "RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245-\347\206\212\345\270\202\347\233\210\345\210\251\345\210\251\345\231\250 (Copy).md" create mode 100644 "\345\237\272\344\272\216\351\232\217\346\234\272\346\243\256\346\236\227\347\232\204\350\266\213\345\212\277\347\255\226\347\225\245.md" create mode 100644 "\345\261\261\345\257\250\345\270\201\346\214\207\346\225\260\357\274\2102018.02.22\345\237\272\347\202\2711000\357\274\211.md" delete mode 100644 "\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211.md" create mode 100644 "\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" create mode 100644 "\351\272\246\350\257\255\350\250\200\347\275\221\346\240\274\347\255\226\347\225\245.md" diff --git "a/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.md" "b/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.md" index 5c52f724..68b65d56 100644 --- "a/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.md" +++ "b/API \346\265\213\350\257\225\346\226\260\346\211\213\345\205\245\351\227\250.md" @@ -44,4 +44,4 @@ https://www.fmz.com/strategy/4 > 更新时间 -2017-02-28 10:14:17 +2019-03-19 21:09:24 diff --git a/KDJ Cpp Demo.md b/KDJ Cpp Demo.md new file mode 100644 index 00000000..e9ef9a50 --- /dev/null +++ b/KDJ Cpp Demo.md @@ -0,0 +1,74 @@ + +> 策略名称 + +KDJ Cpp Demo + +> 策略作者 + +Zero + + + + + +> 源码 (cpp) + +``` cpp +/*backtest +start: 2019-02-26 09:00:00 +end: 2019-03-27 15:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +*/ + +double position = 0; + +bool onTick(string symbol) { + auto ct = exchange.SetContractType(symbol); + if (ct == false) { + return false; + } + auto r = exchange.GetRecords(); + if (!r.Valid || r.size() < 10) { + return false; + } + + auto arr = TA.KDJ(r, 9, 3, 3); + auto k = arr[0][arr[0].size() - 2]; + auto d = arr[1][arr[1].size() - 2]; + auto dPre = arr[1][arr[1].size() - 3]; + auto j = arr[2][arr[2].size() - 2]; + string action; + if ((d < dPre && position > 0) || (d > dPre && position < 0)) { + action = "cover"; + } else if (k > d && position <= 0) { + action = "buy"; + } else if (k < d && position >= 0) { + action = "sell"; + } + if (action.size() > 0) { + position = ext::Trade(action, symbol, 1); + } + return true; +} + +void main() { + while (true) { + if (exchange.IO("status") == 0) { + Sleep(1000); + continue; + } + if (!onTick("MA888")) { + Sleep(1000); + } + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/142260 + +> 更新时间 + +2019-03-29 10:21:16 diff --git a/MACD Cpp Demo.md b/MACD Cpp Demo.md new file mode 100644 index 00000000..c2f46321 --- /dev/null +++ b/MACD Cpp Demo.md @@ -0,0 +1,74 @@ + +> 策略名称 + +MACD Cpp Demo + +> 策略作者 + +Zero + + + + + +> 源码 (cpp) + +``` cpp +/*backtest +start: 2019-02-26 09:00:00 +end: 2019-03-27 15:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +*/ + +double position = 0; + +bool onTick(string symbol) { + auto ct = exchange.SetContractType(symbol); + if (ct == false) { + return false; + } + auto r = exchange.GetRecords(); + if (!r.Valid || r.size() < 20) { + return false; + } + + auto macd = TA.MACD(r); + auto slow = macd[0][macd[0].size() - 2]; + auto fast = macd[1][macd[1].size() - 2]; + string action; + if (fast >= slow && position <= 0) { + action = "buy"; + } else if (fast <= slow && position >= 0) { + action = "sell"; + } + if (action.size() > 0) { + if (position != 0) { + ext::Trade("cover", symbol); + } + position = ext::Trade(action, symbol, 1); + } + return true; +} + +void main() { + while (true) { + if (exchange.IO("status") == 0) { + Sleep(1000); + continue; + } + if (!onTick("MA888")) { + Sleep(1000); + } + } +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/142259 + +> 更新时间 + +2019-03-29 10:21:35 diff --git a/OkEX Websocket Realtime.md b/OkEX Websocket Realtime v2.md similarity index 98% rename from OkEX Websocket Realtime.md rename to OkEX Websocket Realtime v2.md index 834720c6..ee5691e2 100644 --- a/OkEX Websocket Realtime.md +++ b/OkEX Websocket Realtime v2.md @@ -1,7 +1,7 @@ > 策略名称 -OkEX Websocket Realtime +OkEX Websocket Realtime v2 > 策略作者 @@ -137,4 +137,4 @@ https://www.fmz.com/strategy/91176 > 更新时间 -2018-11-06 00:13:58 +2019-04-08 23:47:33 diff --git a/README.md b/README.md index ef202686..43b5395e 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,15 @@ > 开源策略 + - [设定价格微信推送(教学)| Push the price information to telegram](https://www.fmz.com/strategy/125482) + - [OkEX Websocket Realtime v2](https://www.fmz.com/strategy/91176) + - [麦语言网格策略](https://www.fmz.com/strategy/142701) + - [MACD Cpp Demo](https://www.fmz.com/strategy/142259) + - [KDJ Cpp Demo](https://www.fmz.com/strategy/142260) + - [恒温器 Thermostat 择时策略研究](https://www.fmz.com/strategy/127033) + - [API 测试新手入门](https://www.fmz.com/strategy/4) + - [基于随机森林的趋势策略](https://www.fmz.com/strategy/140199) + - [RSI统计套利策略-熊市盈利利器 (Copy)](https://www.fmz.com/strategy/138171) - [爬取币安公告自动出售将要下架币|crawl Binance announcements and sell Delist coin](https://www.fmz.com/strategy/137450) - [多交易所集合行情/下单 策略 范例](https://www.fmz.com/strategy/125569) - [海龟汤策略](https://www.fmz.com/strategy/139249) @@ -19,7 +28,6 @@ - [现现对冲(搬砖)](https://www.fmz.com/strategy/127154) - [测试多图表展示](https://www.fmz.com/strategy/38203) - [选择性套利](https://www.fmz.com/strategy/134371) - - [恒温器 Thermostat 择时策略研究](https://www.fmz.com/strategy/127033) - [MACD+MA指标组合策略](https://www.fmz.com/strategy/128134) - [(学习)API与教程内代码学习文件](https://www.fmz.com/strategy/131864) - [封装Bithumb的ordersDetail接口](https://www.fmz.com/strategy/132241) @@ -57,8 +65,6 @@ - [OkEX 高级API功能 V.1.1.0 (期货:批量下单,现货;TBD) Python2/3](https://www.fmz.com/strategy/113979) - [使用画线类库画K线以及均线图表范例](https://www.fmz.com/strategy/125770) - [MA5](https://www.fmz.com/strategy/125474) - - [设定价格微信推送(教学)](https://www.fmz.com/strategy/125482) - - [OkEX Websocket Realtime](https://www.fmz.com/strategy/91176) - [移植 OKCoin 韭菜收割机 注释](https://www.fmz.com/strategy/124178) - [Binance buy and sell statistics|币安买卖统计](https://www.fmz.com/strategy/121917) - [Push Binance deal order to WeChat|实时推送币安成交到微信(wss协议练习)](https://www.fmz.com/strategy/122649) @@ -102,6 +108,7 @@ - [新手上路CoinEx交易 (LTC_USDT)](https://www.fmz.com/strategy/103464) - [画线类库|Plot library](https://www.fmz.com/strategy/27293) - [Iceberg Buy Order](https://www.fmz.com/strategy/103319) + - [山寨币指数(2018.02.22基点1000)](https://www.fmz.com/strategy/73461) - [Dual Thrust OKEX Feature](https://www.fmz.com/strategy/103247) - [转换任意K线周期管理模板(最近更新20180627)](https://www.fmz.com/strategy/41163) - [检查https://quant.la/Argus/是否正常](https://www.fmz.com/strategy/100344) @@ -188,7 +195,6 @@ - [商品期货结算单平仓盈亏历史查询](https://www.fmz.com/strategy/38083) - [Convert_Record_Cycle](https://www.fmz.com/strategy/37678) - [转换任意K线周期](https://www.fmz.com/strategy/35986) - - [API 测试新手入门](https://www.fmz.com/strategy/4) - [js R-Breaker](https://www.fmz.com/strategy/36195) - [JS版本Dual Thrust](https://www.fmz.com/strategy/36100) - [图表界面信息展示实例1](https://www.fmz.com/strategy/36026) diff --git "a/RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245-\347\206\212\345\270\202\347\233\210\345\210\251\345\210\251\345\231\250 (Copy).md" "b/RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245-\347\206\212\345\270\202\347\233\210\345\210\251\345\210\251\345\231\250 (Copy).md" new file mode 100644 index 00000000..9049b5fb --- /dev/null +++ "b/RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245-\347\206\212\345\270\202\347\233\210\345\210\251\345\210\251\345\231\250 (Copy).md" @@ -0,0 +1,417 @@ + +> 策略名称 + +RSI统计套利策略-熊市盈利利器 (Copy) + +> 策略作者 + +安成蜗牛 + +> 策略描述 + +策略介绍: + +此策略是基于RSI指标的统计套利策略,根据实测在熊市中也能有很高的胜率。策略会对行情进行RSI数据分析,一旦捕获到预定义的K线形态即进行短期套利。 + +RSI指标说明: + +RSI最早被用于期货交易中,后来人们发现用该指标来指导股票市场投资效果也十分不错,并对该指标的特点不断进行归纳和总结。现在,RSI已经成为被投资者应用最广泛的技术指标之一。投资的一般原理认为,投资者的买卖行为是各种因素综合结果的反映,行情的变化最终取决于供求关系,而RSI指标正是根据供求平衡的原理,通过测量某一个期间内股价上涨总幅度占股价变化总幅度平均值的百分比,来评估多空力量的强弱程度,进而提示具体操作的。 + +策略特点: + +支持任意级别的趋势跟踪(分钟K,小时K,日K,周K等) +支持任意交易对(ETH/BTC, BSV/BTC等) +支持任意交易所 +详细的策略报表(包括策略状态,交易历史记录等) +支持接近10个自定义个性化参数 + +使用说明: + +此策略基于Botvs实现,在使用之前需要有一个botvs账户 +上传策略并创建机器人 +配置参数并运行策略 + +参数说明: +http://www.pcclean.io/rsi%E7%BB%9F%E8%AE%A1%E5%A5%97%E5%88%A9%E7%AD%96%E7%95%A5/ + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|wq|true|wq| +|wq2|true|wq2| + + + + +|按钮|默认值|描述| +|----|----|----| +|2|12|安全| + + +> 源码 (javascript) + +``` javascript +/* +RSI策略:仅用于学习用途,用于实盘后果自负 +*/ + +var ExchangProcessor={ + createNew: function(exc_obj){ + //策略参数 + var manage_assets=1;//bch + var max_positions=4;//max=4N + var price_n={BTC_BCH:8,ETH_BCH:8,XRP_BCH:8,EOS_BCH:8,LTC_BCH:8,DASH_BCH:8,CET_BCH:8}; //价格精度 + var num_n={BTC_BCH:8,ETH_BCH:8,XRP_BCH:8,EOS_BCH:8,LTC_BCH:8,DASH_BCH:8,CET_BCH:8}; //数量精度 + var minest_buy={BTC_BCH:0.001,ETH_BCH:0.01,XRP_BCH:1,EOS_BCH:1,LTC_BCH:0.1,DASH_BCH:0.01,CET_BCH:1};//最小买入量 + var minest_sell={BTC_BCH:0.001,ETH_BCH:0.01,XRP_BCH:1,EOS_BCH:1,LTC_BCH:0.1,DASH_BCH:0.01,CET_BCH:1};//最小卖出量 + var order_wait_secs=120000; //订单的最长等待时间 毫秒 + var wait_ms=1000;//默认等待毫秒 + var sxf=0.0005;//用来计算手续费消耗 + + + //全局状态变量 + var positions=[];//记录仓位 + var init_asset=0; //初始资产 + var trades=[];//所有交易 + var trades_recorder=true;//记录所有交易 + var pre_time=null; //记录轮询间隔时间 + var approximate_profit=0;//盈亏近似值 + var add_already=0;//已经加仓次数 + + var processor={}; + //重试购买,直到成功返回 + processor.retryBuy=function(ex,price,num) + { + var currency=ex.GetCurrency(); + var r=ex.Buy(_N(price,price_n[currency]), _N(num,num_n[currency])); + while (!r){ + Log("Buy失败,正在retry。"); + Sleep(wait_ms); + var account=_C(ex.GetAccount); + var ticker=_C(ex.GetTicker); + var last=ticker.Last; + var fixedAmount=(price===-1?Math.min(account.Balance*0.95,num):Math.min(account.Balance/last*0.95,num)); + r=ex.Buy(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); + } + return r; + } + + //重试卖出,直到成功返回 + processor.retrySell=function(ex,price,num){ + var currency=ex.GetCurrency(); + var r=ex.Sell(_N(price,price_n[currency]), _N(num,num_n[currency])); + while (!r){ + Log("Sell失败,正在retry。"); + Sleep(wait_ms); + var account=_C(ex.GetAccount); + var fixedAmount=Math.min(account.Stocks,num); + r=ex.Sell(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); + } + return r; + } + + + processor.get_ChinaTimeString=function(){ + var date = new Date(); + var now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), + date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); + var cdate=new Date(now_utc); + cdate.setHours(cdate.getHours()+8); + var localstring=cdate.getFullYear()+'/'+(cdate.getMonth()+1)+'/'+cdate.getDate()+' '+cdate.getHours()+':'+cdate.getMinutes()+':'+cdate.getSeconds(); + return localstring; + } + + processor.init_obj=function(){ + _CDelay(wait_ms); + pre_time = new Date(); + + //init + { + var account=_C(exc_obj.GetAccount); + var ticker=_C(exc_obj.GetTicker); + var last=ticker.Last; + init_asset=(account.Balance+account.FrozenBalance)+(account.Stocks+account.FrozenStocks)*last; + Sleep(wait_ms); + } + } + + + processor.work=function(){ + var cur_time = new Date(); + var passedtime=cur_time-pre_time; + pre_time=cur_time; + + //计算n,头寸 + var exname=exc_obj.GetName(); + var currency=exc_obj.GetCurrency(); + var account=_C(exc_obj.GetAccount); + var ticker=_C(exc_obj.GetTicker); + var depth = _C(exc_obj.GetDepth); + var last=ticker.Last; + var ask1=depth.Asks[0].Price; + var bid1=depth.Bids[0].Price; + var bestprice=bid1+(Math.abs(ask1-bid1)/2); + var records = _C(exc_obj.GetRecords); + if (records.length<=50){ + Log("records.length is not valid."); + Sleep(wait_ms); + return; + } + var atr = TA.ATR(records, 20); + if (atr.length<=1){ + Log("atr.length is not valid."); + Sleep(wait_ms); + return; + } + var N=atr[atr.length-1]; + var position_unit=Math.min(manage_assets*0.01/N,account.Balance/last*0.95);//cet + //Log("N="+N+", 头寸单位="+position_unit+"CET"); + var highest=TA.Highest(records, 20, 'High'); + var Lowest=TA.Lowest(records, 10, 'Low'); + var cur_asset=(account.Balance+account.FrozenBalance)+(account.Stocks+account.FrozenStocks)*last; + var rsi6 = TA.RSI(records, 6); + var rsi12 = TA.RSI(records, 12); + if (rsi6.length<=5 || rsi12.length<=5){ + Log("rsi is not valid."); + Sleep(wait_ms); + return; + } + var rsi_in=false; + if (rsi6[rsi6.length-1]-rsi6[rsi6.length-2]>1 && rsi6[rsi6.length-2]<=65){ + //Log("rsi_in=true"); + rsi_in=true; + } + var rsi_out=false; + if (rsi6[rsi6.length-1]>=60){ + //Log("rsi_out=true"); + rsi_out=true; + } + + //建仓 + if (positions.length==0 && position_unit>minest_buy[currency]){ + if (rsi_in) + { + var buyID = processor.retryBuy(exc_obj,last,position_unit); + Sleep(order_wait_secs); + var buyOrder=_C(exc_obj.GetOrder,buyID); + if (buyOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(buyID); + } + if (buyOrder.DealAmount>0){ + var postion = { + amount:buyOrder.DealAmount, + buy_price:buyOrder.AvgPrice, + stoploss_price:buyOrder.AvgPrice-N}; + positions.push(postion); + + var details={ + type:"建仓", + time:processor.get_ChinaTimeString(), + RealAmount:buyOrder.DealAmount, + WantAmount:position_unit, + RealPrice:buyOrder.AvgPrice, + WantPrice:buyOrder.Price, + Memo:"" + }; + if (trades_recorder){ + trades.push(details); + } + + add_already=1; + } + } + } + + //加仓 + if (positions.length>0 && position_unit>minest_buy[currency]){ + var last_buy_price=positions[positions.length-1].buy_price; + if (add_already=0.5*N){ + var buyID = processor.retryBuy(exc_obj,last,position_unit); + Sleep(order_wait_secs); + var buyOrder=_C(exc_obj.GetOrder,buyID); + if (buyOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(buyID); + } + if (buyOrder.DealAmount>0){ + var postion = { + amount:buyOrder.DealAmount, + buy_price:buyOrder.AvgPrice, + stoploss_price:buyOrder.AvgPrice-N}; + positions.push(postion); + + var details={ + type:"加仓", + time:processor.get_ChinaTimeString(), + RealAmount:buyOrder.DealAmount, + WantAmount:position_unit, + RealPrice:buyOrder.AvgPrice, + WantPrice:last, + Memo:"" + }; + if (trades_recorder){ + trades.push(details); + } + + add_already=add_already+1; + } + } + } + } + + //止损 + if (positions.length>0){ + var positions_new=[]; + for (var i=0; i < positions.length; i++){ + if (last<=positions[i].stoploss_price){ + account=_C(exc_obj.GetAccount); + var fixedAmount=Math.min(account.Stocks,positions[i].amount); + if (fixedAmount>minest_sell[currency]){ + var sellID = processor.retrySell(exc_obj, last, fixedAmount); + Sleep(order_wait_secs); + var sellOrder=_C(exc_obj.GetOrder,sellID); + approximate_profit+=(sellOrder.AvgPrice*sellOrder.DealAmount*(1-sxf)-positions[i].buy_price*sellOrder.DealAmount*(1+sxf)); + Log("定价卖出: 数量-"+sellOrder.DealAmount+",approximate_profit="+approximate_profit); + if (sellOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(sellID); + if (Math.min(account.Stocks,fixedAmount-sellOrder.DealAmount)>minest_sell[currency]){ + var marketsellOrderID=processor.retrySell(exc_obj, -1, fixedAmount-sellOrder.DealAmount); + Sleep(order_wait_secs); + var marketsellOrderData=_C(exc_obj.GetOrder,marketsellOrderID); + approximate_profit+=(marketsellOrderData.AvgPrice*marketsellOrderData.DealAmount*(1-sxf)-positions[i].buy_price*marketsellOrderData.DealAmount*(1+sxf)); + Log("市价卖出: 数量-"+marketsellOrderData.DealAmount+",approximate_profit="+approximate_profit); + } + } + + var details={ + type:"止损", + time:processor.get_ChinaTimeString(), + RealAmount:-1, + WantAmount:fixedAmount, + RealPrice:-1, + WantPrice:last, + Memo:(last>positions[i].buy_price?"盈利":"亏损") + }; + if (trades_recorder){ + trades.push(details); + } + } + }else{ + positions_new.push(positions[i]); + } + } + positions=positions_new; + } + + //清仓 + if (positions.length>0){ + if (rsi_out){ + var positions_new=[]; + for (var i=0; i < positions.length; i++){ + account=_C(exc_obj.GetAccount); + var fixedAmount=Math.min(account.Stocks,positions[i].amount); + if (fixedAmount>minest_sell[currency]){ + var sellID = processor.retrySell(exc_obj, last, fixedAmount); + Sleep(order_wait_secs); + var sellOrder=_C(exc_obj.GetOrder,sellID); + approximate_profit+=(sellOrder.AvgPrice*sellOrder.DealAmount*(1-sxf)-positions[i].buy_price*sellOrder.DealAmount*(1+sxf)); + Log("定价卖出: 数量-"+sellOrder.DealAmount+",approximate_profit="+approximate_profit); + if (sellOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(sellID); + if (Math.min(account.Stocks,fixedAmount-sellOrder.DealAmount)>minest_sell[currency]){ + var marketsellOrderID=processor.retrySell(exc_obj, -1, fixedAmount-sellOrder.DealAmount); + Sleep(order_wait_secs); + var marketsellOrderData=_C(exc_obj.GetOrder,marketsellOrderID); + approximate_profit+=(marketsellOrderData.AvgPrice*marketsellOrderData.DealAmount*(1-sxf)-positions[i].buy_price*marketsellOrderData.DealAmount*(1+sxf)); + Log("市价卖出: 数量-"+marketsellOrderData.DealAmount+",approximate_profit="+approximate_profit); + } + } + + var details={ + type:"清仓", + time:processor.get_ChinaTimeString(), + RealAmount:-1, + WantAmount:fixedAmount, + RealPrice:-1, + WantPrice:last, + Memo:(last>positions[i].buy_price?"盈利":"亏损") + }; + if (trades_recorder){ + trades.push(details); + } + } + } + positions=positions_new; + } + } + + + //显示状态 + var table1 = {type: 'table', title: '仓位-'+exname+'('+currency+')', cols: ['数量', '成交价','止损价'], rows: []}; + var table2 = {type: 'table', title: '状态-'+exname+'('+currency+')', cols: ['平均真实波幅(N)','头寸单位','初始资产','当前资产','轮询时间','最新价','Highest','Lowest','加仓次数','【近似盈亏】'], rows: []}; + var table3 = {type: 'table', title: '交易历史-'+exname+'('+currency+')', cols: ['日期','类型', '成交数量','发单数量','成交价','发单价','备注'], rows: []}; + for (var i=0; i < positions.length; i++){ + table1.rows.push([positions[i].amount,positions[i].buy_price,positions[i].stoploss_price]); + } + table2.rows.push([N,position_unit,init_asset,cur_asset,passedtime+'ms',last,highest,Lowest,add_already,approximate_profit]); + for (i=0; i < trades.length; i++){ + table3.rows.push([trades[i].time,trades[i].type,trades[i].RealAmount,trades[i].WantAmount,trades[i].RealPrice,trades[i].WantPrice,trades[i].Memo]); + } + processor.logstatus=('`' + JSON.stringify([table1, table2, table3])+'`'+'\n'); + + //记录盈利 + processor.logprofit=approximate_profit; + + //rest + Sleep(wait_ms); + } + + return processor; + } +}; + + + +//主函数 +function main(){ + var exchange_num=exchanges.length; + var processors=[]; + for (var i=0; i 策略出处 + +https://www.fmz.com/strategy/138171 + +> 更新时间 + +2019-03-13 18:16:38 diff --git "a/\345\237\272\344\272\216\351\232\217\346\234\272\346\243\256\346\236\227\347\232\204\350\266\213\345\212\277\347\255\226\347\225\245.md" "b/\345\237\272\344\272\216\351\232\217\346\234\272\346\243\256\346\236\227\347\232\204\350\266\213\345\212\277\347\255\226\347\225\245.md" new file mode 100644 index 00000000..48e3b1bb --- /dev/null +++ "b/\345\237\272\344\272\216\351\232\217\346\234\272\346\243\256\346\236\227\347\232\204\350\266\213\345\212\277\347\255\226\347\225\245.md" @@ -0,0 +1,87 @@ + +> 策略名称 + +基于随机森林的趋势策略 + +> 策略作者 + +发明者量化 + + + + + +> 源码 (python) + +``` python +'''backtest +start: 2019-02-09 00:00:00 +end: 2019-03-11 00:00:00 +period: 1h +exchanges: [{"eid":"OKCoin_EN","currency":"BTC_USD"}] +''' + +import itertools +from collections import deque + +import numpy as np +from sklearn.ensemble import RandomForestClassifier + +def main(): + initAccount = _C(exchange.GetAccount) + position = 0 + classifier = RandomForestClassifier() + win_len = 8 + input = deque(maxlen=300) + output = deque(maxlen=300) + recent_prices = deque(maxlen=win_len + 2) + interval = 3600000 # 一小时采样一次 + + while True: + ticker = _C(exchange.GetTicker) + recent_prices.append(ticker.Last) + + if len(recent_prices) > 0: + Sleep(interval) + + if len(recent_prices) < recent_prices.maxlen: + continue + # 计算波动率 + price_list = list(itertools.islice(recent_prices, 0, recent_prices.maxlen - 1)) + volt_list = np.divide(np.diff(recent_prices), price_list) + # 根据波动范围,将其分类标记为: 上涨(>+0.5%)、下跌(<-0.5%)、平稳(-0.5%~+0.5%) + trend_list = [] + for volt in volt_list: + if 0.005 > volt > -0.005: + trend_list.append(0) + elif volt >= 0.005: + trend_list.append(1) + else: + trend_list.append(-1) + + # 添加波动数据到训练集 + input.append(trend_list[:-1]) + output.append(trend_list[-1]) + + # 当训练集个数包含 200 组数据时,认为可以拟合随机森林 + if len(input) < 200: + continue + classifier.fit(input, output) # 拟合 + prediction = classifier.predict([trend_list[1:]]) # 预测 + if position == 0: + if prediction == 1: + exchange.Buy(-1, _C(exchange.GetAccount).Balance) + position = 1 + else: + if prediction == -1: + exchange.Sell(-1, _C(exchange.GetAccount).Stocks - initAccount.Stocks) + position = 0 +``` + +> 策略出处 + +https://www.fmz.com/strategy/140199 + +> 更新时间 + +2019-03-19 11:05:44 diff --git "a/\345\261\261\345\257\250\345\270\201\346\214\207\346\225\260\357\274\2102018.02.22\345\237\272\347\202\2711000\357\274\211.md" "b/\345\261\261\345\257\250\345\270\201\346\214\207\346\225\260\357\274\2102018.02.22\345\237\272\347\202\2711000\357\274\211.md" new file mode 100644 index 00000000..8647b4d2 --- /dev/null +++ "b/\345\261\261\345\257\250\345\270\201\346\214\207\346\225\260\357\274\2102018.02.22\345\237\272\347\202\2711000\357\274\211.md" @@ -0,0 +1,70 @@ + +> 策略名称 + +山寨币指数(2018.02.22基点1000) + +> 策略作者 + +botvsing + + + + + +> 源码 (python) + +``` python +#!/usr/bin/env python +# -*- coding: utf-8 -*-coding +import time +import urllib2 +import json +import pickle + +def updateTicker(): + global index,initPrice + ticker = json.loads(urllib2.urlopen('https://api.binance.com/api/v3/ticker/price',timeout=10).read()) + change = [] + for t in ticker: + if t['symbol'][-3:] == 'BTC': + if t['symbol'][:-3] in initPrice.keys(): + change.append(float(t['price'])/initPrice[t['symbol'][:-3]]) + else: + initPrice[t['symbol'][:-3]] = float(t['price']) + f=open('price.pkl','w') + pickle.dump(initPrice,f,0) + f.close() + Log(t['symbol'][:-3],' added') + if len(change)>0: + index = 1000*sum(change)/len(change) + + + +initPrice = {} +price = {} +index = 1000 +try: + f=open('price.pkl','r') + initPrice=pickle.load(f) + f.close() +except: + initPrice = {} +Log('共计入山寨币:', len(initPrice)) +def main(): + while True: + try: + updateTicker() + LogProfit(round(index,4)) + except Exception as e: + pass + Sleep(3600000) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/73461 + +> 更新时间 + +2018-07-04 18:15:59 diff --git "a/\346\201\222\346\270\251\345\231\250 Thermostat \346\213\251\346\227\266\347\255\226\347\225\245\347\240\224\347\251\266.md" "b/\346\201\222\346\270\251\345\231\250 Thermostat \346\213\251\346\227\266\347\255\226\347\225\245\347\240\224\347\251\266.md" index 8a8e6df9..30805ea0 100644 --- "a/\346\201\222\346\270\251\345\231\250 Thermostat \346\213\251\346\227\266\347\255\226\347\225\245\347\240\224\347\251\266.md" +++ "b/\346\201\222\346\270\251\345\231\250 Thermostat \346\213\251\346\227\266\347\255\226\347\225\245\347\240\224\347\251\266.md" @@ -14,7 +14,7 @@ Hukybo > 源码 (麦语言) ``` pascal -// 回测配置 +// 回测配置 (*backtest start: 2011-01-01 09:00:00 end: 2019-01-01 15:00:00 @@ -74,4 +74,4 @@ https://www.fmz.com/strategy/127033 > 更新时间 -2019-01-05 17:21:13 +2019-03-26 16:17:52 diff --git "a/\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211.md" "b/\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211.md" deleted file mode 100644 index c0350c2a..00000000 --- "a/\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211.md" +++ /dev/null @@ -1,51 +0,0 @@ - -> 策略名称 - -设定价格微信推送(教学) - -> 策略作者 - -botvsing - - - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|Currency|BTC_USDT|监控的交易对| -|UpPrice|6600|价格大于| -|LowPrice|6500|价格小于| -|Interval|10|轮询时间| - - -> 源码 (javascript) - -``` javascript -//实际使用时行情接口用HttpQuery访问,运行在模拟盘上就可以免费了 -function main() { - exchange.IO("currency", Currency) - var lastPushTime = 0 - while(true){ - var ticker = _C(exchange.GetTicker) - if(ticker.Last > UpPrice || ticker.Last < LowPrice){ - //五分钟内只推一次 - if(Date.now() - lastPushTime > 300*1000){ - lastPushTime = Date.now() - Log(Currency, '当前价格: ', ticker.Last, '@') - } - } - Sleep(Interval*1000) - } -} -``` - -> 策略出处 - -https://www.fmz.com/strategy/125482 - -> 更新时间 - -2018-11-09 16:11:27 diff --git "a/\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" "b/\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" new file mode 100644 index 00000000..6f1406db --- /dev/null +++ "b/\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" @@ -0,0 +1,56 @@ + +> 策略名称 + +设定价格微信推送(教学)| Push the price information to telegram + +> 策略作者 + +botvsing + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Currency|BTC_USDT|trading pair| +|UpPrice|5500|when price is higher than| +|LowPrice|5000|when price is lower than| +|Interval|10|interval| + + +> 源码 (javascript) + +``` javascript +/* +This stragegy will sent a message to your telegram when the price is higher or lower than +the set price. +All stragegy must has a main function as the entrance. +*/ +function main() { + //change symbol,will cover the default exchange which was set when start a bot.Currency is a strategy arguments + exchange.IO("currency", Currency) + var lastPushTime = 0 //the variable of last push timestamp. + while(true){ //run a infinite loop, which is the basic structure + var ticker = _C(exchange.GetTicker) // for information about GetTicker, check on https://fmz-docs.readthedocs.io/en/latest/code_Instruction/Market%20API.html#getticker + if(ticker.Last > UpPrice || ticker.Last < LowPrice){ //ticker.Last represents the last deal price + if(Date.now() - lastPushTime > 300*1000){ //only push once in 5 mins, Date.now() return ms. + lastPushTime = Date.now() //update lastPushTime + Log(Currency, 'Price is: ', ticker.Last, '@') //Log the price on the bot's page and sent the message. '@' in the end means push message + } + } + Log(Currency, 'Price is: ', ticker.Last) //just log the price + Sleep(Interval*1000) //check the last price again after Interval seconds + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/125482 + +> 更新时间 + +2019-04-09 17:06:16 diff --git "a/\351\272\246\350\257\255\350\250\200\347\275\221\346\240\274\347\255\226\347\225\245.md" "b/\351\272\246\350\257\255\350\250\200\347\275\221\346\240\274\347\255\226\347\225\245.md" new file mode 100644 index 00000000..92817804 --- /dev/null +++ "b/\351\272\246\350\257\255\350\250\200\347\275\221\346\240\274\347\255\226\347\225\245.md" @@ -0,0 +1,45 @@ + +> 策略名称 + +麦语言网格策略 + +> 策略作者 + +a8269917 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|ktkc|10|空头起始仓位| +|dtkc|false|多头起始仓位| +|y|0.02|盈利减仓距离| +|s|0.02|亏损加仓距离| +|jia|true|亏损加仓数量| +|jian|true|盈利减仓数量| + + +> 源码 (麦语言) + +``` pascal +VARIABLE:V1:1; +IF dtkc>0 AND BKVOL=0 THEN BEGIN 1,BK(dtkc);V1:C;INFO(1,V1);END +IF ktkc>0 AND SKVOL=0 THEN BEGIN 1,SK(ktkc);V1:C;INFO(1,V1);END +IF BKVOL>0 AND C>V1*(1+y) THEN BEGIN 1,SP(jian);V1:C;INFO(1,V1);END +IF BKVOL>0 AND C0 AND C0 AND C>V1*(1+s) THEN BEGIN 1,SK(jia);V1:C;INFO(1,V1);END +TRADE_AGAIN(1000); +``` + +> 策略出处 + +https://www.fmz.com/strategy/142701 + +> 更新时间 + +2019-04-02 13:15:33 From 758dab0c914f007dcb1f0b44ed7724a9a4b4ec6f Mon Sep 17 00:00:00 2001 From: Zero Date: Tue, 9 Jul 2019 12:09:54 +0800 Subject: [PATCH 13/19] update --- ...45\346\234\272\345\231\250\344\272\272.md" | 8 +- ...10\346\225\231\345\255\246\357\274\211.md" | 108 +++ ...60\345\215\226\347\273\237\350\256\241.md" | 4 +- "CTP \346\234\237\350\264\247.md" | 649 ------------------ ...344\272\206SSL\351\252\214\350\257\201.md" | 2 +- ...13\350\257\225\350\214\203\344\276\213.md" | 119 ++++ ...bit websocket \350\214\203\344\276\213.md" | 101 +++ ...44\346\230\223\346\250\241\346\235\277.md" | 78 +++ ...15\344\276\233\345\272\224\351\207\217.md" | 4 +- ...73\345\233\276\350\214\203\344\276\213.md" | 106 +++ ...32\346\212\225\347\255\226\347\225\245.md" | 2 +- ...ime v2.md => OkEX Websocket Realtime v3.md | 41 +- ...41\347\220\206\347\263\273\347\273\237.md" | 328 +++++++++ ...56\347\273\203\344\271\240\357\274\211.md" | 5 +- ...13\345\212\277\347\255\226\347\225\245.md" | 2 +- README.md | 63 +- ...07\347\272\277\347\255\226\347\225\245.md" | 149 ---- ...\346\216\245\345\217\243 V2.0.0 Python.md" | 116 ++++ "annotation\345\261\236\346\200\247.md" | 249 +++++++ boll+maboll.md | 106 +++ ...11\351\222\256\350\214\203\344\276\213.md" | 37 + ...256\2712-3) | python PlotLine Template.md" | 4 +- ...10\346\225\231\345\255\246\357\274\211.md" | 93 +++ ...10\346\225\231\345\255\246\357\274\211.md" | 114 +++ ...1-\345\237\272\347\241\200\347\211\210.md" | 125 ++++ ...45\344\275\223\351\252\214\347\211\210.md" | 99 +++ ...17\345\222\214\347\262\276\345\272\246.md" | 16 +- ...47\211\210|Simple Iceberg order to buy.md" | 7 +- ...7\211\210|Simple Iceberg order to sell.md" | 4 +- ...55\226\347\225\245 python \347\211\210.md" | 71 ++ ...5\245\227\347\256\227\346\263\225 V1.2.md" | 2 +- ...76\271\347\275\221\346\240\274 (Copy).md" | 190 +++++ ...74\357\274\211|Multiple charts example.md" | 7 +- ...45\237\272\347\202\2711000\357\274\211.md" | 4 +- ...03\344\276\213\344\273\243\347\240\201.md" | 69 ++ ...\357\274\211|Cancel ALL Binance Orders.md" | 4 +- ...\255\226\347\225\245|Index Balance Bot.md" | 4 +- ...\214\201$.CTA\345\207\275\346\225\260).md" | 2 +- ...44\346\230\223\350\275\257\344\273\266.md" | 180 +++++ "\346\227\245\345\277\227|Logger.md" | 74 ++ ...40\345\200\215\347\256\227\346\263\225.md" | 67 +- ...02\344\273\267\345\256\232\346\212\225.md" | 60 ++ ...61\345\272\246\345\201\232\345\270\202.md" | 131 ++++ ...22\350\275\254\350\214\203\344\276\213.md" | 41 ++ ...ce announcements and sell Delist coin.md" | 7 +- ...07\347\253\240\347\255\226\347\225\245.md" | 141 +--- ...06\346\236\266\346\250\241\346\235\277.md" | 2 +- ...44\272\272|Stop Loss Below Fixed Price.md" | 10 +- ...47\225\245|Moving Average Bot 30 lines.md" | 5 +- ...345\212\250\346\203\205\345\206\2652.0.md" | 2 +- ...Push the price information to telegram.md" | 9 +- ...26\347\225\245\346\272\220\347\240\201.md" | 139 ++++ ...55\347\232\204\345\272\224\347\224\250.md" | 196 ++++++ ...21\346\240\274\347\255\226\347\225\245.md" | 7 +- 54 files changed, 3110 insertions(+), 1053 deletions(-) rename "2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.md" => "2014\345\271\264\347\232\204\347\256\200\346\230\223\346\257\224\347\211\271\345\270\201\351\253\230\351\242\221\347\255\226\347\225\245\346\234\272\345\231\250\344\272\272.md" (96%) create mode 100644 "60\350\241\214\344\270\211\350\247\222\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" delete mode 100644 "CTP \346\234\237\350\264\247.md" create mode 100644 "DMI \346\265\213\350\257\225\350\214\203\344\276\213.md" create mode 100644 "Deribit websocket \350\214\203\344\276\213.md" create mode 100644 "FCoin\346\235\240\346\235\206\344\272\244\346\230\223\346\250\241\346\235\277.md" create mode 100644 "MACD\347\224\273\345\233\276\350\214\203\344\276\213.md" rename OkEX Websocket Realtime v2.md => OkEX Websocket Realtime v3.md (67%) create mode 100644 "OkEX\345\220\210\347\272\246 \344\273\223\344\275\215\347\256\241\347\220\206\347\263\273\347\273\237.md" delete mode 100644 "RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.md" create mode 100644 "Telegram \345\217\221\344\277\241\346\216\245\345\217\243 V2.0.0 Python.md" create mode 100644 "annotation\345\261\236\346\200\247.md" create mode 100644 boll+maboll.md create mode 100644 "python \347\212\266\346\200\201\346\240\217\350\241\250\346\240\274 \346\230\276\347\244\272\346\214\211\351\222\256\350\214\203\344\276\213.md" rename "python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).md" => "python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3) | python PlotLine Template.md" (98%) create mode 100644 "rest \347\211\210OKEX\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" create mode 100644 "websocket \347\211\210OKEX\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" create mode 100644 "\344\270\211\350\247\222\345\245\227\345\210\251-\345\237\272\347\241\200\347\211\210.md" create mode 100644 "\344\270\211\350\247\222\345\245\227\345\210\251\347\255\226\347\225\245\344\275\223\351\252\214\347\211\210.md" create mode 100644 "\345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245 python \347\211\210.md" create mode 100644 "\345\215\225\350\276\271\347\275\221\346\240\274 (Copy).md" rename "\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211.md" => "\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211|Multiple charts example.md" (95%) create mode 100644 "\345\270\201\345\256\211 \346\217\220\345\270\201\350\214\203\344\276\213\344\273\243\347\240\201.md" create mode 100644 "\346\225\260\345\255\227\350\264\247\345\270\201\350\207\252\351\200\202\345\272\224\345\235\207\347\272\277\344\272\244\346\230\223\347\263\273\347\273\237\344\273\245\345\217\212KAMA\347\256\227\346\263\225\350\247\243\346\236\220\342\200\224\342\200\224\345\237\272\344\272\216\345\217\221\346\230\216\350\200\205\351\207\217\345\214\226\344\272\244\346\230\223\350\275\257\344\273\266.md" create mode 100644 "\346\227\245\345\277\227|Logger.md" rename "796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.md" => "\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.md" (87%) create mode 100644 "\346\257\217\346\227\245\345\270\202\344\273\267\345\256\232\346\212\225.md" create mode 100644 "\346\267\261\345\272\246\345\201\232\345\270\202.md" create mode 100644 "\347\201\253\345\270\201\346\234\237\350\264\247\345\270\201\345\270\201\350\264\246\346\210\267\351\227\264\350\265\204\351\207\221\345\210\222\350\275\254\350\214\203\344\276\213.md" rename "\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" => "\350\256\276\345\256\232\346\257\224\347\211\271\345\270\201\344\273\267\346\240\274\345\271\266\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" (80%) create mode 100644 "\350\277\220\347\224\250\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\214\207\346\240\207\345\234\250\346\225\260\345\255\227\350\264\247\345\270\201\344\270\255\351\207\217\345\214\226\344\272\244\346\230\223\357\274\214\351\231\204\345\270\246My\350\257\255\350\250\200\347\255\226\347\225\245\346\272\220\347\240\201.md" create mode 100644 "\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\212\200\346\234\257\346\214\207\346\240\207\345\234\250\345\225\206\345\223\201\346\234\237\350\264\247\344\270\255\347\232\204\345\272\224\347\224\250.md" diff --git "a/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.md" "b/2014\345\271\264\347\232\204\347\256\200\346\230\223\346\257\224\347\211\271\345\270\201\351\253\230\351\242\221\347\255\226\347\225\245\346\234\272\345\231\250\344\272\272.md" similarity index 96% rename from "2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.md" rename to "2014\345\271\264\347\232\204\347\256\200\346\230\223\346\257\224\347\211\271\345\270\201\351\253\230\351\242\221\347\255\226\347\225\245\346\234\272\345\231\250\344\272\272.md" index 4d3cfea6..0efb7256 100644 --- "a/2014\345\271\264\347\232\204\347\256\200\346\230\223\347\237\255\347\272\277\346\234\272\345\231\250\344\272\272.md" +++ "b/2014\345\271\264\347\232\204\347\256\200\346\230\223\346\257\224\347\211\271\345\270\201\351\253\230\351\242\221\347\255\226\347\225\245\346\234\272\345\231\250\344\272\272.md" @@ -1,7 +1,7 @@ > 策略名称 -2014年的简易短线机器人 +2014年的简易比特币高频策略机器人 > 策略作者 @@ -12,7 +12,7 @@ botvsing **策略的介绍** 策略分享地址: -https://www.botvs.com/strategy/1088 +https://www.fmz.com/strategy/1088 这个策略是我做虚拟货币以来的主要策略,后面经过不断完善和修改,复杂了很多,但主要思想并没有改变,分享的这个版本是无明显bug的 最初版本,最为简单清晰,没有仓位管理,每次交易都是满仓,没有卡死后重启等等,但也足够说明问题。 策略从2014年8月运行,直到今年年初交易所收手续费。期间运行的还算很好,亏损的时间很少。资金从最初的200元跑到了80比特币。具体的过程可以看[小草的新浪博客](http://blog.sina.com.cn/u/2389357153)里[虚拟货币自动化交易之路](http://blog.sina.com.cn/s/blog_8e6ab2610102v6sq.html)系列文章。 @@ -44,7 +44,7 @@ https://www.botvs.com/strategy/1088 **代码讲解** -完整的代码可以见我在www.botvs.com得策略分享,这里只讲解核心逻辑函数。在没有改动的情况下,在botvs自带的模拟盘竟然运转完全正常,这是一个3年多前的策略,平台还支持到现在,太让人感动了。 +完整的代码可以见我在www.fmz.com得策略分享,这里只讲解核心逻辑函数。在没有改动的情况下,在botvs自带的模拟盘竟然运转完全正常,这是一个3年多前的策略,平台还支持到现在,太让人感动了。 首先是获取买卖价函数GetPrice(),需要获取订单深度信息,注意不同平台的订单深度信息长度不同,以及即使遍历了所有订单仍然没有所需要的量的情况(在后期许多0.01的网格挂单会导致这种情况),调用是GetPrice('Buy')就是获取买价。 ``` function GetPrice(Type) { @@ -199,4 +199,4 @@ https://www.fmz.com/strategy/1088 > 更新时间 -2018-06-20 17:29:14 +2019-06-06 12:30:10 diff --git "a/60\350\241\214\344\270\211\350\247\222\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" "b/60\350\241\214\344\270\211\350\247\222\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" new file mode 100644 index 00000000..51884f88 --- /dev/null +++ "b/60\350\241\214\344\270\211\350\247\222\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" @@ -0,0 +1,108 @@ + +> 策略名称 + +60行三角对冲策略(教学) + +> 策略作者 + +小小梦 + +> 策略描述 + +## 三角对冲教学策略 + +#### 原理 + - 例如 + A 交易所 : ETH_BTC + B 交易所 : ETH_USDT + C 交易所(其实为 B交易所 另一个交易对而已,逻辑上认为是C。) : BTC_USDT + + - B 、C 交易所交易对组合成 ETH_BTC 和A 交易所对冲。这样BC实际是一个交易所账户。 + +#### 优化空间 + + - 币平衡。 + - 根据手续费率算对冲差价,动态差价。 + - 硬搬砖。 + - 订单薄深度扫描,计算最佳对冲量。 + ..... + + +#### BUG反馈 + - 如有错误欢迎留言。 + + + +> 源码 (javascript) + +``` javascript +// 交易对以 ETH_BTC , ETH_USDT , BTC_USDT 为例 +// 教学策略,还有很大优化空间,例如:币平衡模块,根据手续费率控制对冲差价,硬搬砖等等。 +function main () { + if (exchanges[0].GetQuoteCurrency() != exchanges[2].GetCurrency().split("_")[0] || + exchanges[0].GetCurrency().split("_")[0] != exchanges[1].GetCurrency().split("_")[0]) { + throw "交易所 交易对 配置错误。" + } + var marketSlideRate = 1 // 1.02 + var hedgeDiff = 0.0007 + var hedgeAmount = 0.1 + var isFirst = true + var concurrenter = function (funcName, isWait, tasks, amounts) { + for (var i = 0 ; i < exchanges.length; i++) { + if (isFirst) { + exchanges[i].acc = _C(exchanges[i].GetAccount) + exchanges[i].initAcc = exchanges[i].acc + } + if (isWait) { + var a = funcName == "GetTicker" ? exchanges[i].ticker = exchanges[i].tiR.wait() : exchanges[i].id = exchanges[i].trR.wait() + if (funcName == "trade") { + exchanges[i].acc = _C(exchanges[i].GetAccount) + } + } else { + var b = funcName == "GetTicker" ? exchanges[i].tiR = exchanges[i].Go(funcName) : exchanges[i].trR = exchanges[i].Go(tasks[i], -1, amounts[i], exchanges[i].GetCurrency()) + } + } + if (funcName == "trade" && isWait) { + Log("BTC:", exchange.BTC = exchanges[0].acc.Balance + exchanges[2].acc.Stocks, "ETH:", exchange.ETH = exchanges[0].acc.Stocks + exchanges[1].acc.Stocks, "USDT:", + exchange.USDT = exchanges[1].acc.Balance + exchanges[2].acc.Balance, "#FF0000") + LogProfit(exchange.USDT - (exchanges[1].initAcc.Balance + exchanges[2].initAcc.Balance) - + (exchanges[0].initAcc.Balance + exchanges[2].initAcc.Stocks - exchange.BTC) * exchanges[2].ticker.Last - + (exchanges[0].initAcc.Stocks + exchanges[1].initAcc.Stocks - exchange.ETH) * exchanges[1].ticker.Last) + } + isFirst = false + } + + while (1) { + concurrenter("GetTicker", false) + concurrenter("GetTicker", true) + var tickerA = exchanges[0].ticker + var tickerB = exchanges[1].ticker + var tickerC = exchanges[2].ticker + + var tickerBC = { + Buy : tickerB.Buy / tickerC.Sell, + Sell : tickerB.Sell / tickerC.Buy, + } + + if (tickerA.Buy - tickerBC.Sell > hedgeDiff && exchanges[0].acc.Stocks > 0.2 && exchanges[1].acc.Balance > 500 && exchanges[2].acc.Stocks > 0.03) { // Sell A , Buy BC (Buy B Sell C) + concurrenter("trade", false, ["Sell", "Buy", "Sell"], [hedgeAmount, marketSlideRate * tickerB.Sell * hedgeAmount, tickerB.Sell * hedgeAmount / tickerC.Buy]) + concurrenter("trade", true) + } + if (tickerBC.Buy - tickerA.Sell > hedgeDiff && exchanges[0].acc.Balance > 0.03 && exchanges[1].acc.Stocks > 0.2 && exchanges[2].acc.Balance > 500) { // Buy A , Sell BC (...) + concurrenter("trade", false, ["Buy", "Sell", "Buy"], [marketSlideRate * hedgeAmount * tickerA.Sell, hedgeAmount, marketSlideRate * hedgeAmount * tickerA.Sell * tickerC.Sell]) + concurrenter("trade", true) + } + Sleep(500) + } +} + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/144257 + +> 更新时间 + +2019-04-16 16:38:17 diff --git "a/Binance buy and sell statistics|\345\270\201\345\256\211\344\271\260\345\215\226\347\273\237\350\256\241.md" "b/Binance buy and sell statistics|\345\270\201\345\256\211\344\271\260\345\215\226\347\273\237\350\256\241.md" index 2151fb4d..e4a98338 100644 --- "a/Binance buy and sell statistics|\345\270\201\345\256\211\344\271\260\345\215\226\347\273\237\350\256\241.md" +++ "b/Binance buy and sell statistics|\345\270\201\345\256\211\344\271\260\345\215\226\347\273\237\350\256\241.md" @@ -9,7 +9,7 @@ botvsing > 策略描述 -记录主动成交数据 +记录主动成交数据,反映了买卖盘的活跃程度 > 策略参数 @@ -67,4 +67,4 @@ https://www.fmz.com/strategy/121917 > 更新时间 -2018-10-27 16:01:47 +2019-07-03 16:35:27 diff --git "a/CTP \346\234\237\350\264\247.md" "b/CTP \346\234\237\350\264\247.md" deleted file mode 100644 index 70fdbbc4..00000000 --- "a/CTP \346\234\237\350\264\247.md" +++ /dev/null @@ -1,649 +0,0 @@ - -> 策略名称 - -CTP 期货 - -> 策略作者 - -bbsang - -> 策略描述 - -- 只支持操作CTP商品期货 -- 支持自动或手动恢复进度 -- 可同时操作多个不同品种 -- 增加时间段区分与各种网络错误问题的应对处理 -- 移仓功能目前正在加入中 - -请下载最新托管者并比较版本号是否最新 -``` text -$ ./robot -v -BotVS docker 3.0 compiled at 2016-07-05T09:56:18+0800 -``` - - https://dn-filebox.qbox.me/d33687abb648c489b6883296685e8717ea3f44ca.png - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|Instruments|MA701,CF701,zn1701,SR701,pp1701,l1701,hc1610,ni1701,i1701,v1701,rb1610,jm1701,ag1612,al1701,jd1701,cs1701,p1701|合约列表| -|LoopInterval|3|轮询周期(秒)| -|RiskRatio|true|% Risk Per N ( 0 - 100)| -|ATRLength|20|ATR计算周期| -|EnterPeriodA|20|系统一入市周期| -|LeavePeriodA|10|系统一离市周期| -|EnterPeriodB|55|系统二入市周期| -|LeavePeriodB|20|系统二离市周期| -|UseEnterFilter|true|使用入市过滤| -|IncSpace|0.5|加仓间隔(N的倍数)| -|StopLossRatio|2|止损系数(N的倍数)| -|MaxLots|4|单品种加仓次数| -|RMode|0|进度恢复模式: 自动|手动| -|VMStatus|{}|手动恢复字符串| -|WXPush|true|推送交易信息| -|MaxTaskRetry|5|开仓最多重试次数| -|KeepRatio|10|预留保证金比例| - - - - -|按钮|默认值|描述| -|----|----|----| -|暂停/继续|__button__|暂停/继续| - - -> 源码 (javascript) - -``` javascript -/*backtest -start: 2016-03-01 00:00:00 -end: 2016-12-30 00:00:00 -period: 1h -exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] -*/ - -var _bot = $.NewPositionManager(); - -var TTManager = { - New: function(needRestore, symbol, keepBalance, riskRatio, atrLen, enterPeriodA, leavePeriodA, enterPeriodB, leavePeriodB, useFilter, - multiplierN, multiplierS, maxLots) { - - // subscribe - var symbolDetail = _C(exchange.SetContractType, symbol); - if (symbolDetail.VolumeMultiple == 0 || symbolDetail.MaxLimitOrderVolume == 0 || symbolDetail.MinLimitOrderVolume == 0 || symbolDetail.LongMarginRatio == 0 || symbolDetail.ShortMarginRatio == 0) { - Log(symbolDetail); - throw "合约信息异常"; - } else { - Log("合约", symbolDetail.InstrumentName, "一手", symbolDetail.VolumeMultiple, "份, 最大下单量", symbolDetail.MaxLimitOrderVolume, "保证金率:", _N(symbolDetail.LongMarginRatio), _N(symbolDetail.ShortMarginRatio), "交割日期", symbolDetail.StartDelivDate); - } - - var ACT_IDLE = 0; - var ACT_LONG = 1; - var ACT_SHORT = 2; - var ACT_COVER = 3; - - - var ERR_SUCCESS = 0; - var ERR_SET_SYMBOL = 1; - var ERR_GET_ORDERS = 2; - var ERR_GET_POS = 3; - var ERR_TRADE = 4; - var ERR_GET_DEPTH = 5; - var ERR_NOT_TRADING = 6; - var errMsg = ["成功", "切换合约失败", "获取订单失败", "获取持仓失败", "交易下单失败", "获取深度失败", "不在交易时间"]; - - var obj = { - symbol: symbol, - keepBalance: keepBalance, - riskRatio: riskRatio, - atrLen: atrLen, - enterPeriodA: enterPeriodA, - leavePeriodA: leavePeriodA, - enterPeriodB: enterPeriodB, - leavePeriodB: leavePeriodB, - useFilter: useFilter, - multiplierN: multiplierN, - multiplierS: multiplierS - }; - obj.task = { - action: ACT_IDLE, - amount: 0, - dealAmount: 0, - avgPrice: 0, - preCost: 0, - preAmount: 0, - init: false, - retry: 0, - desc: "空闲", - onFinish: null - } - obj.maxLots = maxLots; - obj.lastPrice = 0; - obj.symbolDetail = symbolDetail; - obj.status = { - symbol: symbol, - recordsLen: 0, - vm: [], - open: 0, - cover: 0, - st: 0, - marketPosition: 0, - lastPrice: 0, - holdPrice: 0, - holdAmount: 0, - holdProfit: 0, - N: 0, - upLine: 0, - downLine: 0, - symbolDetail: symbolDetail, - lastErr: "", - lastErrTime: "", - stopPrice: '', - leavePrice: '', - isTrading: false - }; - - obj.setLastError = function(err) { - if (typeof(err) === 'undefined' || err === '') { - obj.status.lastErr = ""; - obj.status.lastErrTime = ""; - return; - } - var t = new Date(); - obj.status.lastErr = err; - obj.status.lastErrTime = t.toLocaleString(); - }; - obj.reset = function(marketPosition, openPrice, N, leavePeriod, preBreakoutFailure) { - if (typeof(marketPosition) !== 'undefined') { - obj.marketPosition = marketPosition; - obj.openPrice = openPrice; - obj.preBreakoutFailure = preBreakoutFailure; - obj.N = N; - obj.leavePeriod = leavePeriod; - var pos = _bot.GetPosition(obj.symbol, marketPosition > 0 ? PD_LONG : PD_SHORT); - if (pos) { - obj.holdPrice = pos.Price; - obj.holdAmount = pos.Amount; - Log(obj.symbol, "仓位", pos); - } else { - throw "恢复" + obj.symbol + "的持仓状态出错, 没有找到仓位信息"; - } - Log("恢复", obj.symbol, "加仓次数", obj.marketPosition, "持仓均价:", obj.holdPrice, "持仓数量:", obj.holdAmount, "最后一次加仓价", obj.openPrice, "N值", obj.N, "离市周期:", leavePeriod, "上次突破:", obj.preBreakoutFailure ? "失败" : "成功"); - obj.status.open = 1; - obj.status.vm = [obj.marketPosition, obj.openPrice, obj.N, obj.leavePeriod, obj.preBreakoutFailure]; - } else { - obj.marketPosition = 0; - obj.holdPrice = 0; - obj.openPrice = 0; - obj.holdAmount = 0; - obj.holdProfit = 0; - obj.preBreakoutFailure = true; // test system A - obj.N = 0; - obj.leavePeriod = leavePeriodA; - } - obj.holdProfit = 0; - obj.lastErr = ""; - obj.lastErrTime = ""; - }; - - obj.Status = function() { - obj.status.N = obj.N; - obj.status.marketPosition = obj.marketPosition; - obj.status.holdPrice = obj.holdPrice; - obj.status.holdAmount = obj.holdAmount; - obj.status.lastPrice = obj.lastPrice; - if (obj.lastPrice > 0 && obj.holdAmount > 0 && obj.marketPosition !== 0) { - obj.status.holdProfit = _N((obj.lastPrice - obj.holdPrice) * obj.holdAmount * symbolDetail.VolumeMultiple, 4) * (obj.marketPosition > 0 ? 1 : -1); - } else { - obj.status.holdProfit = 0; - } - return obj.status; - }; - obj.setTask = function(action, amount, onFinish) { - obj.task.init = false; - obj.task.retry = 0; - obj.task.action = action; - obj.task.preAmount = 0; - obj.task.preCost = 0; - obj.task.amount = typeof(amount) === 'number' ? amount : 0; - obj.task.onFinish = onFinish; - if (action == ACT_IDLE) { - obj.task.desc = "空闲"; - obj.task.onFinish = null; - } else { - if (action !== ACT_COVER) { - obj.task.desc = (action == ACT_LONG ? "加多仓" : "加空仓") + "(" + amount + ")"; - } else { - obj.task.desc = "平仓"; - } - Log("接收到任务", obj.symbol, obj.task.desc); - // process immediately - obj.Poll(true); - } - }; - obj.processTask = function() { - var insDetail = exchange.SetContractType(obj.symbol); - if (!insDetail) { - return ERR_SET_SYMBOL; - } - var SlideTick = 1; - var ret = false; - if (obj.task.action == ACT_COVER) { - var hasPosition = false; - do { - if (!$.IsTrading(obj.symbol)) { - return ERR_NOT_TRADING; - } - hasPosition = false; - var positions = exchange.GetPosition(); - if (!positions) { - return ERR_GET_POS; - } - var depth = exchange.GetDepth(); - if (!depth) { - return ERR_GET_DEPTH; - } - var orderId = null; - for (var i = 0; i < positions.length; i++) { - if (positions[i].ContractType !== obj.symbol) { - continue; - } - var amount = Math.min(insDetail.MaxLimitOrderVolume, positions[i].Amount); - if (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) { - exchange.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy"); - orderId = exchange.Sell(_N(depth.Bids[0].Price - (insDetail.PriceTick * SlideTick), 2), Math.min(amount, depth.Bids[0].Amount), obj.symbol, positions[i].Type == PD_LONG ? "平今" : "平昨", 'Bid', depth.Bids[0]); - hasPosition = true; - } else if (positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD) { - exchange.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell"); - orderId = exchange.Buy(_N(depth.Asks[0].Price + (insDetail.PriceTick * SlideTick), 2), Math.min(amount, depth.Asks[0].Amount), obj.symbol, positions[i].Type == PD_SHORT ? "平今" : "平昨", 'Ask', depth.Asks[0]); - hasPosition = true; - } - } - if (hasPosition) { - if (!orderId) { - return ERR_TRADE; - } - Sleep(1000); - while (true) { - // Wait order, not retry - var orders = exchange.GetOrders(); - if (!orders) { - return ERR_GET_ORDERS; - } - if (orders.length == 0) { - break; - } - for (var i = 0; i < orders.length; i++) { - exchange.CancelOrder(orders[i].Id); - Sleep(500); - } - } - } - } while (hasPosition); - ret = true; - } else if (obj.task.action == ACT_LONG || obj.task.action == ACT_SHORT) { - do { - if (!$.IsTrading(obj.symbol)) { - return ERR_NOT_TRADING; - } - Sleep(1000); - while (true) { - // Wait order, not retry - var orders = exchange.GetOrders(); - if (!orders) { - return ERR_GET_ORDERS; - } - if (orders.length == 0) { - break; - } - for (var i = 0; i < orders.length; i++) { - exchange.CancelOrder(orders[i].Id); - Sleep(500); - } - } - var positions = exchange.GetPosition(); - // Error - if (!positions) { - return ERR_GET_POS; - } - // search position - var pos = null; - for (var i = 0; i < positions.length; i++) { - if (positions[i].ContractType == obj.symbol && (((positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) && obj.task.action == ACT_LONG) || ((positions[i].Type == PD_SHORT || positions[i].Type == PD_SHORT_YD) && obj.task.action == ACT_SHORT))) { - if (!pos) { - pos = positions[i]; - pos.Cost = positions[i].Price * positions[i].Amount; - } else { - pos.Amount += positions[i].Amount; - pos.Profit += positions[i].Profit; - pos.Cost += positions[i].Price * positions[i].Amount; - } - } - } - // record pre position - if (!obj.task.init) { - obj.task.init = true; - if (pos) { - obj.task.preAmount = pos.Amount; - obj.task.preCost = pos.Cost; - } else { - obj.task.preAmount = 0; - obj.task.preCost = 0; - } - } - var remain = obj.task.amount; - if (pos) { - obj.task.dealAmount = pos.Amount - obj.task.preAmount; - remain = parseInt(obj.task.amount - obj.task.dealAmount); - if (remain <= 0 || obj.task.retry >= MaxTaskRetry) { - ret = { - price: (pos.Cost - obj.task.preCost) / (pos.Amount - obj.task.preAmount), - amount: (pos.Amount - obj.task.preAmount), - position: pos - }; - break; - } - } else if (obj.task.retry >= MaxTaskRetry) { - ret = null; - break; - } - - var depth = exchange.GetDepth(); - if (!depth) { - return ERR_GET_DEPTH; - } - var orderId = null; - if (obj.task.action == ACT_LONG) { - exchange.SetDirection("buy"); - orderId = exchange.Buy(_N(depth.Asks[0].Price + (insDetail.PriceTick * SlideTick), 2), Math.min(remain, depth.Asks[0].Amount), obj.symbol, 'Ask', depth.Asks[0]); - } else { - exchange.SetDirection("sell"); - orderId = exchange.Sell(_N(depth.Bids[0].Price - (insDetail.PriceTick * SlideTick), 2), Math.min(remain, depth.Bids[0].Amount), obj.symbol, 'Bid', depth.Bids[0]); - } - // symbol not in trading or other else happend - if (!orderId) { - obj.task.retry++; - return ERR_TRADE; - } - } while (true); - } - if (obj.task.onFinish) { - obj.task.onFinish(ret); - } - obj.setTask(ACT_IDLE); - return ERR_SUCCESS; - }; - obj.Poll = function(subroutine) { - obj.status.isTrading = $.IsTrading(obj.symbol); - if (!obj.status.isTrading) { - return; - } - if (obj.task.action != ACT_IDLE) { - var retCode = obj.processTask(); - if (obj.task.action != ACT_IDLE) { - obj.setLastError("任务没有处理成功: " + errMsg[retCode] + ", " + obj.task.desc + ", 重试: " + obj.task.retry); - } else { - obj.setLastError(); - } - return; - } - if (typeof(subroutine) !== 'undefined' && subroutine) { - return; - } - // Loop - var suffix = WXPush ? '@' : ''; - // switch symbol - _C(exchange.SetContractType, obj.symbol); - var records = exchange.GetRecords(); - if (!records) { - obj.setLastError("获取K线失败"); - return; - } - obj.status.recordsLen = records.length; - if (records.length < obj.atrLen) { - obj.setLastError("K线长度小于 " + obj.atrLen); - return; - } - var opCode = 0; // 0: IDLE, 1: LONG, 2: SHORT, 3: CoverALL - var lastPrice = records[records.length - 1].Close; - obj.lastPrice = lastPrice; - if (obj.marketPosition === 0) { - obj.status.stopPrice = '--'; - obj.status.leavePrice = '--'; - obj.status.upLine = 0; - obj.status.downLine = 0; - for (var i = 0; i < 2; i++) { - if (i == 0 && obj.useFilter && !obj.preBreakoutFailure) { - continue; - } - var enterPeriod = i == 0 ? obj.enterPeriodA : obj.enterPeriodB; - if (records.length < (enterPeriod + 1)) { - continue; - } - var highest = TA.Highest(records, enterPeriod, 'High'); - var lowest = TA.Lowest(records, enterPeriod, 'Low'); - obj.status.upLine = obj.status.upLine == 0 ? highest : Math.min(obj.status.upLine, highest); - obj.status.downLine = obj.status.downLine == 0 ? lowest : Math.max(obj.status.downLine, lowest); - if (lastPrice > highest) { - opCode = 1; - } else if (lastPrice < lowest) { - opCode = 2; - } - if (opCode != 0) { - obj.leavePeriod = (enterPeriod == obj.enterPeriodA) ? obj.leavePeriodA : obj.leavePeriodB; - break; - } - } - } else { - var spread = obj.marketPosition > 0 ? (obj.openPrice - lastPrice) : (lastPrice - obj.openPrice); - obj.status.stopPrice = _N(obj.openPrice + (obj.N * StopLossRatio * (obj.marketPosition > 0 ? -1 : 1))); - if (spread > (obj.N * StopLossRatio)) { - opCode = 3; - obj.preBreakoutFailure = true; - Log(obj.symbolDetail.InstrumentName, "止损平仓", suffix); - obj.status.st++; - } else if (-spread > (IncSpace * obj.N)) { - opCode = obj.marketPosition > 0 ? 1 : 2; - } - if (opCode == 0 && records.length > obj.leavePeriod) { - obj.status.leavePrice = obj.marketPosition > 0 ? TA.Lowest(records, obj.leavePeriod, 'Low') : TA.Highest(records, obj.leavePeriod, 'High'); - if ((obj.marketPosition > 0 && lastPrice < obj.status.leavePrice) || - (obj.marketPosition < 0 && lastPrice > obj.status.leavePrice)) { - obj.preBreakoutFailure = false; - Log(obj.symbolDetail.InstrumentName, "正常平仓", suffix); - opCode = 3; - obj.status.cover++; - } - } - } - - if (opCode == 0) { - return; - } - if (opCode == 3) { - obj.setTask(ACT_COVER, 0, function(ret) { - obj.reset(); - _G(obj.symbol, null); - }); - return; - } - // Open - if (Math.abs(obj.marketPosition) >= obj.maxLots) { - obj.setLastError("禁止开仓, 超过最大持仓 " + obj.maxLots); - return; - } - var atrs = TA.ATR(records, atrLen); - var N = _N(atrs[atrs.length - 1], 4); - - var account = _bot.GetAccount(); - var currMargin = JSON.parse(exchange.GetRawJSON()).CurrMargin; - var unit = parseInt((account.Balance+currMargin-obj.keepBalance) * (obj.riskRatio / 100) / N / obj.symbolDetail.VolumeMultiple); - var canOpen = parseInt((account.Balance-obj.keepBalance) / (opCode == 1 ? obj.symbolDetail.LongMarginRatio : obj.symbolDetail.ShortMarginRatio) / (lastPrice * 1.2) / obj.symbolDetail.VolumeMultiple); - unit = Math.min(unit, canOpen); - if (unit < obj.symbolDetail.MinLimitOrderVolume) { - obj.setLastError("可开 " + unit + " 手 无法开仓, " + (canOpen >= obj.symbolDetail.MinLimitOrderVolume ? "风控触发" : "资金限制")); - return; - } - obj.setTask((opCode == 1 ? ACT_LONG : ACT_SHORT), unit, function(ret) { - if (!ret) { - obj.setLastError("下单失败"); - return; - } - Log(obj.symbolDetail.InstrumentName, obj.marketPosition == 0 ? "开仓" : "加仓", "离市周期", obj.leavePeriod, suffix); - obj.N = N; - obj.openPrice = ret.price; - obj.holdPrice = ret.position.Price; - if (obj.marketPosition == 0) { - obj.status.open++; - } - obj.holdAmount = ret.position.Amount; - obj.marketPosition += opCode == 1 ? 1 : -1; - obj.status.vm = [obj.marketPosition, obj.openPrice, N, obj.leavePeriod, obj.preBreakoutFailure]; - _G(obj.symbol, obj.status.vm); - }); - }; - var vm = null; - if (RMode === 0) { - vm = _G(obj.symbol); - } else { - vm = JSON.parse(VMStatus)[obj.symbol]; - } - if (vm) { - Log("准备恢复进度, 当前合约状态为", vm); - obj.reset(vm[0], vm[1], vm[2], vm[3], vm[4]); - } else { - if (needRestore) { - Log("没有找到" + obj.symbol + "的进度恢复信息"); - } - obj.reset(); - } - return obj; - } -}; - -function onexit() { - Log("已退出策略..."); -} - -function main() { - if (exchange.GetName().indexOf('CTP') == -1) { - throw "只支持商品期货CTP"; - } - SetErrorFilter("login|ready|流控|连接失败|初始|Timeout"); - var mode = exchange.IO("mode", 0); - if (typeof(mode) !== 'number') { - throw "切换模式失败, 请更新到最新托管者!"; - } - while (!exchange.IO("status")) { - Sleep(3000); - LogStatus("正在等待与交易服务器连接, " + new Date()); - } - var positions = _C(exchange.GetPosition); - if (positions.length > 0) { - Log("检测到当前持有仓位, 系统将开始尝试恢复进度..."); - Log("持仓信息", positions); - } - Log("风险系数:", RiskRatio, "N值周期:", ATRLength, "系统1: 入市周期", EnterPeriodA, "离市周期", LeavePeriodA, "系统二: 入市周期", EnterPeriodB, "离市周期", LeavePeriodB, "加仓系数:", IncSpace, "止损系数:", StopLossRatio, "单品种最多开仓:", MaxLots, "次"); - var initAccount = _bot.GetAccount(); - var initMargin = JSON.parse(exchange.GetRawJSON()).CurrMargin; - var keepBalance = _N((initAccount.Balance + initMargin) * (KeepRatio/100), 3); - Log("资产信息", initAccount, "保留资金:", keepBalance); - - var tts = []; - var filter = []; - var arr = Instruments.split(','); - for (var i = 0; i < arr.length; i++) { - var symbol = arr[i].replace(/^\s+/g, "").replace(/\s+$/g, ""); - if (typeof(filter[symbol]) !== 'undefined') { - Log(symbol, "已经存在, 系统已自动过滤"); - continue; - } - filter[symbol] = true; - var hasPosition = false; - for (var j = 0; j < positions.length; j++) { - if (positions[j].ContractType == symbol) { - hasPosition = true; - break; - } - } - var obj = TTManager.New(hasPosition, symbol, keepBalance, RiskRatio, ATRLength, EnterPeriodA, LeavePeriodA, EnterPeriodB, LeavePeriodB, UseEnterFilter, IncSpace, StopLossRatio, MaxLots); - tts.push(obj); - } - - - var preTotalHold = -1; - var lastStatus = ''; - while (true) { - if (GetCommand() === "暂停/继续") { - Log("暂停交易中..."); - while (GetCommand() !== "暂停/继续") { - Sleep(1000); - } - Log("继续交易中..."); - } - while (!exchange.IO("status")) { - Sleep(3000); - LogStatus("正在等待与交易服务器连接, " + new Date() + "\n" + lastStatus); - } - var tblStatus = { - type: "table", - title: "持仓信息", - cols: ["合约名称", "持仓方向", "持仓均价", "持仓数量", "持仓盈亏", "加仓次数", "开仓次数", "止损次数", "成功次数", "当前价格", "N"], - rows: [] - }; - var tblMarket = { - type: "table", - title: "运行状态", - cols: ["合约名称", "合约乘数", "保证金率", "交易时间", "柱线长度", "上线", "下线", "止损价", "离市价", "异常描述", "发生时间"], - rows: [] - }; - var totalHold = 0; - var vmStatus = {}; - var ts = new Date().getTime(); - var holdSymbol = 0; - for (var i = 0; i < tts.length; i++) { - tts[i].Poll(); - var d = tts[i].Status(); - if (d.holdAmount > 0) { - vmStatus[d.symbol] = d.vm; - holdSymbol++; - } - tblStatus.rows.push([d.symbolDetail.InstrumentName, d.holdAmount == 0 ? '--' : (d.marketPosition > 0 ? '多' : '空'), d.holdPrice, d.holdAmount, d.holdProfit, Math.abs(d.marketPosition), d.open, d.st, d.cover, d.lastPrice, d.N]); - tblMarket.rows.push([d.symbolDetail.InstrumentName, d.symbolDetail.VolumeMultiple, _N(d.symbolDetail.LongMarginRatio, 4) + '/' + _N(d.symbolDetail.ShortMarginRatio, 4), (d.isTrading ? '是#0000ff' : '否#ff0000'), d.recordsLen, d.upLine, d.downLine, d.stopPrice, d.leavePrice, d.lastErr, d.lastErrTime]); - totalHold += Math.abs(d.holdAmount); - } - var now = new Date(); - var elapsed = now.getTime() - ts; - var tblAssets = _bot.GetAccount(true); - var nowAccount = _bot.Account(); - - if (tblAssets.rows.length > 10) { - // replace AccountId - tblAssets.rows[0] = ["InitAccount", "初始资产", initAccount]; - } else { - tblAssets.rows.unshift(["NowAccount", "当前可用", nowAccount], ["InitAccount", "初始资产", initAccount]); - } - lastStatus = '`' + JSON.stringify([tblStatus, tblMarket, tblAssets]) + '`\n轮询耗时: ' + elapsed + ' 毫秒, 当前时间: ' + now.toLocaleString() + ', 星期' + ['日', '一', '二', '三', '四', '五', '六'][now.getDay()] + ", 持有品种个数: " + holdSymbol; - if (totalHold > 0) { - lastStatus += "\n手动恢复字符串: " + JSON.stringify(vmStatus); - } - LogStatus(lastStatus); - if (preTotalHold > 0 && totalHold == 0) { - LogProfit(nowAccount.Balance - initAccount.Balance - initMargin); - } - preTotalHold = totalHold; - Sleep(LoopInterval * 1000); - } -} -``` - -> 策略出处 - -https://www.fmz.com/strategy/130234 - -> 更新时间 - -2018-12-14 12:31:22 diff --git "a/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.md" "b/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.md" index 47dabfac..4f43a3b7 100644 --- "a/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.md" +++ "b/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.md" @@ -11,7 +11,7 @@ botvsing ## CoinPark通用协议Python2版本 用途:可以使BotVs支持coinpark.cc交易所 -代码公开地址:https://www.botvs.com/strategy/101399 +代码公开地址:https://www.fmz.com/strategy/101399 运行地址 http://127.0.0.1:6667 diff --git "a/DMI \346\265\213\350\257\225\350\214\203\344\276\213.md" "b/DMI \346\265\213\350\257\225\350\214\203\344\276\213.md" new file mode 100644 index 00000000..a6bd1138 --- /dev/null +++ "b/DMI \346\265\213\350\257\225\350\214\203\344\276\213.md" @@ -0,0 +1,119 @@ + +> 策略名称 + +DMI 测试范例 + +> 策略作者 + +小小梦 + + + + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2019-06-03 00:00:00 +end: 2019-07-03 00:00:00 +period: 1h +exchanges: [{"eid":"Huobi","currency":"BTC_USDT","balance":10000,"stocks":3}] +*/ + +// 指标函数 +function ADX(MDI, PDI, adx_period) { + if(typeof(MDI) == "undefined" || typeof(PDI) == "undefined"){ + return false + } + + if(MDI.length < 10 || PDI.length < 10){ + return false + } + + /* + DX = abs(DIPlus-DIMinus) / (DIPlus+DIMinus)*100 + ADX = sma(DX, len) + */ + + var dx = [] + for(var i = 0; i < MDI.length; i++){ + if(!MDI[i] || !PDI[i]){ + continue + } + var dxValue = Math.abs((PDI[i] - MDI[i])) / (PDI[i] + MDI[i]) * 100 + var obj = { + Close : dxValue, + } + dx.push(obj) + } + + if(dx.length < adx_period){ + return false + } + + var adx = talib.SMA(dx, adx_period) + + return adx +} + +function DMI(records, pdi_period, mdi_period, adxr_period, adx_period) { + var recordsHLC = [] + for(var i = 0; i < records.length ; i++){ + var bar = { + High : records[i].High, + Low : records[i].Low, + Close : records[i].Close, + } + recordsHLC.push(bar) + } + + var m_di = talib.MINUS_DI(recordsHLC, mdi_period) + var p_di = talib.PLUS_DI(recordsHLC, pdi_period) + + var adx = ADX(m_di, p_di, adx_period) + + // ADXR=(当日的ADX+前n日的ADX)÷2 + var n = 0 + var adxr = [] + for (var j = 0 ; j < adx.length; j++) { + if (typeof(adx[j]) == "number") { + n++ + } + + if (n >= adxr_period) { + var currAdxr = (adx[j] + adx[j - adxr_period]) / 2 + adxr.push(currAdxr) + } else { + adxr.push(NaN) + } + } + + return [m_di, p_di, adx, adxr] +} + + + +function main() { + while(1){ + var records = exchange.GetRecords() + var ret = DMI(records, 14, 14, 14, 14) + var preTime = records[records.length - 2].Time + $.PlotRecords(records, "K") + $.PlotLine("m_di", ret[0][ret[0].length - 2], preTime) + $.PlotLine("p_di", ret[1][ret[1].length - 2], preTime) + $.PlotLine("adx", ret[2][ret[2].length - 2], preTime) + $.PlotLine("adxr", ret[3][ret[3].length - 2], preTime) + + Sleep(1000) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/154050 + +> 更新时间 + +2019-07-03 13:56:18 diff --git "a/Deribit websocket \350\214\203\344\276\213.md" "b/Deribit websocket \350\214\203\344\276\213.md" new file mode 100644 index 00000000..146d6913 --- /dev/null +++ "b/Deribit websocket \350\214\203\344\276\213.md" @@ -0,0 +1,101 @@ + +> 策略名称 + +Deribit websocket 范例 + +> 策略作者 + +小小梦 + + + + + +> 源码 (javascript) + +``` javascript +var client = null +var deribitAcc = {} // 可以设置个全局对象保存 token + +function WS_GetAccount() { // 获取账户 某个币种 的资产信息 + var msg = { + "jsonrpc": "2.0", + "id": 2515, + "method": "private/get_account_summary", + "params": { + "currency": "ETH", + "extended": true + } + } + + client.write(JSON.stringify(msg)) + var ret = client.read() + Log(ret, "#FF0000") +} + +function WS_GetToken() { // 认证 ,并且获取 token + var msg = { + "jsonrpc": "2.0", + "id": 9929, + "method": "public/auth", + "params": { + "grant_type": "client_credentials", + "client_id": "XXXXXXX", // 申请 API KEY 时获取 + "client_secret": "XXXXXXXXXXXXXXXXXXXXXXXXXX" // 申请 API KEY 时获取 + } + } + while (1) { + client.write(JSON.stringify(msg)) + var ret = client.read() + try { + var jsonObj = JSON.parse(ret) + if (jsonObj) { + deribitAcc.accessToken = jsonObj.result.access_token + deribitAcc.refToken = jsonObj.result.refresh_token + break + } + } catch (e) { + Log("error:", e) + } + } + Log("更新 deribitAcc accessToken , refToken:", deribitAcc) +} + +function WS_Depth() { // 访问 get_order_book 公共 频道,获取 订单薄深度数据 + var msg = { + "jsonrpc": "2.0", + "id": 8772, + "method": "public/get_order_book", + "params": { + "instrument_name": "BTC-PERPETUAL", // 指定,获取 BTC 永续合约的深度数据 + "depth": 5 + } + } + + client.write(JSON.stringify(msg)) + var ret = client.read() + Log("depth : ", ret) +} + +function main() { + client = Dial("wss://www.deribit.com/ws/api/v2") + WS_GetToken() + + WS_GetAccount() + WS_Depth() + +} + +function onexit() { + Log("关闭 ws 连接") + client.close() +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/147765 + +> 更新时间 + +2019-05-15 18:37:40 diff --git "a/FCoin\346\235\240\346\235\206\344\272\244\346\230\223\346\250\241\346\235\277.md" "b/FCoin\346\235\240\346\235\206\344\272\244\346\230\223\346\250\241\346\235\277.md" new file mode 100644 index 00000000..90e1c2b7 --- /dev/null +++ "b/FCoin\346\235\240\346\235\206\344\272\244\346\230\223\346\250\241\346\235\277.md" @@ -0,0 +1,78 @@ + +> 策略名称 + +FCoin杠杆交易模板 + +> 策略作者 + +wmjbs + +> 策略描述 + +1.此模板仅支持Fcoin的杠杆账户 +2.目前仅有卖出功能,买入功能和杠杆账户资产获取功能 +3.希望有能力的朋友进行改进,加入撤单功能和获取未完成订单功能 + + + +> 源码 (javascript) + +``` javascript +/* +1.此模板仅支持Fcoin的杠杆账户 +2.目前仅有卖出功能、买入功能和杠杆账户资产获取功能 +3.希望有能力的朋友进行改进,加入撤单功能和获取未完成订单功能 +*/ + +$.fcoinSell = function(price, amount) { + var message = "&symbol=btcusdt" + "&side=sell" + "&type=limit" + "&price=" + price.toString() + "&amount=" + amount.toString() + "&exchange=main" + "&account_type=margin" + id = exchanges[0].IO("api", "POST", "/v2/orders", message) + return id; +} + +$.fcoinBuy = function(price, amount) { + var message = "&symbol=btcusdt" + "&side=buy" + "&type=limit" + "&price=" + price.toString() + "&amount=" + amount.toString() + "&exchange=main" + "&account_type=margin" + id = exchanges[0].IO("api", "POST", "/v2/orders", message) + return id; +} + +$.Get_Account = function() { + var account = null; + while (true) { + var Currency = "btcusdt"; + account = exchange.IO("api", "GET", "/v2/broker/leveraged_accounts/account", "account_type=" + Currency); + if (account.status == 'ok') { + break; + } + Sleep(1500) + } + return { + Info: null, + Balance: Math.abs(account.data.available_quote_currency_amount), + FrozenBalance: Math.abs(account.data.frozen_quote_currency_amount), + Stocks: Math.abs(account.data.available_base_currency_amount), + FrozenStocks: Math.abs(account.data.frozen_base_currency_amount) + } +} + +// 测试代码 +function main() { + + var buyorder = $.fcoinBuy(6000, 0.001); + var sellorder = $.fcoinSell(9000, 0.001); + + Log(buyorder); + Log(sellorder); + + Log($.Get_Account()); + Log($.Get_Account().Stocks); +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/151157 + +> 更新时间 + +2019-06-09 10:47:22 diff --git "a/Get cryptocurrency current and max supply|\350\216\267\345\217\226\345\270\201\347\247\215\344\276\233\345\272\224\351\207\217.md" "b/Get cryptocurrency current and max supply|\350\216\267\345\217\226\345\270\201\347\247\215\344\276\233\345\272\224\351\207\217.md" index 710434b7..d5eeec72 100644 --- "a/Get cryptocurrency current and max supply|\350\216\267\345\217\226\345\270\201\347\247\215\344\276\233\345\272\224\351\207\217.md" +++ "b/Get cryptocurrency current and max supply|\350\216\267\345\217\226\345\270\201\347\247\215\344\276\233\345\272\224\351\207\217.md" @@ -7,7 +7,9 @@ Get cryptocurrency current and max supply|获取币种供应量 botvsing +> 策略描述 +使用coinmarketcap提供的API接口获取币种供应量和流通量,可用于计算总市值 @@ -48,4 +50,4 @@ https://www.fmz.com/strategy/122370 > 更新时间 -2018-10-18 20:55:41 +2019-07-03 16:33:08 diff --git "a/MACD\347\224\273\345\233\276\350\214\203\344\276\213.md" "b/MACD\347\224\273\345\233\276\350\214\203\344\276\213.md" new file mode 100644 index 00000000..8114e50f --- /dev/null +++ "b/MACD\347\224\273\345\233\276\350\214\203\344\276\213.md" @@ -0,0 +1,106 @@ + +> 策略名称 + +MACD画图范例 + +> 策略作者 + +小小梦 + + + + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2019-05-13 00:00:00 +end: 2019-06-12 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}] +*/ + +var preTime = 0; +var ChartObj = null; +function main(){ + LogReset(1); + ChartObj = Chart(null); + ChartObj.reset(); + var records = null; + var MACD = null; + exchange.SetContractType("quarter"); + // Log(exchange.GetUSDCNY()); + // exchange.SetRate(exchange.GetUSDCNY()); + exchange.SetRate(1); + ChartObj = $.GetCfg(); + + // 处理 指标轴------------------------ + ChartObj.yAxis = [{ + title: {text: 'K线'},//标题 + style: {color: '#4572A7'},//样式 + opposite: false //生成右边Y轴 + }, + { + title:{text: "指标轴"}, + opposite: true, //生成右边Y轴 ceshi + } + ]; + // 初始化指标线 + while(!records || records.length < 30){ + records = _C(exchange.GetRecords); + LogStatus("records.length:", records.length); + Sleep(1000); + } + + $.PlotRecords(records, 'OK期货'); + $.PlotLine('dif', 0, records[records.length - 1].Time); + $.PlotLine('dea', 0, records[records.length - 1].Time); + var chart = $.PlotLine('macd', 0, records[records.length - 1].Time); + // 修改指标线 坐标轴Y轴 + for(var key in ChartObj.series){ + if(ChartObj.series[key].name == 'dif' || ChartObj.series[key].name == 'dea' || ChartObj.series[key].name == 'macd'){ + ChartObj.series[key].yAxis = 1; + } + } + chart.update(ChartObj); + chart.reset(); + + while(true){ + records = _C(exchange.GetRecords); + if(records.length > 50){ + $.PlotRecords(records, 'OK期货'); + MACD = TA.MACD(records); + var dif = MACD[0]; + var dea = MACD[1]; + var macd = MACD[2]; + if(preTime !== records[records.length - 1].Time){ + $.PlotLine('dif', dif[dif.length - 2], records[records.length - 2].Time); + $.PlotLine('dea', dea[dea.length - 2], records[records.length - 2].Time); + $.PlotLine('macd', macd[macd.length - 2], records[records.length - 2].Time); + + $.PlotLine('dif', dif[dif.length - 1], records[records.length - 1].Time); + $.PlotLine('dea', dea[dea.length - 1], records[records.length - 1].Time); + $.PlotLine('macd', macd[macd.length - 1], records[records.length - 1].Time); + + preTime = records[records.length - 1].Time; + }else{ + $.PlotLine('dif', dif[dif.length - 1], records[records.length - 1].Time); + $.PlotLine('dea', dea[dea.length - 1], records[records.length - 1].Time); + $.PlotLine('macd', macd[macd.length - 1], records[records.length - 1].Time); + } + } + LogStatus("records.length:", records.length, records[records.length - 1]); + // Log(records[records.length - 1]); + Sleep(1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/151972 + +> 更新时间 + +2019-06-12 20:16:58 diff --git "a/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.md" "b/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.md" index fc6d48bc..d59db524 100644 --- "a/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.md" +++ "b/My-1-\344\273\267\345\200\274\345\271\263\345\235\207\345\256\232\346\212\225\347\255\226\347\225\245.md" @@ -9,7 +9,7 @@ Lizza > 策略描述 -实盘:https://www.botvs.com/m/robot/26018 +实盘:https://www.fmz.com/m/robot/26018 这个策略适合长期看好比特币的脑残粉,使用价值平均策略来进行定投,可以有效的抵抗市场波动。(关于价值平均定投请度娘。) 基本的思路是先想好每个月想要投入多少钱(策略变量:MoneyEveryMonth),然后决定多久交易一次,交易的间隔不建议小于5分钟(策略参数:InvestInternal)。 diff --git a/OkEX Websocket Realtime v2.md b/OkEX Websocket Realtime v3.md similarity index 67% rename from OkEX Websocket Realtime v2.md rename to OkEX Websocket Realtime v3.md index ee5691e2..a2133bb6 100644 --- a/OkEX Websocket Realtime v2.md +++ b/OkEX Websocket Realtime v3.md @@ -1,7 +1,7 @@ > 策略名称 -OkEX Websocket Realtime v2 +OkEX Websocket Realtime v3 > 策略作者 @@ -10,6 +10,8 @@ FawkesPan > 策略描述 # OkEX WebSocket API Connecter (compress supported) +因为 `websocket-client` 新版的各种大脑降级设计 很多功能无法使用 +需要安装老版本websocket-client的包才能正常使用 `pip3 install websocket-client==0.46.0` @@ -20,9 +22,9 @@ FawkesPan # -*- coding: utf-8 -*- # encoding: utf-8 # -# Market Real-time Subscription +# Market Real-time Subscription v3 # -# Copyright 2018 FawkesPan +# Copyright 2019 FawkesPan # # Do What the Fuck You Want To Public License # @@ -50,11 +52,10 @@ pong = time.time() class WSSubscription: - def __init__(self,symbol='btc',contract_type='this_week',on_message=None): - self.__symbol = symbol.lower() - self.__contract_type = contract_type + def __init__(self, instrument_id='BTC-USD-190517', market='futures', on_message=None): + self.__iid = instrument_id + self.__market = market self.__Depth = {} - self.__Position = {} if on_message is not None: self.__callbackEnabled = True @@ -69,14 +70,21 @@ class WSSubscription: def GetDepth(self): return self.__Depth - def subscribe(self,ws): + def subscribe(self, ws): + + def operator(op, args): + message = { + 'op': op, + 'args': args + } + ws.send(json.dumps(message)) def run(*args): - ws.send("{'event':'addChannel','channel':'ok_sub_futureusd_%s_depth_%s_5'}" % (self.__symbol,self.__contract_type)) - ws.send("{'event':'addChannel','channel':'ok_sub_futureusd_%s_trade_%s'}" % (self.__symbol,self.__contract_type)) + operator('subscribe', ['%s/depth5:%s' % (self.__market, self.__iid)]) + operator('subscribe', ['%s/trade:%s' % (self.__market, self.__iid)]) while True: - ws.send("{'event':'ping'}") + ws.send("ping") time.sleep(30) threading.Thread(target=run).start() @@ -84,7 +92,7 @@ class WSSubscription: def sub(self): websocket.enableTrace(False) - URL = "wss://real.okex.com:10441/websocket?compress=true" + URL = "wss://real.okex.com:10442/ws/v3" ws = websocket.WebSocketApp(URL, on_message=self.incoming, on_error=self.error_handling, @@ -108,8 +116,7 @@ class WSSubscription: pong = time.time() if 'asks' in message and 'bids' in message: d = json.loads(message) - self.__Depth = d[0]['data'] - self.__Depth['asks'].reverse() + self.__Depth = d['data'][0] if self.__callbackEnabled: self.__callback(message) @@ -125,7 +132,7 @@ ext.OkEXWS = WSSubscription # 模块测试 def main(): - OkEX = ext.OkEXWS(symbol='btc',contract_type='this_week') + OkEX = ext.OkEXWS('BTC-USD-190517', 'futures') while (True): Log(OkEX.GetDepth()) time.sleep(1) @@ -133,8 +140,8 @@ def main(): > 策略出处 -https://www.fmz.com/strategy/91176 +https://www.fmz.com/strategy/143457 > 更新时间 -2019-04-08 23:47:33 +2019-05-18 00:17:12 diff --git "a/OkEX\345\220\210\347\272\246 \344\273\223\344\275\215\347\256\241\347\220\206\347\263\273\347\273\237.md" "b/OkEX\345\220\210\347\272\246 \344\273\223\344\275\215\347\256\241\347\220\206\347\263\273\347\273\237.md" new file mode 100644 index 00000000..629a017b --- /dev/null +++ "b/OkEX\345\220\210\347\272\246 \344\273\223\344\275\215\347\256\241\347\220\206\347\263\273\347\273\237.md" @@ -0,0 +1,328 @@ + +> 策略名称 + +OkEX合约 仓位管理系统 + +> 策略作者 + +FawkesPan + + + + + +> 源码 (python) + +``` python + +import time +import math +import threading +import decimal +from uuid import uuid4 as _uuid + +def genUUID(): + return str(_uuid()) + +class PositionManager: + + def __init__(self, exchange, symbol, contract, getDepth, tickSize=0.01): + self.okex = exchange + self.symbol = symbol + self.contract = contract + self.tickSize = tickSize + self.isFMZ = False + if 'Asks' in getDepth().keys(): + self.isFMZ = True + self.okexGetDepth = getDepth + self.orderLock = threading.Lock() + self.orderLocks = {} + self.orders = {} + self.cancels = [] + self.completeds = [] + self.init() + + def init(self): + self.okex.IO("currency", self.symbol.upper()) + self.okex.SetContractType(self.contract) + self.order_logs = { + 'buySent': 0, + 'buyCanceled': 0, + 'sellSent': 0, + 'sellCanceled': 0 + } + + def toNearest(self, num): + tickDec = decimal.Decimal(str(self.tickSize)) + return float((decimal.Decimal(round(num / self.tickSize, 0)) * tickDec)) + + def getDepth(self): + depth = self.okexGetDepth() + if self.isFMZ: + depth['asks'] = [[x['Price'], x['Amount']] for x in depth['Asks']] + depth['bids'] = [[x['Price'], x['Amount']] for x in depth['Bids']] + return depth + + def getOrderLogs(self): + return self.order_logs + + def getBestPrices(self): + bestPrices = {} + depth = self.getDepth() + ask, bid = depth['asks'][0][0], depth['bids'][0][0] + spread = ask - bid + if spread <= self.tickSize*2: + bestPrices['ask'] = ask + bestPrices['bid'] = bid + elif spread <= self.tickSize*6: + bestPrices['ask'] = ask-self.tickSize + bestPrices['bid'] = bid+self.tickSize + elif spread >= self.tickSize*20: + bestPrices['ask'] = ask-self.tickSize*5 + bestPrices['bid'] = bid+self.tickSize*5 + else: + midPrice = self.toNearest((ask+bid)/2) + bestPrices['ask'] = midPrice+self.tickSize*2 + bestPrices['bid'] = midPrice-self.tickSize*2 + return { + 'ask': self.toNearest(bestPrices['ask']), + 'bid': self.toNearest(bestPrices['bid']) + } + + def getPositions(self, noRetry=False, maxRetries=10): + if noRetry: + return self.okex.GetPosition() + attempts = 0 + while True: + time.sleep(0.4) + positions = self.okex.GetPosition() + attempts+=1 + if len(positions) != 0: + return positions + if attempts == maxRetries: + return False + + def havePosition(self, type=None, noRetry=True, maxRetries=10): + positions = self.getPositions(noRetry=True) + if not positions: + positions = [] + if type == None: + pass + elif type == 'buy': + key = 'buy_amount' + elif type == 'sell': + key = 'sell_amount' + for position in positions: + if type is not None: + if position['Info'][key] != 0: + return positions + else: + return positions + if noRetry: + return False + attempts = 0 + while True: + time.sleep(0.4) + positions = self.getPositions(noRetry=True) + if not positions: + positions = [] + attempts+=1 + for position in positions: + if type is not None: + if position['Info'][key] != 0: + return positions + else: + return positions + if attempts == maxRetries: + return False + + def orderDone(self, orderID): + orders = self.okex.GetOrders() + for order in orders: + if order['Info']['order_id'] == orderID: + return order['Info']['price'], order['Info']['amount']-order['Info']['deal_amount'] + return True + + def getOrder(self, uuid): + try: + self.orders[uuid] + except KeyError: + Log('不存在订单 %s' % uuid) + return 0 + return self.orders[uuid] + + def getOrderInfo(self, uuid): + return self.okex.GetOrder(self.getOrder(uuid)) + + def awaitOrder(self, uuid, timeout=None): + start = time.time() + try: + self.orderLocks[uuid] + except KeyError: + return False + while True: + if self.orderLocks[uuid].acquire(False): + del self.orderLocks[uuid] + return self.getOrder(uuid) + else: + if timeout is not None: + if time.time()-timeout>start: + Log('等待订单成交已超时.') + return + time.sleep(0.001) + + def isDone(self, uuid): + if uuid in self.completeds: + return True + return False + + def cancel(self, uuid): + self.cancels.append(uuid) + _cancel = self.okex.CancelOrder(self.getOrder(uuid)) + self.orderLocks[uuid].acquire() + self.orderLocks[uuid].release() + if _cancel: + Log(uuid, str(self.getOrder(uuid)), '已取消.') + return True + Log(uuid, str(self.getOrder(uuid)), '取消失败.', str(self.okex.GetRawJSON())) + return False + + def trade(self, type, price, amount, matchPrice=False, noRetry=False, uuid=None): + if type == 'buy' or type == 'closesell': + _trader = self.okex.Buy + _side = 'buy' + __side = 'bid' + else: + _trader = self.okex.Sell + _side = 'sell' + __side = 'ask' + def trader(price, amount): + self.orderLock.acquire() + self.okex.SetDirection(type) + order = _trader(price, amount) + self.orders[uuid] = order + self.orderLock.release() + self.order_logs['%sSent' % _side]+=1 + return order + def isBestPrice(currentPrice, depth): + ret = False + if _side == 'buy': + if currentPrice > depth['bids'][1][0]: + ret = True + else: + if currentPrice < depth['asks'][1][0]: + ret = True + return ret + if price is None: + price = self.getBestPrices()[__side] + if matchPrice: + price = -1 + order = trader(price, amount) + if noRetry: + self.completeds.append(uuid) + self.orderLocks[uuid].release() + return + if order == False: + if 20016 in str(self.okex.GetRawJSON()): + order = trader(price, amount) + if order == False: + Log('%s 返回值: %s', (uuid, str(self.okex.GetRawJSON()))) + self.completeds.append(uuid) + self.orderLocks[uuid].release() + return + time.sleep(1) + while True: + if uuid in self.cancels: + Log('%s 已停止下单尝试.' % uuid) + self.completeds.append(uuid) + self.orderLocks[uuid].release() + return + time.sleep(1) + depth = self.getDepth() + isDone = self.orderDone(order) + if isDone == True: + self.completeds.append(uuid) + self.orderLocks[uuid].release() + return + if isBestPrice(isDone[0], depth): + continue + if not self.okex.CancelOrder(order): + time.sleep(1) + if self.orderDone(order): + self.completeds.append(uuid) + self.orderLocks[uuid].release() + return + self.order_logs['%sCanceled' % _side]+=1 + time.sleep(1) + if price != -1: + price = self.getBestPrices()[__side] + if uuid in self.cancels: + Log('%s 已停止下单尝试.' % uuid) + self.completeds.append(uuid) + self.orderLocks[uuid].release() + return + order = trader(price, isDone[1]) + + def openLong(self, amount, price=None, matchPrice=False, noRetry=False): + uuid = genUUID() + Log('%s 买入做多 是否使用对手价 %s 阻塞直至成功 %s' % (uuid, str(matchPrice), str(not noRetry))) + threading.Thread(target=self.trade, kwargs=dict({'type': 'buy', + 'price': price, + 'amount': amount, + 'matchPrice': matchPrice, + 'noRetry': noRetry, + 'uuid': uuid}), daemon=True).start() + self.orderLocks[uuid] = threading.Lock() + self.orderLocks[uuid].acquire() + return uuid + + def openShort(self, amount, price=None, matchPrice=False, noRetry=False): + uuid = genUUID() + Log('%s 卖出做空 是否使用对手价 %s 阻塞直至成功 %s' % (uuid, str(matchPrice), str(not noRetry))) + threading.Thread(target=self.trade, kwargs=dict({'type': 'sell', + 'price': price, + 'amount': amount, + 'matchPrice': matchPrice, + 'noRetry': noRetry, + 'uuid': uuid}), daemon=True).start() + self.orderLocks[uuid] = threading.Lock() + self.orderLocks[uuid].acquire() + return uuid + + def coverLong(self, amount, price=None, matchPrice=False, noRetry=False): + uuid = genUUID() + Log('%s 卖出平多 是否使用对手价 %s 阻塞直至成功 %s' % (uuid, str(matchPrice), str(not noRetry))) + threading.Thread(target=self.trade, kwargs=dict({'type': 'closebuy', + 'price': price, + 'amount': amount, + 'matchPrice': matchPrice, + 'noRetry': noRetry, + 'uuid': uuid}), daemon=True).start() + self.orderLocks[uuid] = threading.Lock() + self.orderLocks[uuid].acquire() + return uuid + + def coverShort(self, amount, price=None, matchPrice=False, noRetry=False): + uuid = genUUID() + Log('%s 买入平空 是否使用对手价 %s 阻塞直至成功 %s' % (uuid, str(matchPrice), str(not noRetry))) + threading.Thread(target=self.trade, kwargs=dict({'type': 'closesell', + 'price': price, + 'amount': amount, + 'matchPrice': matchPrice, + 'noRetry': noRetry, + 'uuid': uuid}), daemon=True).start() + self.orderLocks[uuid] = threading.Lock() + self.orderLocks[uuid].acquire() + return uuid + +ext.okexPositionManager = PositionManager + +``` + +> 策略出处 + +https://www.fmz.com/strategy/121976 + +> 更新时间 + +2019-05-16 22:07:51 diff --git "a/Push Binance deal order to WeChat|\345\256\236\346\227\266\346\216\250\351\200\201\345\270\201\345\256\211\346\210\220\344\272\244\345\210\260\345\276\256\344\277\241(wss\345\215\217\350\256\256\347\273\203\344\271\240\357\274\211.md" "b/Push Binance deal order to WeChat|\345\256\236\346\227\266\346\216\250\351\200\201\345\270\201\345\256\211\346\210\220\344\272\244\345\210\260\345\276\256\344\277\241(wss\345\215\217\350\256\256\347\273\203\344\271\240\357\274\211.md" index d4967f31..c37f3e22 100644 --- "a/Push Binance deal order to WeChat|\345\256\236\346\227\266\346\216\250\351\200\201\345\270\201\345\256\211\346\210\220\344\272\244\345\210\260\345\276\256\344\277\241(wss\345\215\217\350\256\256\347\273\203\344\271\240\357\274\211.md" +++ "b/Push Binance deal order to WeChat|\345\256\236\346\227\266\346\216\250\351\200\201\345\270\201\345\256\211\346\210\220\344\272\244\345\210\260\345\276\256\344\277\241(wss\345\215\217\350\256\256\347\273\203\344\271\240\357\274\211.md" @@ -7,7 +7,10 @@ Push Binance deal order to WeChat|实时推送币安成交到微信(wss协议练 botvsing +> 策略描述 +通过websocket协议,将币安成交信息推送到微信,可以作为wss协议的练习。 +具体原理是30分钟更新一次listenKey,然后订阅账户订阅的datastream。 > 策略参数 @@ -50,4 +53,4 @@ https://www.fmz.com/strategy/122649 > 更新时间 -2018-10-20 15:06:05 +2019-07-03 16:27:05 diff --git "a/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.md" "b/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.md" index 8fa5b453..aa31abd1 100644 --- "a/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.md" +++ "b/Python \347\262\276\347\256\200\345\244\232\345\223\201\347\247\215 MACD \350\266\213\345\212\277\347\255\226\347\225\245.md" @@ -13,7 +13,7 @@ Zero > python版CTP商品期货交易类库(支持2/3 测试版) -https://www.botvs.com/strategy/24288 +https://www.fmz.com/strategy/24288 > 策略参数 diff --git a/README.md b/README.md index 43b5395e..d1cbd3cd 100644 --- a/README.md +++ b/README.md @@ -4,22 +4,60 @@ > 开源策略 - - [设定价格微信推送(教学)| Push the price information to telegram](https://www.fmz.com/strategy/125482) - - [OkEX Websocket Realtime v2](https://www.fmz.com/strategy/91176) + - [交易所最小数量和精度](https://www.fmz.com/strategy/108887) + - [数字货币自适应均线交易系统以及KAMA算法解析——基于发明者量化交易软件](https://www.fmz.com/strategy/155663) + - [运用阿隆(Aroon)指标在数字货币中量化交易,附带My语言策略源码](https://www.fmz.com/strategy/155582) + - [阿隆(Aroon)技术指标在商品期货中的应用](https://www.fmz.com/strategy/154547) + - [山寨币指数(2018.02.22基点1000)](https://www.fmz.com/strategy/73461) + - [指数平衡策略|Index Balance Bot](https://www.fmz.com/strategy/116012) + - [简单固定价格止损机器人|Stop Loss Below Fixed Price](https://www.fmz.com/strategy/121081) + - [冰山委托买入简单版|Simple Iceberg order to buy](https://www.fmz.com/strategy/121522) + - [冰山委托卖出简单版|Simple Iceberg order to sell](https://www.fmz.com/strategy/121524) + - [币安取消所有交易对未完成订单(IO扩展示范)|Cancel ALL Binance Orders](https://www.fmz.com/strategy/121549) + - [Binance buy and sell statistics|币安买卖统计](https://www.fmz.com/strategy/121917) + - [Get cryptocurrency current and max supply|获取币种供应量](https://www.fmz.com/strategy/122370) + - [Push Binance deal order to WeChat|实时推送币安成交到微信(wss协议练习)](https://www.fmz.com/strategy/122649) + - [设定比特币价格并微信推送(教学)| Push the price information to telegram](https://www.fmz.com/strategy/125482) + - [爬取币安公告自动出售将要下架币|crawl Binance announcements and sell Delist coin](https://www.fmz.com/strategy/137450) + - [多图表例子(数据可下载为csv等表格)|Multiple charts example](https://www.fmz.com/strategy/136056) + - [DMI 测试范例](https://www.fmz.com/strategy/154050) + - [动态平衡策略 python 版](https://www.fmz.com/strategy/152830) - [麦语言网格策略](https://www.fmz.com/strategy/142701) + - [annotation属性](https://www.fmz.com/strategy/149661) + - [日志|Logger](https://www.fmz.com/strategy/151754) + - [MACD画图范例](https://www.fmz.com/strategy/151972) + - [三角套利-基础版](https://www.fmz.com/strategy/151145) + - [期货反手加倍算法](https://www.fmz.com/strategy/3648) + - [FCoin杠杆交易模板](https://www.fmz.com/strategy/151157) + - [每日市价定投](https://www.fmz.com/strategy/151259) + - [2014年的简易比特币高频策略机器人](https://www.fmz.com/strategy/1088) + - [三角套利策略体验版](https://www.fmz.com/strategy/149489) + - [火币期货币币账户间资金划转范例](https://www.fmz.com/strategy/148532) + - [OkEX Websocket Realtime v3](https://www.fmz.com/strategy/143457) + - [OkEX合约 仓位管理系统](https://www.fmz.com/strategy/121976) + - [Telegram 发信接口 V2.0.0 Python](https://www.fmz.com/strategy/116201) + - [币安 提币范例代码](https://www.fmz.com/strategy/147856) + - [Deribit websocket 范例](https://www.fmz.com/strategy/147765) + - [python 状态栏表格 显示按钮范例](https://www.fmz.com/strategy/147155) + - [boll+maboll](https://www.fmz.com/strategy/146391) + - [深度做市](https://www.fmz.com/strategy/146238) + - [单边网格 (Copy)](https://www.fmz.com/strategy/144679) + - [websocket 版OKEX跨期对冲策略(教学)](https://www.fmz.com/strategy/144378) + - [rest 版OKEX跨期对冲策略(教学)](https://www.fmz.com/strategy/144406) + - [60行三角对冲策略(教学)](https://www.fmz.com/strategy/144257) + - [python版 画线类库 (兼容2/3) | python PlotLine Template](https://www.fmz.com/strategy/39066) + - [简单均线策略|Moving Average Bot 30 lines](https://www.fmz.com/strategy/103070) - [MACD Cpp Demo](https://www.fmz.com/strategy/142259) - [KDJ Cpp Demo](https://www.fmz.com/strategy/142260) - [恒温器 Thermostat 择时策略研究](https://www.fmz.com/strategy/127033) - [API 测试新手入门](https://www.fmz.com/strategy/4) - [基于随机森林的趋势策略](https://www.fmz.com/strategy/140199) - [RSI统计套利策略-熊市盈利利器 (Copy)](https://www.fmz.com/strategy/138171) - - [爬取币安公告自动出售将要下架币|crawl Binance announcements and sell Delist coin](https://www.fmz.com/strategy/137450) - [多交易所集合行情/下单 策略 范例](https://www.fmz.com/strategy/125569) - [海龟汤策略](https://www.fmz.com/strategy/139249) - [策略框架](https://www.fmz.com/strategy/20663) - [商品期货跟单系统](https://www.fmz.com/strategy/79351) - [交互模板](https://www.fmz.com/strategy/137403) - - [多图表例子(数据可下载为csv等表格)](https://www.fmz.com/strategy/136056) - [M Language “Turtle Trading strategy” implementations(V 1.0)](https://www.fmz.com/strategy/132298) - [cancelorder加强版](https://www.fmz.com/strategy/134368) - [RSI统计套利策略-熊市盈利利器](https://www.fmz.com/strategy/131971) @@ -58,7 +96,6 @@ - [双均线DDI策略|Double Average Lines -DDI Strategy](https://www.fmz.com/strategy/128133) - [高低点突破成交量指数加权策略|Break High and Low - Volume Index Weighting Strategy](https://www.fmz.com/strategy/128125) - [标准差价格通道策略|Standard deviation price channel strategy](https://www.fmz.com/strategy/128121) - - [CTP 期货](https://www.fmz.com/strategy/130234) - [你不知道的MACD+MA指标组合策略|MACD+MA Indicator Combination Strategy](https://www.fmz.com/strategy/127101) - [商品期货交易类库(旧版)](https://www.fmz.com/strategy/127341) - [BitMEX 高级API功能 V.1.1.0 (期货:批量下单,编辑订单,冰山订单,一键撤单,定时撤单) Python2/3](https://www.fmz.com/strategy/114148) @@ -66,17 +103,8 @@ - [使用画线类库画K线以及均线图表范例](https://www.fmz.com/strategy/125770) - [MA5](https://www.fmz.com/strategy/125474) - [移植 OKCoin 韭菜收割机 注释](https://www.fmz.com/strategy/124178) - - [Binance buy and sell statistics|币安买卖统计](https://www.fmz.com/strategy/121917) - - [Push Binance deal order to WeChat|实时推送币安成交到微信(wss协议练习)](https://www.fmz.com/strategy/122649) - - [Get cryptocurrency current and max supply|获取币种供应量](https://www.fmz.com/strategy/122370) - [指数均衡策略 (教学)](https://www.fmz.com/strategy/120581) - - [指数平衡策略|Index Balance Bot](https://www.fmz.com/strategy/116012) - - [简单均线策略|Moving Average Bot 30 lines](https://www.fmz.com/strategy/103070) - - [币安取消所有交易对未完成订单(IO扩展示范)|Cancel ALL Binance Orders](https://www.fmz.com/strategy/121549) - - [冰山委托卖出简单版|Simple Iceberg order to sell](https://www.fmz.com/strategy/121524) - - [冰山委托买入简单版|Simple Iceberg order to buy](https://www.fmz.com/strategy/121522) - [简单预定买入后卖出机器人|Buy then Sell (ping-pong strategy)](https://www.fmz.com/strategy/121228) - - [简单固定价格止损机器人|Stop Loss Below Fixed Price](https://www.fmz.com/strategy/121081) - [经典均线策略](https://www.fmz.com/strategy/12348) - [闪崩机器人 (教学)](https://www.fmz.com/strategy/118939) - [模拟测试kdj](https://www.fmz.com/strategy/119057) @@ -91,7 +119,6 @@ - [动态平衡alpha](https://www.fmz.com/strategy/115321) - [CoinPark交易所通用协议 6.27 16:00 更新 关闭了SSL验证](https://www.fmz.com/strategy/101399) - [30行赌徒策略](https://www.fmz.com/strategy/113796) - - [交易所最小数量和精度](https://www.fmz.com/strategy/108887) - [Shannon's Demon](https://www.fmz.com/strategy/64455) - [BitMEX 高级API功能 (期货:批量下单,一键撤单) JavaScript](https://www.fmz.com/strategy/105056) - [动态平衡 做市策略 (小高)](https://www.fmz.com/strategy/114044) @@ -108,14 +135,11 @@ - [新手上路CoinEx交易 (LTC_USDT)](https://www.fmz.com/strategy/103464) - [画线类库|Plot library](https://www.fmz.com/strategy/27293) - [Iceberg Buy Order](https://www.fmz.com/strategy/103319) - - [山寨币指数(2018.02.22基点1000)](https://www.fmz.com/strategy/73461) - [Dual Thrust OKEX Feature](https://www.fmz.com/strategy/103247) - [转换任意K线周期管理模板(最近更新20180627)](https://www.fmz.com/strategy/41163) - [检查https://quant.la/Argus/是否正常](https://www.fmz.com/strategy/100344) - - [2014年的简易短线机器人](https://www.fmz.com/strategy/1088) - [fcoin挖矿演示](https://www.fmz.com/strategy/97791) - [币安出售所有山寨币](https://www.fmz.com/strategy/97629) - - [RSI 双均线策略](https://www.fmz.com/strategy/46605) - [商品期货 - 形态策略(增强型锤子)](https://www.fmz.com/strategy/97130) - [追涨杀跌](https://www.fmz.com/strategy/96634) - [Python 机器学习之 SVM 预测买卖](https://www.fmz.com/strategy/21370) @@ -168,7 +192,6 @@ - [测试 默认 参数组功能](https://www.fmz.com/strategy/40155) - [全球10大交易系统之 Aberration 多品种商品期货交易系统](https://www.fmz.com/strategy/25943) - [Dual Thrust 商品期货](https://www.fmz.com/strategy/13011) - - [python版 画线类库 (兼容2/3)](https://www.fmz.com/strategy/39066) - [BotVS 商品期货 量化 测试入门 策略](https://www.fmz.com/strategy/59120) - [如何找出一定Bar数量的 K线前期高点、低点 及 Demo 程序](https://www.fmz.com/strategy/58179) - [python版现货数字货币交易类库](https://www.fmz.com/strategy/21104) @@ -189,7 +212,6 @@ - [KingKeltner趋势策略_低频](https://www.fmz.com/strategy/42283) - [buy-hold 买入持有](https://www.fmz.com/strategy/41786) - [知乎专栏 实例文章策略](https://www.fmz.com/strategy/39586) - - [知乎专栏 实例文章策略](https://www.fmz.com/strategy/40266) - [BitMEX 简单测试](https://www.fmz.com/strategy/40289) - [商品期货查看账户详细信息](https://www.fmz.com/strategy/37793) - [商品期货结算单平仓盈亏历史查询](https://www.fmz.com/strategy/38083) @@ -241,7 +263,6 @@ - [多平台账户统计](https://www.fmz.com/strategy/7827) - [阶梯下单 - 可设置触发价格](https://www.fmz.com/strategy/639) - [统计收益 (复制)](https://www.fmz.com/strategy/4489) - - [796期货反手加倍算法](https://www.fmz.com/strategy/3648) - [多线程获取多个交易的深度信息](https://www.fmz.com/strategy/3651) - [账户余额变动邮箱提醒, 支持添加多个交易所](https://www.fmz.com/strategy/2006) - [多线程获取多个交易的账户信息](https://www.fmz.com/strategy/3297) diff --git "a/RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.md" "b/RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.md" deleted file mode 100644 index 1402d547..00000000 --- "a/RSI \345\217\214\345\235\207\347\272\277\347\255\226\347\225\245.md" +++ /dev/null @@ -1,149 +0,0 @@ - -> 策略名称 - -RSI 双均线策略 - -> 策略作者 - -yilidalei - - - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|RSI_Period|14|RSI周期| -|MA_fast_Period|10|快线周期| -|MA_slow_Period|24|慢线周期| -|SuperSellValue|20|超卖阈值| -|SuperBuyValue|80|超买阈值| - - - - -|按钮|默认值|描述| -|----|----|----| -|btn1|__button__|test| -|btn2|__button__|test2| - - -> 源码 (javascript) - -``` javascript -// 以下是测试代码 -/*- 状态 在使用 模板时需要在 主策略内声明 -var TASK_IDLE = 0; -var TASK_OPEN_LONG = 1; -var TASK_OPEN_SHORT = 2; -var TASK_ADD = 3; -var TASK_ST = 4; -var TASK_COVER = 5; -*/ - -// 临时参数 -/* -var RSI_Period = 14; -var MA_fast_Period = 10; -var MA_slow_Period = 200; -var SuperSellValue = 20; -var SuperBuyValue = 80; -*/ - -// 全局变量 -var currency0 = exchanges[0].GetCurrency(); -var ChartObj = null; -var TASK_IDLE = 0; -var TASK_OPEN_LONG = 1; -var TASK_OPEN_SHORT = 2; -var TASK_ADD = 3; -var TASK_ST = 4; -var TASK_COVER = 5; - -function onTick1() { - // 获取K线数据 - var nowTime = new Date().getTime(); - var records = _C(exchanges[0].GetRecords); - if(records.length < Math.abs(RSI_Period, MA_slow_Period, MA_fast_Period)){ - return $.TaskCmd(TASK_IDLE); - } - - var rsi = TA.RSI(records, RSI_Period); - var ma_fast = TA.MA(records, MA_fast_Period); - var ma_slow = TA.MA(records, MA_slow_Period); - - // $.AddData = function(index, dataKey, dataValue) - - // 画图表 - $.PlotRecords(records, currency0); - $.PlotLine('ma_fast' + MA_fast_Period, ma_fast[ma_fast.length - 1], records[records.length - 1].Time); - $.PlotLine('ma_slow' + MA_slow_Period, ma_slow[ma_slow.length - 1], records[records.length - 1].Time); - $.PlotLine('rsi' + RSI_Period, rsi[rsi.length - 1], records[records.length - 1].Time); - - if (rsi[rsi.length - 2] > SuperBuyValue) { - // 标记 - $.PlotFlag(nowTime, 'C', 'CL', 'circlepin', 'blue'); - return $.TaskCmd(TASK_COVER); - }else if(rsi[rsi.length - 2] < SuperSellValue && records[records.length - 1].Close > ma_slow[ma_slow.length - 1] && records[records.length - 1].Close < ma_fast[ma_fast.length - 1]){ - // 标记 - $.PlotFlag(nowTime, 'L', 'L', 'flag', 'red'); - return $.TaskCmd(TASK_OPEN_LONG, 0.5); - } - - return $.TaskCmd(TASK_IDLE); -} - -function main() { - LogReset(1); - ChartObj = Chart(null); - ChartObj.reset(); - ChartObj = $.GetCfg(); - // 处理 指标轴------------------------ - ChartObj.yAxis = [{ - title: {text: 'K线'},//标题 - style: {color: '#4572A7'},//样式 - opposite: false //生成右边Y轴 - }, - { - title:{text: "指标轴"}, - opposite: true, //生成右边Y轴 ceshi - } - ]; - // 初始化指标线 - var records = null; - while(!records || records.length < 30){ - records = _C(exchange.GetRecords); - LogStatus("records.length:", records.length); - Sleep(1000); - } - - $.PlotRecords(records, currency0); - $.PlotLine('ma_fast' + MA_fast_Period, 0, records[records.length - 1].Time); - $.PlotLine('ma_slow' + MA_slow_Period, 0, records[records.length - 1].Time); - var chart = $.PlotLine('rsi' + RSI_Period, 0, records[records.length - 1].Time); - // $.PlotFlag(new Date().getTime(), '开始', 'begin', 'circlepin', 'green'); - // $.PlotFlag(new Date().getTime(), 'CoverLong', 'CL', 'circlepin', 'blue'); - // $.PlotFlag(new Date().getTime(), 'Long', 'L', 'flag', 'red'); - // 修改指标线 坐标轴Y轴 - for(var key in ChartObj.series){ - if(ChartObj.series[key].name == 'rsi' + RSI_Period){ - ChartObj.series[key].yAxis = 1; - } - } - chart.update(ChartObj); - chart.reset(); - - $.Relation_Exchange_onTick(exchanges[0], onTick1); - $.Trend(); // 不用传参数。 -} -``` - -> 策略出处 - -https://www.fmz.com/strategy/46605 - -> 更新时间 - -2018-06-09 17:45:28 diff --git "a/Telegram \345\217\221\344\277\241\346\216\245\345\217\243 V2.0.0 Python.md" "b/Telegram \345\217\221\344\277\241\346\216\245\345\217\243 V2.0.0 Python.md" new file mode 100644 index 00000000..cdb8dd6f --- /dev/null +++ "b/Telegram \345\217\221\344\277\241\346\216\245\345\217\243 V2.0.0 Python.md" @@ -0,0 +1,116 @@ + +> 策略名称 + +Telegram 发信接口 V2.0.0 Python + +> 策略作者 + +FawkesPan + +> 策略描述 + +# Telegram API接口 (FMZ.com) + +##### 这个库目前只能Telegram发信 后续会增加更多功能。 + +### 初始化 +``` +# key 为 Bot key +## 获取 Bot key 可以参考 https://www.ccino.org/create-a-telegram-bot.html +# chat_id 为收信用户Telegram ID +## Telegram ID 可以通过 @dwx_aibot 机器人获取, 连接至此机器人后发送 /getid 即可获得 ChatID +Telegram = ext.Telegram(key=string, chat_id=integer) # 创建一个新的接口对象 +``` +### 发信 +``` +# chat_id 为可选项 默认会使用初始化时设置的ChatID +# message 即为信息内容 +Telegram.Send(message=string, chat_id=integer) +``` +### 注意事项 +在能够给自己发信息之前,你需要先在Telegram中给自己的机器人发送一条 /start 信息,不然机器人是没法给你发信的。 +### 与我联系 +邮箱 i@fawkex.me +电报 [FawkesPan](https://telegram.me/FawkesPan) + +接受策略定制 + +### 关于这个库 +[Telegram API文档](https://core.telegram.org/bots/api) + +[使用 WTFPL – Do What the Fuck You Want to Public License](http://www.wtfpl.net/) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|DEBUG|0|DEBUG模式: 0|1| +|KEY||Telegram 机器人 Key| +|CHATID|false|Telegram 会话 ID| + + +> 源码 (python) + +``` python +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# encoding: utf-8 +# +# Telegram Interface for FMZ.com +# +# Copyright 2018 FawkesPan +# Contact : i@fawkex.me / Telegram@FawkesPan +# +# Do What the Fuck You Want To Public License +# + +try: + import requests +except: + print('Requests not installed. Try: pip install requests') + Log('Requests not installed. Try: pip install requests') + + raise Exception('Requests not installed. Try: pip install requests') + +class Telegram: + def __init__(self): + self.key = KEY + self.chat_id = CHATID + self.url = 'https://api.telegram.org/bot%s' % self.key + + def Send(self, message='', chat_id=None): + if chat_id is None: + chat_id = self.chat_id + PARAM = {} + PARAM['chat_id'] = chat_id + PARAM['text'] = message + PARAM['parse_mode'] = 'markdown' + URL = self.url + '/sendMessage' + try: + res = requests.post(URL, data = PARAM) + return True + except IOError as e: + print(e) + return False + + +ext.Telegram = Telegram + +# 模块功能测试 +def main(): + if DEBUG == 1: + msger = ext.Telegram(KEY, CHATID) + msger.Send("Hello World!") + + return True +``` + +> 策略出处 + +https://www.fmz.com/strategy/116201 + +> 更新时间 + +2019-05-16 20:06:03 diff --git "a/annotation\345\261\236\346\200\247.md" "b/annotation\345\261\236\346\200\247.md" new file mode 100644 index 00000000..41f7c83c --- /dev/null +++ "b/annotation\345\261\236\346\200\247.md" @@ -0,0 +1,249 @@ + +> 策略名称 + +annotation属性 + +> 策略作者 + +量化新人 + +> 策略描述 + +BotVS支持策略同时展现多个图表, 这是一个简单的例子. 如果不能正常展示, 请清空浏览器缓存后刷新 + + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2019-01-22 00:00:00 +end: 2019-01-23 00:00:00 +period: 30m +exchanges: [{"eid":"OKCoin_EN","currency":"BTC_USD"}] +*/ +// function main() { +// var cfgA = { +// extension: { +// layout: 'single', // 不参于分组,单独显示, 默认为分组 'group' +// height: 300, // 指定高度 +// }, +// title: { +// text: '盘口图表' +// }, +// xAxis: { +// type: 'datetime' +// }, +// series: [{ +// name: '买一', +// data: [], +// }, { +// name: '卖一', +// data: [], +// }] +// } +// var cfgB = { +// title: { +// text: '差价图' +// }, +// xAxis: { +// type: 'datetime' +// }, +// series: [{ +// name: '差价', +// type: 'column', +// data: [], +// }], +// annotations: [{ +// shapes: [{ +// point: '0', +// type: 'circle', +// r: 10 +// }, { +// point: '3', +// type: 'rect', +// width: 20, +// height: 20, +// x: -10, +// y: -25 +// }], +// labels: [{ +// point: { +// x: 6, +// y: 195, +// xAxis: 0, +// yAxis: 0 +// } +// }] +// }] +// } + +// var cfgC = { +// __isStock: false, +// title: { +// text: '饼图' +// }, +// series: [{ +// type: 'pie', +// name: 'one', +// data: [ +// ["A", 25], +// ["B", 25], +// ["C", 25], +// ["D", 25], +// ] // 指定初始数据后不需要用add函数更新, 直接更改图表配置就可以更新序列. +// }] +// }; +// var cfgD = { +// extension: { +// layout: 'single', +// col: 8, // 指定宽度占的单元值, 总值 为12 +// height: '300px', +// }, +// title: { +// text: '盘口图表' +// }, +// xAxis: { +// type: 'datetime' +// }, +// series: [{ +// name: '买一', +// data: [], +// }, { +// name: '卖一', +// data: [], +// }] +// } +// var cfgE = { +// __isStock: false, +// extension: { +// layout: 'single', +// col: 4, +// height: '300px', +// }, +// title: { +// text: '饼图2' +// }, +// series: [{ +// type: 'pie', +// name: 'one', +// data: [ +// ["A", 25], +// ["B", 25], +// ["C", 25], +// ["D", 25], +// ] +// }] +// }; + +// var chart = Chart([cfgA, cfgB, cfgC, cfgD, cfgE]); +// chart.reset() +// // 为饼图清加一个数点,add只能更新通过add方式添加的数据点, 内置的数据点无法后期更新 +// chart.add(3, { +// name: "ZZ", +// y: 25 +// }); +// while (true) { +// Sleep(1000) +// var ticker = exchange.GetTicker() +// if (!ticker) { +// continue; +// } +// var diff = ticker.Sell - ticker.Buy +// cfgA.subtitle = { +// text: '买一 ' + ticker.Buy + ', 卖一 ' + ticker.Sell, +// }; +// cfgB.subtitle = { +// text: '价差 ' + diff, +// }; + +// chart.add([0, [ ticker.Buy]]); +// chart.add([1, [ ticker.Sell]]); +// // 相当于更新第二个图表的第一个数据序列 +// chart.add([2, [new Date().getTime(), diff]]); +// chart.add(4, [new Date().getTime(), ticker.Buy]); +// chart.add(5, [new Date().getTime(), ticker.Buy]); +// cfgC.series[0].data[0][1] = 789 +// cfgE.series[0].data[0][1] = 789 +// // update实际上等于重置了图表的配置 +// chart.update([cfgA, cfgB, cfgC, cfgD, cfgE]); +// } +// } +var cfgA = { + extension: { + layout: 'single', // 不参于分组,单独显示, 默认为分组 'group' + height: 300, // 指定高度 + col: 8, // 指定宽度占的单元值, 总值 为12 + }, + title: { + text: 'stock' + }, + + series: [ // 数据系列,该属性保存的是 各个 数据系列(线, K线图, 标签等..) + { + type: 'candlestick', + name: "line1", + data: [] + }, // 索引为0, data 数组内存放的是该索引系列的 数据 ] + { + type: 'flags', + data: [{ + x: 1548170700000, + y: 3575.8, + title: '1卖', + text: 'Shape: "squarepin"' + }], + onSeries: 'dataseries', + shape: 'squarepin', + width: 16 + }, + ], + annotations: [{ + shapes: [{ + fill: 'none', + stroke: 'red', + strokeWidth: 3, + type: 'path', + points: [{ + x: 1548167400000, + y: 3562.59, + + }, { + x: 1548171000000, + y: 3561.34, + + }], + }] + }] + +} + +function main() { + var ObjChart = Chart(cfgA); // 调用 Chart 函数,初始化 图表。 + ObjChart.reset(); // 清空 + var recordsArr = [] + while (true) { + var nowTime = new Date().getTime(); // 获取本次轮询的 时间戳, 即一个 毫秒 的时间戳。用来确定写入到图表的X轴的位置。 + // var ticker = _C(exchange.GetTicker); // 获取行情数据 + var records = _C(exchange.GetRecords, PERIOD_M30) + var lastKline = records[records.length - 1] + Log("ticker:", lastKline) + + + var newItem = [lastKline.Time, lastKline.Open, lastKline.High, lastKline.Low, lastKline.Close] + recordsArr.push(newItem) + + cfgA.series[0].data = recordsArr + ObjChart.update(cfgA); + Sleep(2000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/149661 + +> 更新时间 + +2019-06-21 14:19:14 diff --git a/boll+maboll.md b/boll+maboll.md new file mode 100644 index 00000000..96298f2f --- /dev/null +++ b/boll+maboll.md @@ -0,0 +1,106 @@ + +> 策略名称 + +boll+maboll + +> 策略作者 + +3piggy + +> 策略描述 + +布林带突破与回撤结合策略 +开仓信号:布林带上轨均线金叉,布林带宽放大,中轨向上,开多。反之开空 +平仓信号:布林带收窄,上轨均线死叉 +逆向信号:布林带回撤 + +信号还在过滤中 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|ma|13|ma周期| +|bo|21|bo周期| +|gap|0.004|gap| +|period|true|period| +|ma2|7|ma2周期| + + +> 源码 (python) + +``` python +import numpy as np +import talib +import time +if period == 1: + per = PERIOD_M1 +if period == 2: + per = PERIOD_M3 +if period == 3: + per = PERIOD_M5 +if period == 4: + per = PERIOD_M15 +if period == 5: + per = PERIOD_M30 +if period == 6: + per = PERIOD_H1 + + + +def ontick(): + records = exchange.GetRecords(per) + #------------指标计算--------- + #rsi = TA.RSI(records,14) + #if rsi[-1] > 65 or rsi[-1] < 35: + # return + bb = talib.BBANDS(records.Close,timeperiod=bo, nbdevup=2, nbdevdn=2, matype=0) #计算BB + move = talib.SMA(records.Close,ma2)#收盘价ma + mabt = talib.SMA(bb[0],ma)#上轨ma + mabd = talib.SMA(bb[2],ma)#下跪ma + account = exchange.GetAccount() + + + if (bb[0][-1]-bb[2][-1])/bb[1][-1] < gap: + return + + '''if records[-1]['Close'] < bb[2][-1]: + exchange.Buy(-1,account.Balance*0.1) + Log('逆向开多') + if records[-1]['Close'] > bb[0][-1]: + exchange.Sell(-1,account.Stocks*0.1) + Log('逆向开空') + ''' + else: + if move[-1]>move[-2] and bb[0][-1] > mabt[-1] and bb[0][-2] < mabt[-2] and bb[2][-1] < bb[2][-2] and bb[1][-1] > bb[1][-2] and records[-1]['Close'] > mabt[-1]: + exchange.Buy(-1,account.Balance*0.1) + Log('开多') + + if move[-1] mabd[-2] and bb[0][-1] > bb[0][-2] and bb[1][-1] < bb[1][-2] and records[-1]['Close'] < mabd[-1]: + exchange.Sell(-1,account.Stocks) + Log('开空') + + + '''if bb[0][-1]-bb[2][-1] < bb[0][-2]-bb[2][-2]: + if bb[0][-1] < mabt[-1] and bb[0][-2] > mabt[-2]: + exchange.Sell(-1,account.Stocks) + Log('平多') + + if bb[2][-1] > mabd[-1] and bb[2][-2] < mabd[-2]: + exchange.Buy(-1,account.Balance) + Log('平空')''' +def main(): + while True: + ontick() + Sleep(30000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/146391 + +> 更新时间 + +2019-05-10 10:12:53 diff --git "a/python \347\212\266\346\200\201\346\240\217\350\241\250\346\240\274 \346\230\276\347\244\272\346\214\211\351\222\256\350\214\203\344\276\213.md" "b/python \347\212\266\346\200\201\346\240\217\350\241\250\346\240\274 \346\230\276\347\244\272\346\214\211\351\222\256\350\214\203\344\276\213.md" new file mode 100644 index 00000000..cec676f9 --- /dev/null +++ "b/python \347\212\266\346\200\201\346\240\217\350\241\250\346\240\274 \346\230\276\347\244\272\346\214\211\351\222\256\350\214\203\344\276\213.md" @@ -0,0 +1,37 @@ + +> 策略名称 + +python 状态栏表格 显示按钮范例 + +> 策略作者 + +小小梦 + + + + + +> 源码 (python) + +``` python +import json + +def main(): + tab = { + "type" : "table", + "title" : "demo", + "cols" : ["a", "b", "c"], + "rows" : [["1", "2", {"type" : "button", "cmd" : "coverAll", "name" : "平仓"}]] # 在状态栏表格 第一行,第三列上配置一个按钮 名字是平仓 + } + + LogStatus("`" + json.dumps(tab) + "`") + +``` + +> 策略出处 + +https://www.fmz.com/strategy/147155 + +> 更新时间 + +2019-05-10 11:35:13 diff --git "a/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).md" "b/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3) | python PlotLine Template.md" similarity index 98% rename from "python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).md" rename to "python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3) | python PlotLine Template.md" index 7da9e2bf..fbd0ceff 100644 --- "a/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3).md" +++ "b/python\347\211\210 \347\224\273\347\272\277\347\261\273\345\272\223 (\345\205\274\345\256\2712-3) | python PlotLine Template.md" @@ -1,7 +1,7 @@ > 策略名称 -python版 画线类库 (兼容2-3) +python版 画线类库 (兼容2-3) | python PlotLine Template > 策略作者 @@ -255,4 +255,4 @@ https://www.fmz.com/strategy/39066 > 更新时间 -2017-11-09 21:22:40 +2019-04-13 13:48:51 diff --git "a/rest \347\211\210OKEX\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" "b/rest \347\211\210OKEX\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" new file mode 100644 index 00000000..edce40bb --- /dev/null +++ "b/rest \347\211\210OKEX\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" @@ -0,0 +1,93 @@ + +> 策略名称 + +rest 版OKEX跨期对冲策略(教学) + +> 策略作者 + +小小梦 + +> 策略描述 + +## 极简版OKEX跨期对冲策略(教学) + + ![IMG](https://www.fmz.com/upload/asset/16f1d9f01f17d547a55c.png) + + - 只做正套,反套可以修改下,合约调换一下,即是反套。 + + - 添加两个 交易所对象,第一个季度,第二个当周。 + + - 精简了所有能简化的代码,优化空间还很大,教学策略谨慎实盘,跨期有一定风险。 + + - 欢迎反馈BUG。 + + + ### 教学策略,实盘慎用。 + ### 教学策略,实盘慎用。 + ### 教学策略,实盘慎用。 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|_Begin|true|起始差价| +|_Add|true|差价间距| +|_Profit|true|平仓差价利润| +|_Count|10|节点数量| +|_ContractNum|true|节点下单量| + + +> 源码 (javascript) + +``` javascript +function Hedge (isOpen, priceA, priceB) { + exchanges[0].SetDirection(isOpen ? "sell" : "closesell") + exchanges[1].SetDirection(isOpen ? "buy" : "closebuy"); + (function (routineA, routineB) { + Log(routineA.wait(), routineB.wait(), priceA, priceB) + })(exchanges[0].Go(isOpen ? "Sell" : "Buy", priceA, _ContractNum), exchanges[1].Go(isOpen ? "Buy" : "Sell", priceB, _ContractNum)); +} + +var slidePrice = 5 +function main () { + var tickerA, tickerB + var arr = [] + for (var i = 0 ; i < _Count ; i++) { + arr.push({open: _Begin + i * _Add, cover: _Begin + i * _Add - _Profit, isHold: false}) + } + exchanges[0].SetContractType("quarter") + exchanges[1].SetContractType("this_week") + while (1) { + var tab = {type: "table", title: "状态", cols: ["节点信息"], rows: []} + tickerA = exchanges[0].GetTicker() + tickerB = exchanges[1].GetTicker() + + if (tickerA && tickerB) { + $.PlotLine("差价:A所-B所", tickerA.Last - tickerB.Last) + for (var j = 0 ; j < arr.length; j++) { + if (tickerA.Buy - tickerB.Sell > arr[j].open && !arr[j].isHold) { + Hedge(true, tickerA.Buy - slidePrice, tickerB.Sell + slidePrice) + arr[j].isHold = true + } + if (tickerA.Sell - tickerB.Buy < arr[j].cover && arr[j].isHold) { + Hedge(false, tickerA.Sell + slidePrice, tickerB.Buy - slidePrice) + arr[j].isHold = false + } + tab.rows.push([JSON.stringify(arr[j])]) + } + } + LogStatus(_D(), "\n `" + JSON.stringify(tab) + "`") + Sleep(500) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/144406 + +> 更新时间 + +2019-04-17 16:58:51 diff --git "a/websocket \347\211\210OKEX\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" "b/websocket \347\211\210OKEX\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" new file mode 100644 index 00000000..17ae8ded --- /dev/null +++ "b/websocket \347\211\210OKEX\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" @@ -0,0 +1,114 @@ + +> 策略名称 + +websocket 版OKEX跨期对冲策略(教学) + +> 策略作者 + +小小梦 + +> 策略描述 + +## 极简版OKEX跨期对冲策略(教学) + + - 实盘截图: + ![IMG](https://www.fmz.com/upload/asset/16f45ddc33e43f3248db.png) + + - 只做正套,反套可以修改下,合约调换一下,即是反套。 + + - 添加两个 交易所对象,第一个季度,第二个当周。 + + - 精简了所有能简化的代码,优化空间还很大,教学策略谨慎实盘,跨期有一定风险。 + + - 使用 对手价下单。 + + - 欢迎反馈BUG。 + + + ### 教学策略,实盘慎用。 + ### 教学策略,实盘慎用。 + ### 教学策略,实盘慎用。 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|_Begin|true|起始差价| +|_Add|true|差价间距| +|_Profit|true|平仓差价利润| +|_Count|10|节点数量| +|_ContractNum|true|节点下单量| +|_Instrument_id_A|LTC-USD-190628|A交易所季度合约ID| +|_Instrument_id_B|LTC-USD-190426|B交易所当周合约ID| + + +> 源码 (javascript) + +``` javascript +function Hedge (isOpen, retSetA, retSetB) { + exchanges[0].SetDirection(isOpen ? "sell" : "closesell") + exchanges[1].SetDirection(isOpen ? "buy" : "closebuy"); + (function (routineA, routineB) { + Log(routineA.wait(), routineB.wait(), retSetA, retSetB) + })(exchanges[0].Go(isOpen ? "Sell" : "Buy", -1, _ContractNum), exchanges[1].Go(isOpen ? "Buy" : "Sell", -1, _ContractNum)) +} + +function main () { + var param = {"op": "subscribe", "args": ["futures/ticker:" + _Instrument_id_A, "futures/ticker:" + _Instrument_id_B]} + var client = Dial("wss://real.okex.com:10442/ws/v3|compress=gzip_raw&mode=recv&reconnect=true&payload=" + JSON.stringify(param)) + client.write(JSON.stringify(param)) + var tickerA, tickerB + var arr = [] + for (var i = 0 ; i < _Count ; i++) { + arr.push({open: _Begin + i * _Add, cover: _Begin + i * _Add - _Profit, isHold: false}) + } + while (1) { + var tab = {type: "table", title: "状态", cols: ["节点信息"], rows: []} + Sleep(10) + var ret = client.read(-2) + if (!ret || ret == "") { + continue + } + + var obj = null + try { + obj = JSON.parse(ret) + } catch (e) { + Log(e) + continue + } + + if (obj.table == "futures/ticker" && obj.data[0].instrument_id == _Instrument_id_A) { + tickerA = obj.data[0] + } else if (obj.table == "futures/ticker" && obj.data[0].instrument_id == _Instrument_id_B) { + tickerB = obj.data[0] + } + + if (tickerA && tickerB) { + $.PlotLine(tickerA.instrument_id + "-" + tickerB.instrument_id, tickerA.last - tickerB.last) + for (var j = 0 ; j < arr.length; j++) { + if (tickerA.best_bid - tickerB.best_ask > arr[j].open && !arr[j].isHold) { + Hedge(true, exchanges[0].SetContractType("quarter"), exchanges[1].SetContractType("this_week")) + arr[j].isHold = true + } + if (tickerA.best_ask - tickerB.best_bid < arr[j].cover && arr[j].isHold) { + Hedge(false, exchanges[0].SetContractType("quarter"), exchanges[1].SetContractType("this_week")) + arr[j].isHold = false + } + tab.rows.push([JSON.stringify(arr[j])]) + } + } + LogStatus(_D(), "\n `" + JSON.stringify(tab) + "`") + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/144378 + +> 更新时间 + +2019-04-18 17:56:09 diff --git "a/\344\270\211\350\247\222\345\245\227\345\210\251-\345\237\272\347\241\200\347\211\210.md" "b/\344\270\211\350\247\222\345\245\227\345\210\251-\345\237\272\347\241\200\347\211\210.md" new file mode 100644 index 00000000..b0e3f762 --- /dev/null +++ "b/\344\270\211\350\247\222\345\245\227\345\210\251-\345\237\272\347\241\200\347\211\210.md" @@ -0,0 +1,125 @@ + +> 策略名称 + +三角套利-基础版 + +> 策略作者 + +cruiselijq + + + + + +> 源码 (python) + +``` python +#!python2 +# -*- coding:utf-8 -*- +from time import sleep + +Q3 = 0.5 +tax = 0.0015 #交易费率,0.15% + + +class fmz_market(): + + # 基础行情数据处理,根据传入的交易对,获取数据,返回行情dict + def basic_data_handle(self, pair): + pair_depth = {'sale_volume': 0, 'sale_price': 0, 'buy_volume': 0, 'buy_price': 0} + depth = exchanges[pair].GetDepth() + asks_infor = depth.Asks[0] + bids_infor = depth.Bids[0] + pair_depth['sale_volume'] = asks_infor.Amount + pair_depth['sale_price'] = asks_infor.Price + pair_depth['buy_volume'] = bids_infor.Amount + pair_depth['buy_price'] = bids_infor.Price + #Log(pair_depth) + return pair_depth + + + + #进行参数计算 + def profit_calculation(self): + profit_obtain = 0 + #先获取行情数据 + P1_depth = self.basic_data_handle(0) + P2_depth = self.basic_data_handle(1) + P3_depth = self.basic_data_handle(2) + #买一价格整理 + p1_sale_price =float(P1_depth['sale_price']) + p1_buy_price = float(P1_depth['buy_price']) + p2_sale_price = float(P2_depth['sale_price']) + p2_buy_price = float(P2_depth['buy_price']) + p3_sale_price = float(P3_depth['sale_price']) + p3_buy_price = float(P3_depth['buy_price']) + + #深度数据整理 + p1_sale_volume = float(P1_depth['sale_volume']) + p1_buy_volume = float(P1_depth['buy_volume']) + p2_sale_volume = float(P2_depth['sale_volume']) + p2_buy_volume = float(P2_depth['buy_volume']) + p3_sale_volume = float(P3_depth['sale_volume']) + p3_buy_volume = float(P3_depth['buy_volume']) + # 进行数据分析,正向交易费率,P1:EOS_USDT,P2:BTC_USDT,P3:EOS_ETH,卖出EOS,买入BTC,买入EOS(卖,买,买) + if p1_buy_price / p2_sale_price > p3_sale_price: + #总的手续费计算 + tax_account = (p1_buy_price + p3_sale_price*p2_sale_price + p3_sale_price*p2_sale_price) * Q3 * tax + #总的获利计算 + profit_sum = (p1_buy_price / p2_sale_price - p3_sale_price) * Q3 * p2_buy_price + Log('P1;',p1_buy_price,',P2:',p2_sale_price,',P3:',p3_sale_price,',tax_account:',tax_account,',profit_sum:',profit_sum) + #如果总的获利 < 手续费,则直接退出 + if profit_sum < tax_account: + return 0 + p1_accout_receive = p1_buy_price * Q3 * (1 - tax) #卖出EOS得到usdt,同时减去税 + p3_accout_used = p3_sale_price * Q3 * (1 + tax) #计算买入Q3 EOS的时候,需要的BTC + p2_accout_used = p2_sale_price * p3_accout_used * (1 + tax) #计算买入的BTC 需要耗费的USDT数量 + #获利总量计算 + profit_obtain = p1_accout_receive - p2_accout_used #卖EOS得到的usdt - 买入同样数量的EOS需要的USDT + return profit_obtain + + # 进行数据分析,逆向交易费率,P1:EOS_USDT,P2:BTC_USDT,P3:EOS_BTC,卖出EOS->BTC,卖出BTC,买入EOS(卖,卖,买) + if p1_buy_price / p2_sale_price < p3_sale_price: + # 总的手续费计算 + tax_account = (p3_buy_price * p2_buy_price + p3_buy_price * p2_buy_price + p1_sale_price) * Q3 * tax + # 总的获利计算 + profit_sum = (p3_sale_price - p1_buy_price / p2_sale_price) * Q3 * p2_buy_price + Log('P1;', p1_buy_price, ',P2:', p2_sale_price, ',P3:', p3_sale_price, ',tax_account:', tax_account, ',profit_sum:', profit_sum) + # 如果总的获利 < 手续费,则直接退出 + if profit_sum < tax_account: + return 0 + p3_accout_receive = p3_buy_price * Q3 * (1 - tax) # 卖出EOS得到BTC,同时减去税 + p1_accout_used = p1_sale_price * Q3 * (1 + tax) # 计算买入Q3 EOS的时候,需要的USDT + p2_accout_receive = p2_buy_price * p3_accout_receive * (1 - tax) # 计算卖出的BTC 得到的USDT数量 + # 获利总量计算 + profit_obtain = p2_accout_receive - p1_accout_used #卖出的BTC得到的usdt - 买入EOS锁需要消耗的usdt + return profit_obtain + + return 0 + + #循环计算 + def profit_calculation_cycle(self): + usdt_remain = 0 + for i in range(10000): + profit_obtain = self.profit_calculation() + usdt_remain = usdt_remain + profit_obtain + if profit_obtain > 0: + Log(u'EOS:',Q3,u'.....USDT:',usdt_remain) + + + +def main(): + Log(exchange.GetAccount()) + Log("测试") + fmz_market_instances = fmz_market() + fmz_market_instances.profit_calculation_cycle() + # fmz_market_instances.basic_data_handle(0) +``` + +> 策略出处 + +https://www.fmz.com/strategy/151145 + +> 更新时间 + +2019-06-11 14:24:17 diff --git "a/\344\270\211\350\247\222\345\245\227\345\210\251\347\255\226\347\225\245\344\275\223\351\252\214\347\211\210.md" "b/\344\270\211\350\247\222\345\245\227\345\210\251\347\255\226\347\225\245\344\275\223\351\252\214\347\211\210.md" new file mode 100644 index 00000000..715555bb --- /dev/null +++ "b/\344\270\211\350\247\222\345\245\227\345\210\251\347\255\226\347\225\245\344\275\223\351\252\214\347\211\210.md" @@ -0,0 +1,99 @@ + +> 策略名称 + +三角套利策略体验版 + +> 策略作者 + +shoujing + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Q3|0.5|搬砖数量| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2019-04-24 00:00:00 +end: 2019-05-24 00:00:00 +period: 1h +exchanges: [{"eid":"OKEX","currency":"BTC_USDT","balance":10000,"stocks":3},{"eid":"OKEX","currency":"LTC_USDT","balance":10000,"stocks":3},{"eid":"OKEX","currency":"LTC_BTC","balance":10000,"stocks":3}] +*/ + +var initAccount={//初始账户 + BTC:0.009, + LTC:0.7, + USDT:55, +} + +var doAccount={//操作账户初始化 + BTC:0.009, + LTC:0.7, + USDT:55, +} + +var tax = 0.0015;//交易费率,0.15% + +function getBaseData(){ + var P1,P2,P3;//基础价格数据,分别为btc_usdt,ltc_usdt,ltc_btc交易对 + P1 = exchanges[0].GetTicker(); + P2 = exchanges[1].GetTicker(); + P3 = exchanges[2].GetTicker(); + return [P1,P2,P3]; +} + +function main() { + Log(initAccount); + var xunhuan = true;//程序是否继续执行,用于判断账户余额是否满足操作,这里不做考虑 + while(xunhuan){ + var baseData = getBaseData();//获取基础数据 + if((baseData[1].Buy-baseData[0].Sell*baseData[2].Sell)*Q3>Q3*tax*(2*baseData[1].Buy+baseData[0].Sell*baseData[2].Sell)){//考虑了手续费的套利条件(P2-P1*P3)*Q3>Q3*tax*(2*P2+P1*P3),注意为使订单能全部成交,均使用对手价进行判断,实际操作时还需要考虑交易深度问题 + if(xunhuan){ + doAccount.LTC = doAccount.LTC + Q3*(1-tax); + doAccount.BTC = doAccount.BTC - baseData[2].Sell*Q3;//买入LTC、卖出BTC + doAccount.LTC = doAccount.LTC - Q3; + doAccount.USDT = doAccount.USDT + baseData[1].Buy*Q3*(1-tax);//卖出LTC,获得USDT + doAccount.BTC = doAccount.BTC + baseData[2].Sell*Q3*(1-tax); + doAccount.USDT = doAccount.USDT - baseData[0].Sell*baseData[2].Sell*Q3;//买入BTC,获得USDT + Log('Usdt收益:',doAccount.USDT-initAccount.USDT,'usdt','正循环套利','#FF0000'); + Log('真实收益:',doAccount.USDT-initAccount.USDT-(initAccount.LTC-doAccount.LTC)*baseData[1].Buy-(initAccount.BTC-doAccount.BTC)*baseData[2].Sell,'#0000FF')//扣除手续费后的真实收益 + Log(doAccount.USDT-initAccount.USDT-(initAccount.LTC-doAccount.LTC)*baseData[1].Buy-(initAccount.BTC-doAccount.BTC)*baseData[2].Sell,'#0000FF') + }else{ + xunhuan = false; + } + }else if(baseData[0].Buy*baseData[2].Buy-baseData[1].Sell>(2*baseData[0].Buy*baseData[2].Buy+baseData[1].Sell)*tax){//考虑手续费的逆循环套利 + if(xunhuan){ + doAccount.LTC = doAccount.LTC - Q3; + doAccount.BTC = doAccount.BTC + baseData[2].Buy*Q3*(1-tax); + doAccount.LTC = doAccount.LTC + Q3*(1-tax); + doAccount.USDT = doAccount.USDT - baseData[1].Sell*Q3; + doAccount.BTC = doAccount.BTC - baseData[2].Buy*Q3; + doAccount.USDT = doAccount.USDT + baseData[0].Buy*baseData[2].Buy*Q3*(1-tax); + Log('Usdt收益:',doAccount.USDT-initAccount.USDT,'usdt,逆循环套利','#FF0000'); + Log('真实收益:',doAccount.USDT-initAccount.USDT-(initAccount.LTC-doAccount.LTC)*baseData[1].Sell-(initAccount.BTC-doAccount.BTC)*baseData[2].Buy,'#0000FF') + Log(doAccount.USDT-initAccount.USDT-(initAccount.LTC-doAccount.LTC)*baseData[1].Buy-(initAccount.BTC-doAccount.BTC)*baseData[2].Sell,'#0000FF') + }else{ + xunhuan = false; + } + } + Sleep(1000);//程序休眠1秒 + } +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/149489 + +> 更新时间 + +2019-05-25 18:11:32 diff --git "a/\344\272\244\346\230\223\346\211\200\346\234\200\345\260\217\346\225\260\351\207\217\345\222\214\347\262\276\345\272\246.md" "b/\344\272\244\346\230\223\346\211\200\346\234\200\345\260\217\346\225\260\351\207\217\345\222\214\347\262\276\345\272\246.md" index efcc031e..210cbc45 100644 --- "a/\344\272\244\346\230\223\346\211\200\346\234\200\345\260\217\346\225\260\351\207\217\345\222\214\347\262\276\345\272\246.md" +++ "b/\344\272\244\346\230\223\346\211\200\346\234\200\345\260\217\346\225\260\351\207\217\345\222\214\347\262\276\345\272\246.md" @@ -37,6 +37,10 @@ imaltai -- main 函数在策略中不会触发, 只做为模板调试的入口 */ +/* eslint no-unused-vars : "off" */ +/* eslint no-constant-condition : "off" */ +/* global _N $ Log GetAccount GetTicker GetRecords PD_LONG PD_SHORT */ + var DEFAULT_MINAMOUNT = 1; var DEFAULT_AMOUNTPRECISION = 2; var DEFAULT_PRICEPRECISION = 4; @@ -54,7 +58,7 @@ function findItem(array, keyName, value) { if (!result && (value.includes('usd') && !value.includes('usdt'))) { value = value + 't'; //usd 在 币对里面肯定放在最后 - for (var i = 0; i < array.length; i++) { + for (i = 0; i < array.length; i++) { if (array[i][keyName].toLowerCase().trim() == value) { result = array[i]; break; @@ -214,7 +218,7 @@ $.GetMinTotal = function (jiaoyisuo, bidui) { return 0; } -huobiMinAmounts = [{"symbol":"AST_BTC", "minamount":1}, +var huobiMinAmounts = [{"symbol":"AST_BTC", "minamount":1}, {"symbol":"ACT_BTC", "minamount":0.1}, {"symbol":"ADX_BTC", "minamount":0.01}, {"symbol":"ABT_BTC", "minamount":0.1}, @@ -424,7 +428,7 @@ huobiMinAmounts = [{"symbol":"AST_BTC", "minamount":1}, {"symbol":"ZLA_ETH", "minamount":0.1}, {"symbol":"CTXC_ETH", "minamount":0.1}]; -huobiPrecisions = [{"symbol":"btc_usdt","priceprecision":2,"amountprecision":4,"symbol-partition":"main"}, +var huobiPrecisions = [{"symbol":"btc_usdt","priceprecision":2,"amountprecision":4,"symbol-partition":"main"}, {"symbol":"bch_usdt","priceprecision":2,"amountprecision":4,"symbol-partition":"main"}, {"symbol":"eth_usdt","priceprecision":2,"amountprecision":4,"symbol-partition":"main"}, {"symbol":"etc_usdt","priceprecision":4,"amountprecision":4,"symbol-partition":"main"}, @@ -658,6 +662,8 @@ huobiPrecisions = [{"symbol":"btc_usdt","priceprecision":2,"amountprecision":4," {"symbol":"mco_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, {"symbol":"gnt_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, {"symbol":"gas_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"ekt_eth","priceprecision":8,"amountprecision":4,"symbol-partition":"innovation"}, +{"symbol":"bcv_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, {"symbol":"ost_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, {"symbol":"link_eth","priceprecision":8,"amountprecision":2,"symbol-partition":"innovation"}, {"symbol":"rcn_eth","priceprecision":8,"amountprecision":0,"symbol-partition":"innovation"}, @@ -695,7 +701,7 @@ huobiPrecisions = [{"symbol":"btc_usdt","priceprecision":2,"amountprecision":4," {"symbol":"bix_eth","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}, {"symbol":"bix_usdt","priceprecision":6,"amountprecision":4,"symbol-partition":"innovation"}]; -okexRegulation = [ +var okexRegulation = [ {"symbol":"bch_btc", "minamount":0.001, "amountprecision":0.00000001, "priceprecision": 0.00000001}, {"symbol":"ltc_btc", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, {"symbol":"eth_btc", "minamount":0.001, "amountprecision":0.000001, "priceprecision": 0.00000001}, @@ -1665,4 +1671,4 @@ https://www.fmz.com/strategy/108887 > 更新时间 -2018-08-30 23:47:33 +2019-07-07 11:51:41 diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230\344\271\260\345\205\245\347\256\200\345\215\225\347\211\210|Simple Iceberg order to buy.md" "b/\345\206\260\345\261\261\345\247\224\346\211\230\344\271\260\345\205\245\347\256\200\345\215\225\347\211\210|Simple Iceberg order to buy.md" index 4d14e7b9..d19ab6a2 100644 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230\344\271\260\345\205\245\347\256\200\345\215\225\347\211\210|Simple Iceberg order to buy.md" +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230\344\271\260\345\205\245\347\256\200\345\215\225\347\211\210|Simple Iceberg order to buy.md" @@ -7,7 +7,12 @@ botvsing +> 策略描述 +Very simple, just for learn. +Code is best annotation. + +冰山委托买入,将订单分成小笔M买入,避免冲击市场,是很好的简单入门比特币量化交易的学习策略 > 策略参数 @@ -54,4 +59,4 @@ https://www.fmz.com/strategy/121522 > 更新时间 -2018-10-16 10:57:07 +2019-07-03 16:40:18 diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230\345\215\226\345\207\272\347\256\200\345\215\225\347\211\210|Simple Iceberg order to sell.md" "b/\345\206\260\345\261\261\345\247\224\346\211\230\345\215\226\345\207\272\347\256\200\345\215\225\347\211\210|Simple Iceberg order to sell.md" index 72154fe7..9c990270 100644 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230\345\215\226\345\207\272\347\256\200\345\215\225\347\211\210|Simple Iceberg order to sell.md" +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230\345\215\226\345\207\272\347\256\200\345\215\225\347\211\210|Simple Iceberg order to sell.md" @@ -12,6 +12,8 @@ botvsing Very simple, just for learn. Code is best annotation. +冰山委托卖出,将订单分成小笔卖出,避免冲击市场,是很好的简单入门比特币量化交易的学习策略 + > 策略参数 @@ -59,4 +61,4 @@ https://www.fmz.com/strategy/121524 > 更新时间 -2018-10-16 10:57:32 +2019-07-03 16:39:19 diff --git "a/\345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245 python \347\211\210.md" "b/\345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245 python \347\211\210.md" new file mode 100644 index 00000000..0b4b441b --- /dev/null +++ "b/\345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245 python \347\211\210.md" @@ -0,0 +1,71 @@ + +> 策略名称 + +动态平衡策略 python 版 + +> 策略作者 + +teddy + + + + + +> 源码 (python) + +``` python + +# !usr/bin/ python3 +# *_* coding:utf-8 *_* +#学会python后写的第一个动态平衡策略 +# QQ:5325049 不足之处欢迎指正 + +import time + +#定义获取行情及账户信息函数 +def nowinfo(): + global NowTicker,NowAsset,NowCoinValue,AssetDiff + NowTicker = exchange.GetTicker() #获取行情信息 + NowAsset = exchange.GetAccount() # 获取账户信息 + NowCoinValue =NowTicker.Last * NowAsset.Stocks #计算币资产净值 + AssetDiff = NowCoinValue-NowAsset.Balance #计算币资产与现金差额 + +# 定义交易执行函数 +def trade(): + if AssetDiff > NowAsset.Balance*0.05: # 判断币值是否超过资金5% + Log("交易将被执行,以",NowTicker.Buy,"卖出",AssetDiff/2/NowTicker.Buy,"个币") + exchange.SetPrecision(5,5) #设置计价精度 + exchange.Sell(NowTicker.Buy,AssetDiff/2/NowTicker.Buy) #执行币卖出交易 + elif AssetDiff < NowAsset.Balance*(-0.05): #判断币值是否低于资金5% + Log("交易将被执行,以",NowTicker.Sell,"买入",AssetDiff/-2/NowTicker.Sell,"个币") + exchange.SetPrecision(5,5) #设置计价精度 + exchange.Buy(NowTicker.Sell,AssetDiff/-2/NowTicker.Sell) #执行币买入交易 + else: + Log("未触发交易条件") + +# 入口函数,只要定义了系统就会自动执行该函数,不需要调用啊 +def main(): + i = 0 + while i < 1000: #设置执行总次数 + nowinfo() # 调用获取行情资产函数 + Log(NowTicker) # 打印行情信息 + Log(NowAsset) # 打印账户信息 + Log("当前币余额:",NowAsset.Stocks) + Log("当前资金余额:",NowAsset.Balance) + Log("当前币市值:", NowCoinValue) + Log("币市值与资金差额:",AssetDiff) + trade() #调用 交易执行函数 + i+=1 # 条件迭代 + Log("第", i, "轮循环结束") + time.sleep(60) # 等待60秒 + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/152830 + +> 更新时间 + +2019-06-22 18:35:30 diff --git "a/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.md" "b/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.md" index f22fa10a..28f31d8d 100644 --- "a/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.md" +++ "b/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225 V1.2.md" @@ -31,7 +31,7 @@ Zero V1.1 解决了OKCoin冻结0.0001个币导致程序卡住的bug -更详细的说明, 移步: https://www.botvs.com/#!/bbs-topic/38 +更详细的说明, 移步: https://www.fmz.com/#!/bbs-topic/38 > 策略参数 diff --git "a/\345\215\225\350\276\271\347\275\221\346\240\274 (Copy).md" "b/\345\215\225\350\276\271\347\275\221\346\240\274 (Copy).md" new file mode 100644 index 00000000..26c3df4b --- /dev/null +++ "b/\345\215\225\350\276\271\347\275\221\346\240\274 (Copy).md" @@ -0,0 +1,190 @@ + +> 策略名称 + +单边网格 (Copy) + +> 策略作者 + +xd123456 + +> 策略描述 + +测试的时候填写起始价格来测试是否正常 +起始价格不填写为现价买入+价格区间买入 +微信173970984 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|buyjingdu|2|下单价格精度| +|buymount|3|下单数量精度| +|buypersent|true|下单百分比| +|buylimit|0.01|最小交易量| +|reffertime|3000|刷新时间间隔| +|moneybt|100|网格的价格间距| +|startpricex|false|起始价格| +|liruncha|0.1|利润差价| + + +> 源码 (javascript) + +``` javascript +//获取账户余额 +var startPrice= 0; +function getBalancex(){ + var balance = exchange.GetAccount(); + Log("余额:", balance.Balance,"币余额:", balance.Stocks); + return balance; +} + + +//获取币种现价 +function getPrice(typex){ + var NowPrice =exchange.GetTicker(); + if(typex=='buy'){ + + Log("当前买入价格:"+(NowPrice.Buy)) + return NowPrice.Buy; + } + if(typex=='sell'){ + Log("当前卖出价格:"+(NowPrice.Sell)) + return NowPrice.Sell; + } +} + +//取消所有买单操作重新下单 +function cancelOrders(){ + //获取所有未成交订单 + var orders = _C(exchange.GetOrders); + for(var z in orders){ + //# Log("当前订单类型:",orders[z].Type,"订单Id:",orders[z].Id); + if(orders[z].Type==0){ + exchange.CancelOrder(orders[z].Id) + Log("取消之前的挂单成功,id:",orders[z].Id); + } + } + /* + for(var i=0;i0){ + price=startpricex-moneybt; + }else{ + price=price-moneybt; //实际价格为当前价格减去区间价格 + } + startPrice=price; + var balancex = getBalancex(); + balanceAmount = balancex.Balance; + + //需要购买的数量 + doAmount = (balanceAmount*(buypersent/100))/price + + + + var id = 0; + if(doAmount>buylimit){ + saveBuyId=id= exchange.Buy(price, doAmount); + Log("下单成功id:", id," 价格:", price," 数量:", doAmount); + }else{ + Log("可买数量低于最小交易量:", buylimit," 数量:", doAmount); + } +} + + +//根据上次的ID来检查订单状态 然后出售 +function doSellTrading2(){ + //获取订单状态 + Log("上一订单ID:", saveBuyId); + if(saveBuyId!=0){ + var order = exchange.GetOrder(saveBuyId); + if(order){ + if(order.Status==ORDER_STATE_CLOSED){ + leftStocks=leftStocks-orderList[i].Amount + var sellPrice = order.Price+liruncha; + var sellAmount = order.Amount; + var id=exchange.Sell(sellPrice, sellAmount); + Log("出售成功id:", id," 价格:", sellPrice," 数量:", sellAmount); + } + } + } + +} + + + + + + + + + +//定时扫描是否有买单成交 并出售对应数量 +function doSellTrading(){ + //如果余额大于零 + balan = getBalancex() + leftStocks=balan.Stocks; + if(balan.Stocks>0){ + var orderList = exchange.GetTrades() + //理论检测前20条数据即可 + if(orderList){ + for(i=0;i<=100;i++){ + //Log("查看订单信息:",orderList); + if(orderList[i].Type==0 && leftStocks>orderList[i].Amount){ + leftStocks=leftStocks-orderList[i].Amount + var sellPrice = orderList[i].Price+liruncha; + var sellAmount = orderList[i].Amount; + var id=exchange.Sell(sellPrice, sellAmount); + Log("出售成功id:", id," 价格:", sellPrice," 数量:", sellAmount); + } + } + } + } +} + + +function onTick(){ + //在这里写策略逻辑,将会不断调用exchange + doSellTrading2() + doTradingBuy() +} +/* +function main(){ + var id = exchange.Sell(99999, 1); + var order = exchange.GetOrder(id);//参数id为订单号码,需填入你想要查询的订单的号码 + Log("Id", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:", + order.DealAmount, "Status:", order.Status, "Type:", order.Type); +} +*/ +function main(){ + exchange.SetPrecision(buyjingdu, buymount); + while(true){ + onTick(); + Sleep(reffertime); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/144679 + +> 更新时间 + +2019-04-19 14:36:15 diff --git "a/\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211.md" "b/\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211|Multiple charts example.md" similarity index 95% rename from "\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211.md" rename to "\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211|Multiple charts example.md" index 0708de0b..355a0604 100644 --- "a/\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211.md" +++ "b/\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211|Multiple charts example.md" @@ -1,13 +1,16 @@ > 策略名称 -多图表例子(数据可下载为csv等表格) +多图表例子(数据可下载为csv等表格)|Multiple charts example > 策略作者 botvsing +> 策略描述 +一个展示多个图表的例子,多个图可共用一行,可以设置图表展示的宽度。 +支持HighCharts和HighStocks的基本图表,如折线图、直方图、柱状图、饼图、K线图等等,具体查询highchart官网,仿照本例子稍微更改就可使用。 @@ -334,4 +337,4 @@ https://www.fmz.com/strategy/136056 > 更新时间 -2019-01-31 10:31:25 +2019-07-03 16:13:56 diff --git "a/\345\261\261\345\257\250\345\270\201\346\214\207\346\225\260\357\274\2102018.02.22\345\237\272\347\202\2711000\357\274\211.md" "b/\345\261\261\345\257\250\345\270\201\346\214\207\346\225\260\357\274\2102018.02.22\345\237\272\347\202\2711000\357\274\211.md" index 8647b4d2..79d1c0e6 100644 --- "a/\345\261\261\345\257\250\345\270\201\346\214\207\346\225\260\357\274\2102018.02.22\345\237\272\347\202\2711000\357\274\211.md" +++ "b/\345\261\261\345\257\250\345\270\201\346\214\207\346\225\260\357\274\2102018.02.22\345\237\272\347\202\2711000\357\274\211.md" @@ -7,7 +7,9 @@ botvsing +> 策略描述 +疼痛及了山寨币对BTC价格指数,2018.02.22基点1000。新加入的山寨币会列出。 @@ -67,4 +69,4 @@ https://www.fmz.com/strategy/73461 > 更新时间 -2018-07-04 18:15:59 +2019-07-03 16:46:08 diff --git "a/\345\270\201\345\256\211 \346\217\220\345\270\201\350\214\203\344\276\213\344\273\243\347\240\201.md" "b/\345\270\201\345\256\211 \346\217\220\345\270\201\350\214\203\344\276\213\344\273\243\347\240\201.md" new file mode 100644 index 00000000..05769add --- /dev/null +++ "b/\345\270\201\345\256\211 \346\217\220\345\270\201\350\214\203\344\276\213\344\273\243\347\240\201.md" @@ -0,0 +1,69 @@ + +> 策略名称 + +币安 提币范例代码 + +> 策略作者 + +小小梦 + + + + + +> 源码 (javascript) + +``` javascript +String.prototype.format= function(){ +    var args = Array.prototype.slice.call(arguments); +    var count=0; +    return this.replace(/%s/g,function(s,i){ +        return args[count++]; +    }); +} + +function WithdrawForBinance (accessKey, currency, address, addressTag, amount) { + /* Withdraw API desc on Binance API doc + query string : + asset=ETH&address=0x6915f16f8791d0a1cc2bf47c13a6b2a92000504b&amount=1&recvWindow=5000&name=test×tamp=1510903211000 + HMAC SHA256 signature: + [linux]$ echo -n "asset=ETH&address=0x6915f16f8791d0a1cc2bf47c13a6b2a92000504b&amount=1&recvWindow=5000×tamp=1510903211000" | + openssl dgst -sha256 -hmac "NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j" + (stdin)= 157fb937ec848b5f802daa4d9f62bea08becbf4f311203bda2bd34cd9853e320 + curl command: + (HMAC SHA256) + [linux]$ curl -H "X-MBX-APIKEY: vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A" -X + POST 'https://www.binance.com/wapi/v3/withdraw.html? + asset=ETH&address=0x6915f16f8791d0a1cc2bf47c13a6b2a92000504b&amount=1&recvWindow=5000&name=addressName×tamp=1510903211000& + signature=157fb937ec848b5f802daa4d9f62bea08becbf4f311203bda2bd34cd9853e320' + */ + + var timeStamp = new Date().getTime() + var queryString = "asset=%s&address=%s&amount=%s&name=%s×tamp=%s" + queryString = queryString.format(currency, address, amount, addressTag, timeStamp) + + // sign + var signature = exchange.HMAC("sha256", "hex", queryString, "{{secretkey}}") + var uri = "https://www.binance.com/wapi/v3/withdraw.html?" + queryString + "&signature=" + signature + + // request + var ret = HttpQuery(uri, "", "", "X-MBX-APIKEY: " + accessKey, true) + + Log(ret) +} + + + + +function main() { + WithdrawForBinance("your accessKey", "ETH", "the address that you want to send", "test", "0.01") +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/147856 + +> 更新时间 + +2019-05-16 11:06:54 diff --git "a/\345\270\201\345\256\211\345\217\226\346\266\210\346\211\200\346\234\211\344\272\244\346\230\223\345\257\271\346\234\252\345\256\214\346\210\220\350\256\242\345\215\225\357\274\210IO\346\211\251\345\261\225\347\244\272\350\214\203\357\274\211|Cancel ALL Binance Orders.md" "b/\345\270\201\345\256\211\345\217\226\346\266\210\346\211\200\346\234\211\344\272\244\346\230\223\345\257\271\346\234\252\345\256\214\346\210\220\350\256\242\345\215\225\357\274\210IO\346\211\251\345\261\225\347\244\272\350\214\203\357\274\211|Cancel ALL Binance Orders.md" index 96a96108..1f17723c 100644 --- "a/\345\270\201\345\256\211\345\217\226\346\266\210\346\211\200\346\234\211\344\272\244\346\230\223\345\257\271\346\234\252\345\256\214\346\210\220\350\256\242\345\215\225\357\274\210IO\346\211\251\345\261\225\347\244\272\350\214\203\357\274\211|Cancel ALL Binance Orders.md" +++ "b/\345\270\201\345\256\211\345\217\226\346\266\210\346\211\200\346\234\211\344\272\244\346\230\223\345\257\271\346\234\252\345\256\214\346\210\220\350\256\242\345\215\225\357\274\210IO\346\211\251\345\261\225\347\244\272\350\214\203\357\274\211|Cancel ALL Binance Orders.md" @@ -7,7 +7,9 @@ botvsing +> 策略描述 +币安取消所有交易对未完成订单,使用IO接口,可以当作学习IO接口连接为支持API接口的范例 @@ -45,4 +47,4 @@ https://www.fmz.com/strategy/121549 > 更新时间 -2018-10-16 10:58:22 +2019-07-03 16:36:05 diff --git "a/\346\214\207\346\225\260\345\271\263\350\241\241\347\255\226\347\225\245|Index Balance Bot.md" "b/\346\214\207\346\225\260\345\271\263\350\241\241\347\255\226\347\225\245|Index Balance Bot.md" index 043ad68f..3062a155 100644 --- "a/\346\214\207\346\225\260\345\271\263\350\241\241\347\255\226\347\225\245|Index Balance Bot.md" +++ "b/\346\214\207\346\225\260\345\271\263\350\241\241\347\255\226\347\225\245|Index Balance Bot.md" @@ -16,6 +16,8 @@ Remember, the total ratio added up must lower than 1 and has a extra room to buy 指数平衡策略。可以将资产按预设比例进行平衡,支持跨交易所平衡。注意同意个交易所要相邻添加。 +The Flash Crash Bot sets pre-orders above and below a specified base price. Buy orders are placed at predefined price points that fall below the set base price. Conversely, sell orders are placed above this base price. This bot is most effective in a volatile market. + > 策略参数 @@ -107,4 +109,4 @@ https://www.fmz.com/strategy/116012 > 更新时间 -2018-10-17 12:09:51 +2019-07-03 16:43:18 diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).md" "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).md" index ee89f59b..1a72349a 100644 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).md" +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).md" @@ -26,7 +26,7 @@ function main() { } var emaSlow = TA.EMA(r, 20) var emaFast = TA.EMA(r, 5) - var cross = _Cross(emaFast, emaSlow); // 判断指标 相交状态, _Cross 参看 : https://www.botvs.com/bbs-topic/1140 + var cross = _Cross(emaFast, emaSlow); // 判断指标 相交状态, _Cross 参看 : https://www.fmz.com/bbs-topic/1140 if (mp <= 0 && cross > 1) { Log(pair, "买, 金叉周期", cross, "mp:", mp); return 0.1 * (mp < 0 ? 2 : 1) // 返回的数值 就是 要开仓的 数量, 正数是 开多 ,负数是 开空, 0 是 全部平掉。 diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\350\207\252\351\200\202\345\272\224\345\235\207\347\272\277\344\272\244\346\230\223\347\263\273\347\273\237\344\273\245\345\217\212KAMA\347\256\227\346\263\225\350\247\243\346\236\220\342\200\224\342\200\224\345\237\272\344\272\216\345\217\221\346\230\216\350\200\205\351\207\217\345\214\226\344\272\244\346\230\223\350\275\257\344\273\266.md" "b/\346\225\260\345\255\227\350\264\247\345\270\201\350\207\252\351\200\202\345\272\224\345\235\207\347\272\277\344\272\244\346\230\223\347\263\273\347\273\237\344\273\245\345\217\212KAMA\347\256\227\346\263\225\350\247\243\346\236\220\342\200\224\342\200\224\345\237\272\344\272\216\345\217\221\346\230\216\350\200\205\351\207\217\345\214\226\344\272\244\346\230\223\350\275\257\344\273\266.md" new file mode 100644 index 00000000..fa17647f --- /dev/null +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\350\207\252\351\200\202\345\272\224\345\235\207\347\272\277\344\272\244\346\230\223\347\263\273\347\273\237\344\273\245\345\217\212KAMA\347\256\227\346\263\225\350\247\243\346\236\220\342\200\224\342\200\224\345\237\272\344\272\216\345\217\221\346\230\216\350\200\205\351\207\217\345\214\226\344\272\244\346\230\223\350\275\257\344\273\266.md" @@ -0,0 +1,180 @@ + +> 策略名称 + +数字货币自适应均线交易系统以及KAMA算法解析——基于发明者量化交易软件 + +> 策略作者 + +Hukybo + +> 策略描述 + +# 1、自适应均线KAMA简介 + +顾名思义自适应均线(KAMA)属于移动平均线(Moving Average)类别,但是与传统移动平均线不一样的是它很“聪明”。我们知道普通均线有很多缺点,比如:短期均线贴近价格走势,非常敏感,但是很容易产生虚假信号;长期均线在趋势判断上非常准确,但是往往行情已经走了一段,它才反应过来。 + +KAMA的“聪明”就体现在,它能根据当前的市场状态,也就是波动率,来自主调节敏感性。其变现形式就是:在震荡行情中,KAMA的变化明显减慢;当趋势来临的时候,又反应迅速。那么在实盘中,它的好处就是:既能减少因“日常杂波”产生的交易成本,又能在行情起飞时及时上车。 + +# 2、图表中的KAMA + ![IMG](https://www.fmz.com/upload/asset/39cae99a1e12e456fa33.png) + + +# 3、KAMA的计算方法 + +- 方向(DIR) = 收盘价 - n日前收盘价 +- 波动率(VIR) = sum(abs(收盘价 - 上一个交易日收盘价), n) +- 效率(ER) = 方向 / 波动率 +- 快速 = 2 / (n1 + 1) +- 慢速 = 2 / (n2 + 1) +- 平滑(CS) = 效率 * (快速 - 慢速) + 慢速 +- 系数(CQ) = 平滑 * 平滑 +- KAMA = 指数加权平均(动态移动平均(收盘价, 系数), 2) + +其中,n、n1、n2都是周期参数,默认情况下n周期数是10,n1是短期周期数为2,n2是长期周期数为30。这也是KAMA作者Perry Kaufman认同的一组参数,n用于方向和波动率计算效率,n1和n2是快速均线和慢速均线的周期数,理论上n1的参数越大,KAMA就越平滑。 + +KAMA的计算方法是:首先计算出方向(DIR)和波动率(VIR),然后在跟两者的比例计算出效率。效率(ER)是衡量价格的变化程度,计算方式也很简单:方向 / 波动率。计算结果是0~1之间,当ER的值越接近0表明市场处于震荡状态,当ER的值越接近1表明市场处于趋势状态。 + +当计算出效率(ER)就可以结合快速均线和慢速均线推导出平滑常数(CS):效率 * (快速 - 慢速) + 慢速。CS代表了趋势运行的速度,根据CS的计算公式,我们可以发现,CS的变化始终与ER的变化成正比。 + +然后根据平滑的乘方计算出系数(CQ),其目的是使慢周期参数在计算中起到更重要的作用,这也是一个较为保守的做法。KAMA最终的平滑程度是由系数(CQ)决定,在KAMA的计算中,系数(CQ)决定了最后两次均线平滑的周期参数,即:指数加权平均(动态移动平均(收盘价, 系数), 2)。 + +# 4、如何使用KAMA + +尽管KAMA的计算方法非常复杂,但是使用方法与普通均线类似,在实际应用中,它不仅可以判断行情走势,还可以用于精确的买卖点。由于它非常“聪明”,可以用于很多交易策略中,甚至在数字货币中也值得一试。 + +- 当价格大于KAMA,并且KAMA向上时,多头开仓。 +- 当价格小于KAMA,并且KAMA向下时,空头开仓。 +- 当价格小于KAMA,或者KAMA向下时,多头平仓。 +- 当价格大于KAMA,或者KAMA向上时,空头平仓。 + +# 5、基于KAMA构建交易策略 + +**第一步:计算KAMA** +注意!在左上角选择编程语言为:`My语言`。在talib库中已经有现成的KAMA,但是它只有一个外部参数(n)周期,n1和n2已经默认为2和30。本篇中的策略只作抛砖引玉直接使用,动手能力强的小伙伴也可以自己写哈。那么在My语言中也可以直接与JavaScript语言混合,注意看下面的代码: +``` +%% // My语言内JavaScript的标准格式 +scope.KAMA = function() { + var r = _C(exchange.GetRecords); // 获取K线数组 + if (r.length > 140) { // 过滤K线长度 + var kama = talib.KAMA(r, 140); // 调用talib库计算KAMA + return kama[kama.length - 2]; // 返回KAMA的具体数值 + } + return; +} +%% // My语言内JavaScript的标准格式 +``` + +**第二步:计算交易条件并下单** +``` +%% +scope.KAMA = function() { + var r = _C(exchange.GetRecords); + if (r.length > 140) { + var kama = talib.KAMA(r, 140); + return kama[kama.length - 2]; + } + return; +} +%% + +K^^KAMA; // 把KAMA打印到图表上 +A:CLOSE; // 把收盘价打印到图表上 + +K > REF(K, 1) && CLOSE > K,BK; // 开多 +K < REF(K, 1) && CLOSE < K,SK; // 开空 +K < REF(K, 1) || CLOSE < K,SP; // 平多 +K > REF(K, 1) || CLOSE > K,BP; // 平空 +``` + +**第三步:设置策略信号过滤方式** +``` +%% +scope.KAMA = function() { + var r = _C(exchange.GetRecords); + if (r.length > 140) { + var kama = talib.KAMA(r, 140); + return kama[kama.length - 2]; + } + return; +} +%% + +K^^KAMA; +A:CLOSE; + +K > REF(K, 1) && CLOSE > K,BK; +K < REF(K, 1) && CLOSE < K,SK; +K < REF(K, 1) || CLOSE < K,SP; +K > REF(K, 1) || CLOSE > K,BP; + +AUTOFILTER; // 启用一开一平信号过滤机制 +``` + +[点击复制完整策略源码](https://www.fmz.com/strategy/155663) + +# 6、策略回测 + +为了更接近真实的交易环境,我们在回测时采用开平仓各2跳的滑点来压力测试,测试环境如下: + +- 交易所:BitMEX +- 行情品种:XBTUSD +- 交易品种:XBTUSD +- 时间:2017年07月01日~2019年07月01日 +- K线周期:日线 +- 滑点:开平仓各2跳 + +**测试环境** + ![IMG](https://www.fmz.com/upload/asset/399923632ea2b1e1ebc8.png) +**收益明细** + ![IMG](https://www.fmz.com/upload/asset/3a2eb03e368a8b48d9d0.png) +**资金曲线** + ![IMG](https://www.fmz.com/upload/asset/39c54ce3928c3c8c15cb.png) + +单从上面的回测结果看,这个简单的KAMA策略果然不负众望,即使在数字货币2018年的超级大熊市中,资金曲线并没有出现较大的回撤,并且在行情长期处于震荡时期,也没有来回开平仓,造成不必要的亏损。同时在2019年的牛市中也有不错的表现。 + +# 7、总结 + +一个优秀的可以实盘的策略一定是经过千锤百炼的打磨,本篇中的策略还有很多可以优化升级的空间,比如增加一定的过滤条件、主动的止盈止损条件等等。作为均线的一种,KAMA继承了普通均线优缺点,同时又进行了升华。在一个变化莫测的市场,即便是固定一个“最好的参数”也很难适应未来的行情,因此这种随势而动,随行情变化而变化的方法或许是一个更好的选择。 + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2017-07-01 00:00:00 +end: 2019-07-01 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_BitMEX","currency":"XBT_USD"}] +args: [["SlideTick",0,126961],["ContractType","XBTUSD",126961]] +*) + +%% +scope.KAMA = function() { + var r = _C(exchange.GetRecords); + if (r.length > 140) { + var kama = talib.KAMA(r, 140); + return kama[kama.length - 2]; + } + return; +} +%% + +K^^KAMA; +A:CLOSE; + +K > REF(K, 1) && CLOSE > K,BK; +K < REF(K, 1) && CLOSE < K,SK; +K < REF(K, 1) || CLOSE < K,SP; +K > REF(K, 1) || CLOSE > K,BP; + +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/155663 + +> 更新时间 + +2019-07-06 16:36:04 diff --git "a/\346\227\245\345\277\227|Logger.md" "b/\346\227\245\345\277\227|Logger.md" new file mode 100644 index 00000000..74ec2ce7 --- /dev/null +++ "b/\346\227\245\345\277\227|Logger.md" @@ -0,0 +1,74 @@ + +> 策略名称 + +日志|Logger + +> 策略作者 + +fmzero + +> 策略描述 + +设置不同的level,控制日志输出等级 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|level|0|日志级别: 调试|信息|警告|错误| + + +> 源码 (javascript) + +``` javascript +//var COLOR_ERROR = "#FF0000" +//var COLOR_WARN = "#FF0000" +//var COLOR_INFO = "#0000FF" +//var COLOR_DEBUG = "#000000" +var LEVER_PATTERN = { + DEBUG: 0, + INFO: 1, + WARNING: 2, + ERROR: 3 +} +//var loggerLever = [LEVER_PATTERN.DEBUG, LEVER_PATTERN.INFO, LEVER_PATTERN.WARNING, LEVER_PATTERN.ERROR][level] +$.Error = function(msg) { + Log('[ERR] ', msg, '#FF0000') +} + +$.Warn = function(msg) { + if(level <= LEVER_PATTERN.WARNING) { + Log('[WAR] ', msg, '#FF0000') + } +} + +$.Info = function(msg) { + if(level <= LEVER_PATTERN.INFO) { + Log('[INF] ', msg, '#0000FF') + } +} + +$.Debug = function(msg) { + if(level <= LEVER_PATTERN.DEBUG) { + Log('[DBG] ', msg, '#000000') + } +} + +function main() { + $.Error('this is error') + $.Warn('this is warn') + $.Info('this is info') + $.Debug('this is debug') +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/151754 + +> 更新时间 + +2019-06-19 08:12:16 diff --git "a/796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.md" "b/\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.md" similarity index 87% rename from "796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.md" rename to "\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.md" index 66d2a991..db378b82 100644 --- "a/796\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.md" +++ "b/\346\234\237\350\264\247\345\217\215\346\211\213\345\212\240\345\200\215\347\256\227\346\263\225.md" @@ -1,7 +1,7 @@ > 策略名称 -796期货反手加倍算法 +期货反手加倍算法 > 策略作者 @@ -17,9 +17,10 @@ Zero |参数|默认值|描述| |----|----|----| -|MarginIdx|0|杠杆大小: 10|20| +|Symbol|this_week|合约名称| +|MarginLevel|10|杠杆大小| |OpType|0|开仓方向: 做多|做空| -|OpAmount|0.1|开仓数量| +|OpAmount|true|开仓数量| |OpMode|0|开仓方式: 吃单|挂单| |MaxSpace|0.5|挂单失效距离| |SlidePrice|0.1|下单滑动价(元)| @@ -28,6 +29,7 @@ Zero |ReverseRate|2|反手加仓倍数| |MaxLoss|10|最多反手次数| |ReverseMode|0|反手模式: 反仓|顺仓| +|MinStock|0.01|最小交易量| |SaveLocal|false|保存本地日志| |Interval|true|轮询间隔(秒)| @@ -36,37 +38,13 @@ Zero ``` javascript -var MarginLevel = [10,20][MarginIdx]; var FirstTradeType = [ORDER_TYPE_BUY, ORDER_TYPE_SELL][OpType]; var OrgAccount = null; var Counter = {s : 0, f: 0}; var LastProfit = 0; var AllProfit = 0; -var _IsBTC = false; var _Failed = 0; -function _N(v, precision) { - if (typeof(precision) != 'number') { - precision = 4; - } - var d = parseFloat(v.toFixed(Math.max(10, precision+5))); - s = d.toString().split("."); - if (s.length < 2 || s[1].length <= precision) { - return d; - } - - var b = Math.pow(10, precision); - return Math.floor(d*b)/b; -} - -function EnsureCall(e, method) { - var r; - while (!(r = e[method].apply(this, Array.prototype.slice.call(arguments).slice(2)))) { - Sleep(Interval); - } - return r; -} - function StripOrders(e, orderId) { var order = null; if (typeof(orderId) == 'undefined') { @@ -74,7 +52,7 @@ function StripOrders(e, orderId) { } while (true) { var dropped = 0; - var orders = EnsureCall(e, 'GetOrders'); + var orders = _C(e.GetOrders); for (var i = 0; i < orders.length; i++) { if (orders[i].Id == orderId) { order = orders[i]; @@ -107,8 +85,8 @@ function GetAccount(e, waitFrozen) { var account = null; var alreadyAlert = false; while (true) { - account = EnsureCall(e, "GetAccount"); - if (!waitFrozen || account.FrozenStocks < e.GetMinStock()) { + account = _C(e.GetAccount); + if (!waitFrozen || account.FrozenStocks < MinStock) { break; } if (!alreadyAlert) { @@ -130,7 +108,7 @@ function GetAccount(e, waitFrozen) { } function GetPosition(e, orderType) { - var positions = EnsureCall(e, 'GetPosition'); + var positions = _C(e.GetPosition); if (typeof(orderType) == 'undefined') { return positions; } @@ -144,7 +122,7 @@ function GetPosition(e, orderType) { function GetTicker(e) { while (true) { - var ticker = EnsureCall(e, 'GetTicker'); + var ticker = _C(e.GetTicker); if (ticker.Buy > 0 && ticker.Sell > 0 && ticker.Sell > ticker.Buy) { return ticker; } @@ -163,7 +141,7 @@ function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxSpace, retryDelay var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell; var isBuy = tradeType == ORDER_TYPE_BUY; while (true) { - var account = EnsureCall(e, 'GetAccount'); + var account = _C(e.GetAccount); var ticker = GetTicker(e); var tradePrice = 0; if (isBuy) { @@ -179,7 +157,7 @@ function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxSpace, retryDelay } dealAmount = _N((nowPosition ? nowPosition.Amount : 0) - (initPosition ? initPosition.Amount : 0), 6); var doAmount = Math.min(tradeAmount - dealAmount, account.Stocks * MarginLevel, 4); - if (doAmount < e.GetMinStock()) { + if (doAmount < MinStock) { break; } prePrice = tradePrice; @@ -207,7 +185,7 @@ function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxSpace, retryDelay function coverFutures(e, orderType) { var coverAmount = 0; while (true) { - var positions = EnsureCall(e, 'GetPosition'); + var positions = _C(e.GetPosition); var ticker = GetTicker(e); var found = 0; for (var i = 0; i < positions.length; i++) { @@ -319,7 +297,7 @@ function loop(pos) { } return pos; } else { - var orders = EnsureCall(exchange, "GetOrders"); + var orders = _C(exchange.GetOrders); if (orders.length == 0) { Counter.s++; var account = GetAccount(exchange, true); @@ -337,8 +315,8 @@ function onexit() { } function main() { - if (exchange.GetName().indexOf("796") == -1) { - throw "只支持796期货, 现货暂不支持"; + if (exchange.GetName().indexOf("Futures") == -1) { + throw "只支持期货, 现货暂不支持"; } EnableLogLocal(SaveLocal); if (exchange.GetRate() != 1) { @@ -350,10 +328,10 @@ function main() { StopLoss /= 100; var eName = exchange.GetName(); - - _IsBTC = exchange.GetCurrency().indexOf("BTC") != -1; - - exchange.SetContractType("week"); + if (eName == "Futures_CTP") { + throw "暂只支持数字货币期货" + } + exchange.SetContractType(Symbol); exchange.SetMarginLevel(MarginLevel); Interval *= 1000; SetErrorFilter("502:|503:|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF"); @@ -362,7 +340,7 @@ function main() { LogStatus("启动成功"); var pos = null; var positions = GetPosition(exchange); - if (positions.length == 1 && positions[0].MarginLevel == MarginLevel) { + if (positions.length == 1) { pos = positions[0]; Log("发现一个仓位, 已经自动恢复进度"); } else if (positions.length > 1) { @@ -378,6 +356,7 @@ function main() { Sleep(Interval); } } + ``` > 策略出处 @@ -386,4 +365,4 @@ https://www.fmz.com/strategy/3648 > 更新时间 -2015-02-04 13:49:31 +2019-06-11 09:15:37 diff --git "a/\346\257\217\346\227\245\345\270\202\344\273\267\345\256\232\346\212\225.md" "b/\346\257\217\346\227\245\345\270\202\344\273\267\345\256\232\346\212\225.md" new file mode 100644 index 00000000..8f3fb92b --- /dev/null +++ "b/\346\257\217\346\227\245\345\270\202\344\273\267\345\256\232\346\212\225.md" @@ -0,0 +1,60 @@ + +> 策略名称 + +每日市价定投 + +> 策略作者 + +cdxy + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|singleInvestAmount|true|市价买入| + + +> 源码 (javascript) + +``` javascript + + +function main() { + Log(exchange.GetAccount()); + + + //最近一次投资的日期 + var lastInvestDate = ''; + + while (true) { + //每次轮询,间隔时间为60秒 + Sleep(60 * 1000); + + //如果当前日期和最近一次投资日期相同,说明当天已经投过了,跳过 + var now = new Date(); + var date = now.toISOString().slice(0,10); + if (date == lastInvestDate) { + continue; + } + + lastInvestDate = date; + Log("日期: " + date); + + + exchange.Buy(-1, singleInvestAmount); + } +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/151259 + +> 更新时间 + +2019-06-07 16:26:19 diff --git "a/\346\267\261\345\272\246\345\201\232\345\270\202.md" "b/\346\267\261\345\272\246\345\201\232\345\270\202.md" new file mode 100644 index 00000000..4945665b --- /dev/null +++ "b/\346\267\261\345\272\246\345\201\232\345\270\202.md" @@ -0,0 +1,131 @@ + +> 策略名称 + +深度做市 + +> 策略作者 + +3piggy + +> 策略描述 + +给交易所跑的策略,大致的策略是,获取当前价格,同时挂出买卖单增加深度,可以复制别的行情,可以参考别的趋势。 + + + +> 源码 (python) + +``` python +# -*- coding: UTF-8 -*- +import requests +import time +import random +import hashlib +import sys +import threading +from openapi import * + +symbol = sys.argv[1] +gap= float(sys.argv[2]) #密度/价差 +baseamount = float(sys.argv[3]) +basebuy = float(sys.argv[4]) +amount_add = float(sys.argv[5]) #挂单增量 数字型(number) +amount_add2 = float(sys.argv[6]) #挂单增量 数字型(number) +longperoidlimit = int(sys.argv[7]) +bigbase = float(sys.argv[8]) #大单基准量 +orderlimit = int(sys.argv[9]) #总单量 +api_key = sys.argv[10] +secret_key = sys.argv[11] + +shortperoidlimit = 3 #高频单量 + +pre_short_id = [] #高平id标记 +pre_long_id = [] #低频id标记 +pre_big_id = 0 + +requests.packages.urllib3.disable_warnings() + +def GetTicker(): + + +def GetDepth(): + +def GetSign(sign_str): + + +def GetOrders(): + +def create_order(side,price,amount): + + +def CancelOrder(order_id): + +def Buy(price,amount): + + +def Sell(price,amount): + +def GetRecords(symbol,period): + + +def GetPrecision(): + +def getrr(): + + +def ordersend_shortperoid(): + + + +def ordersend_longperoid(): + + +def send_big_order(): + + +def cancel(): + + + + +if __name__ == '__main__': + precision = GetPrecision() + print(precision) + i = 0 + for x in precision: + if precision[i]['symbol'] == symbol: + pricedot = precision[i]['price_precision'] + amountdot = precision[i]['amount_precision'] + i += 1 + pricegap = max(gap,pow(10,-pricedot)) + threading_list = [ordersend_shortperoid,ordersend_longperoid,send_big_order,cancel] + threadingList = [] + threadingDict = {} + for x in threading_list: + th = threading.Thread(target=x) + threadingList.append(th) + threadingDict[th.__dict__['_name']] = th.__dict__['_target'] + th.start() + + while True: + try: + time.sleep(200) + for i in threadingList: + if i.is_alive() is False: + threadingList.remove(i) + result = threadingDict.pop(i.name) + th = threading.Thread(target=result) + threadingList.append(th) + threadingDict[th.__dict__['_name']] = th.__dict__['_target'] + th.start() + except Exception as e: + print('check error',e) +``` + +> 策略出处 + +https://www.fmz.com/strategy/146238 + +> 更新时间 + +2019-05-02 21:02:21 diff --git "a/\347\201\253\345\270\201\346\234\237\350\264\247\345\270\201\345\270\201\350\264\246\346\210\267\351\227\264\350\265\204\351\207\221\345\210\222\350\275\254\350\214\203\344\276\213.md" "b/\347\201\253\345\270\201\346\234\237\350\264\247\345\270\201\345\270\201\350\264\246\346\210\267\351\227\264\350\265\204\351\207\221\345\210\222\350\275\254\350\214\203\344\276\213.md" new file mode 100644 index 00000000..e8bbba84 --- /dev/null +++ "b/\347\201\253\345\270\201\346\234\237\350\264\247\345\270\201\345\270\201\350\264\246\346\210\267\351\227\264\350\265\204\351\207\221\345\210\222\350\275\254\350\214\203\344\276\213.md" @@ -0,0 +1,41 @@ + +> 策略名称 + +火币期货币币账户间资金划转范例 + +> 策略作者 + +小小梦 + + + + + +> 源码 (javascript) + +``` javascript +function main() { + // API 接口描述: + // https://api.huobi.pro + // POST /v1/futures/transfer + // params currency e.g. btc + // amount + // type futures-to-pro + + Log(exchange.GetAccount()) + var ret = exchange.IO("api", "POST", "/v1/futures/transfer", "currency=ltc&amount=0.1&type=pro-to-futures") // 测试的是LTC , 币币转期货 + Log("ret", ret) + + /* ret + ret {"status":"ok","data":25669845} + */ +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/148532 + +> 更新时间 + +2019-05-20 18:19:53 diff --git "a/\347\210\254\345\217\226\345\270\201\345\256\211\345\205\254\345\221\212\350\207\252\345\212\250\345\207\272\345\224\256\345\260\206\350\246\201\344\270\213\346\236\266\345\270\201|crawl Binance announcements and sell Delist coin.md" "b/\347\210\254\345\217\226\345\270\201\345\256\211\345\205\254\345\221\212\350\207\252\345\212\250\345\207\272\345\224\256\345\260\206\350\246\201\344\270\213\346\236\266\345\270\201|crawl Binance announcements and sell Delist coin.md" index 5c7c1072..ec8e0ac7 100644 --- "a/\347\210\254\345\217\226\345\270\201\345\256\211\345\205\254\345\221\212\350\207\252\345\212\250\345\207\272\345\224\256\345\260\206\350\246\201\344\270\213\346\236\266\345\270\201|crawl Binance announcements and sell Delist coin.md" +++ "b/\347\210\254\345\217\226\345\270\201\345\256\211\345\205\254\345\221\212\350\207\252\345\212\250\345\207\272\345\224\256\345\260\206\350\246\201\344\270\213\346\236\266\345\270\201|crawl Binance announcements and sell Delist coin.md" @@ -7,7 +7,12 @@ botvsing +> 策略描述 +爬取币安公告页面,观察近两次的下架信息,具体格式为“Binance将下架CLOAK、MOD、SALT、SUB、WINGS”、“Binance将下架BCN,CHAT,ICN,TRIG”。 + +爬虫将以“将下架”为关键词爬取新的下架公告,当然不排除币安更改公告格式,可参考此策略加以完善。由于爬虫任务过于简单,将用简单的JavaScript编写。爬取到下架币后,将检查账户信息,如果存在下架币,以较低的价格全部卖出,如果存在未完成订单,先撤销。直到将所持有的下架币完全卖出。 +具体分析,参考帖子:https://zhuanlan.zhihu.com/p/57012933 @@ -96,4 +101,4 @@ https://www.fmz.com/strategy/137450 > 更新时间 -2019-03-07 11:31:36 +2019-07-03 16:16:39 diff --git "a/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.md" "b/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.md" index 253177ac..76a9f4df 100644 --- "a/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.md" +++ "b/\347\237\245\344\271\216\344\270\223\346\240\217 \345\256\236\344\276\213\346\226\207\347\253\240\347\255\226\347\225\245.md" @@ -5,20 +5,12 @@ > 策略作者 -yilidalei +小小梦 > 策略描述 -测试JS - -> 策略参数 - - +知乎专栏 实例文章策略 -|参数|默认值|描述| -|----|----|----| -|RatioA|0.05|调整系数| -|RatioB|0.1|平仓加仓偏离系数| > 源码 (javascript) @@ -32,127 +24,15 @@ var Interval = 500; // 轮询时间 , 毫秒 , 500 毫秒 = 0.5 var Balance_Unit = 0; var ContractTypeInfo = null; // 合约信息 var initAccount = null; // 初始账户信息 -var nowAccount = null; // 当前账户信息 var LONG = 1; var SHORT = 2; -var IDLE = 0; -var State = IDLE; -var EnterPrice = null; // 入场价 -var FloatProfitStop = null; // 浮动止损 -var LossStop = null; // 止损线 -var manager = null; // 用于引用《商品期货交易类库》 导出函数 生成的对象。 -var MaxAdds = 9; -var Adds = 0; // 功能函数 (待填写) function loop(){ // 主循环函数 - /*入场:以前一日收盘价上下0.5*ATR为上下轨,突破上轨做多一份资金,突破下轨做空一份资金。*/ - var records = exchange.GetRecords(PERIOD_D1); - if(!records || records.length < 21){ - return; - } - var atr = GetATR(records); - if(atr.length < 2){ - return; - } - var Bar = records[records.length - 1]; - var lastDayClose = records[records.length - 2].Close; - var lastDayATR = atr[atr.length - 2]; - var upTrack = lastDayClose + lastDayATR * 0.5; - var downTrack = lastDayClose - lastDayATR * 0.5; - - // 开仓 - if(State == IDLE && Bar.Close > upTrack){ // LONG - // Log("触发!上轨:", upTrack, "当前Bar最新收盘价(Close)", Bar.Close, "lastDayATR:", lastDayATR, "lastDayClose:", lastDayClose); // 测试代码 - // throw "暂停!"; // 测试代码 - nowAccount = CheckBalance_Unit(LONG); - var tradeInfoLong = manager.OpenLong(ContractType, _N(Balance_Unit / (ContractTypeInfo.VolumeMultiple * Bar.Close * ContractTypeInfo.LongMarginRatio), 0)); // 商品期货交易类库 导出函数,处理交易细节。 - if(tradeInfoLong){ - EnterPrice = tradeInfoLong.price; - CalcFPS_LS(EnterPrice, LONG); - State = LONG; - } - }else if(State == IDLE && Bar.Close < downTrack){ // SHORT - // Log("触发!下轨:", downTrack, "当前Bar最新收盘价(Close)", Bar.Close, "lastDayATR:", lastDayATR, "lastDayClose:", lastDayClose); // 测试代码 - // throw "暂停!"; // 测试代码 - nowAccount = CheckBalance_Unit(SHORT); - var tradeInfoShort = manager.OpenShort(ContractType, _N(Balance_Unit / (ContractTypeInfo.VolumeMultiple * Bar.Close * ContractTypeInfo.ShortMarginRatio), 0)); // 商品期货交易类库 导出函数,处理交易细节。 - if(tradeInfoShort){ - EnterPrice = tradeInfoShort.price; - CalcFPS_LS(EnterPrice, SHORT); - State = SHORT; - } - } - - // 加仓 - if(State == LONG && Bar.Close > FloatProfitStop && Adds < MaxAdds){ // 多仓状态 触发浮动止盈线 - nowAccount = CheckBalance_Unit(LONG); - var tradeInfoLong = manager.OpenLong(ContractType, _N(Balance_Unit / (ContractTypeInfo.VolumeMultiple * Bar.Close * ContractTypeInfo.LongMarginRatio), 0)); // 商品期货交易类库 导出函数,处理交易细节。 - // 移动中线 - if(tradeInfoLong){ - Adds++; - EnterPrice = tradeInfoLong.price; - CalcFPS_LS(EnterPrice, LONG); - } - }else if(State == SHORT && Bar.Close < FloatProfitStop && Adds < MaxAdds){ // 空仓状态 触发浮动止盈线 - nowAccount = CheckBalance_Unit(SHORT); - var tradeInfoShort = manager.OpenShort(ContractType, _N(Balance_Unit / (ContractTypeInfo.VolumeMultiple * Bar.Close * ContractTypeInfo.ShortMarginRatio), 0)); // 商品期货交易类库 导出函数,处理交易细节。 - // 移动中线 - if(tradeInfoShort){ - Adds++; - EnterPrice = tradeInfoShort.price; - CalcFPS_LS(EnterPrice, SHORT); - } - } - - // 平仓 - if(State == LONG && Bar.Close < LossStop){ // 平多 - manager.Cover(ContractType); - Adds = 0; - State = IDLE; - nowAccount = _C(exchange.GetAccount); - LogProfit(nowAccount.Balance - initAccount.Balance); - }else if(State == SHORT && Bar.Close > LossStop){ // 平空 - manager.Cover(ContractType); - Adds = 0; - State = IDLE; - nowAccount = _C(exchange.GetAccount); - LogProfit(nowAccount.Balance - initAccount.Balance); - } - -} - -function CalcFPS_LS(Para_EnterPrice, Direction){ // 计算 FloatProfitStop : FPS , LossStop : LS - // 以做多为例:设置当前初始线(入场价),按着一定规则(如:止损线=0.8 * 入场价)浮动止盈线和止损线,可以设置,(浮动止盈线-中线)= 1.2(中线-止损线) - /* - if(Direction == LONG){ - LossStop = 0.8 * Para_EnterPrice; - FloatProfitStop = 1.2 * (Para_EnterPrice - (0.8 * Para_EnterPrice)) + Para_EnterPrice; - }else if(Direction == SHORT){ - LossStop = 1.2 * Para_EnterPrice; - FloatProfitStop = Para_EnterPrice - 1.2 * (1.2 * Para_EnterPrice - Para_EnterPrice); - }else{ - throw "错误的Direction参数:" + Direction; - } - */ - var array = [0, RatioA * (10 - Adds) / 20, RatioA * (10 - Adds) / 20, RatioA * (10 - Adds) / 20, RatioA * (10 - Adds) / 20, RatioA * (10 - Adds) / 20]; // ceshi - if(Direction == LONG){ - LossStop = (1 - RatioA + array[Adds]) * Para_EnterPrice; // RatioA : 0.05 - FloatProfitStop = (1 + RatioB) * (Para_EnterPrice - ((1 - RatioA) * Para_EnterPrice)) + Para_EnterPrice; - }else if(Direction == SHORT){ - LossStop = (1 + RatioA - array[Adds]) * Para_EnterPrice; - FloatProfitStop = Para_EnterPrice - (1 + RatioB) * ((1 + RatioA) * Para_EnterPrice - Para_EnterPrice); - }else{ - throw "错误的Direction参数:" + Direction; - } -} - -function GetATR(records){ // 默认为 records 参数是有效值,传入,即: 不为null ,Bar 长度足够。 - var atr = TA.ATR(records); - return atr; + CheckBalance_Unit(LONG); } function CheckBalance_Unit(Direction){ - ContractTypeInfo = _C(exchange.SetContractType, ContractType); + ContractTypeInfo = exchange.SetContractType(ContractType); Log("标的物合约信息:", ContractTypeInfo); Balance_Unit = _N(initAccount.Balance * UsedRatio / 10, 2); Log("账户信息:", initAccount, "资金分配 10份,一份为:", Balance_Unit); @@ -160,9 +40,9 @@ function CheckBalance_Unit(Direction){ var ticker = _C(exchange.GetTicker); var OneContractMargin = ContractTypeInfo.VolumeMultiple * ticker.Last * (Direction == LONG ? ContractTypeInfo.LongMarginRatio : ContractTypeInfo.ShortMarginRatio); if(Balance_Unit < OneContractMargin * 1.2){ - throw "最新价格:" + ticker.Last + "调整系数1.2 " + " ,资金可用部分的10分之一 不足 开" + (Direction == LONG ? "多" : "空") + "1手合约," + "1手合约需:" + OneContractMargin; + throw "最新价格:" + ticker.Last + "调整系数1.2" + " ,资金可用部分的10分之一 不足 开" + (Direction == LONG ? "多" : "空") + "1手合约," + "1手合约需:" + OneContractMargin; }else{ - Log("最新价格:" + ticker.Last + "调整系数1.2 " + " 1份资金 可开:", Direction == LONG ? "多" : "空", _N(Balance_Unit / OneContractMargin, 0)); + Log("最新价格:" + ticker.Last + "调整系数1.2" + "1份资金 可开:", Direction == LONG ? "多" : "空", _N(Balance_Unit / OneContractMargin, 0)); } var nowAccount = _C(exchange.GetAccount); if(nowAccount.Balance < Balance_Unit){ @@ -170,16 +50,11 @@ function CheckBalance_Unit(Direction){ }else if(nowAccount.Balance < OneContractMargin * 1.2){ throw "资金不足:" + JSON.stringify(nowAccount) + ", 系数1.2,1手合约保证金:" + OneContractMargin; } - if(nowAccount.Balance - initAccount.Balance * (1 - UsedRatio) < OneContractMargin * 1.2){ - throw "资金可用部分不足一手保证金金额。可用部分:" + (nowAccount.Balance - initAccount.Balance * (1 - UsedRatio)) + ",1手保证金" + OneContractMargin + ",系数:1.2"; - } - return nowAccount; } // 入口函数 main function main(){ // 程序的初始化工作 (待填写) - manager = $.NewPositionManager(); // 《商品期货交易类库》导出函数 ,返回一个控制对象。 while(true){ if(exchange.IO("status") == true && (initAccount = exchange.GetAccount()) !== null){ break; @@ -215,8 +90,8 @@ function onexit(){ > 策略出处 -https://www.fmz.com/strategy/40266 +https://www.fmz.com/strategy/39586 > 更新时间 -2017-05-09 15:00:16 +2017-05-12 18:22:01 diff --git "a/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.md" "b/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.md" index 62ed9ec6..608c97e1 100644 --- "a/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.md" +++ "b/\347\255\226\347\225\245\346\241\206\346\236\266\346\250\241\346\235\277.md" @@ -22,7 +22,7 @@ var TASK_COVER = 5; */ 使用说明: -https://www.botvs.com/bbs-topic/634 +https://www.fmz.com/bbs-topic/634 > 策略参数 diff --git "a/\347\256\200\345\215\225\345\233\272\345\256\232\344\273\267\346\240\274\346\255\242\346\215\237\346\234\272\345\231\250\344\272\272|Stop Loss Below Fixed Price.md" "b/\347\256\200\345\215\225\345\233\272\345\256\232\344\273\267\346\240\274\346\255\242\346\215\237\346\234\272\345\231\250\344\272\272|Stop Loss Below Fixed Price.md" index 95f6bcf2..c51020bb 100644 --- "a/\347\256\200\345\215\225\345\233\272\345\256\232\344\273\267\346\240\274\346\255\242\346\215\237\346\234\272\345\231\250\344\272\272|Stop Loss Below Fixed Price.md" +++ "b/\347\256\200\345\215\225\345\233\272\345\256\232\344\273\267\346\240\274\346\255\242\346\215\237\346\234\272\345\231\250\344\272\272|Stop Loss Below Fixed Price.md" @@ -7,7 +7,15 @@ botvsing +> 策略描述 +一个简单的固定价格止损机器人,可以帮助你止损。也是个很好的入门数字货币量化交易的策略。 + +### 参数: + +StopPrice:Fixed price to stop loss + +Intervel: Intervel(second) of checking coin price > 策略参数 @@ -79,4 +87,4 @@ https://www.fmz.com/strategy/121081 > 更新时间 -2018-10-16 10:55:52 +2019-07-03 16:41:50 diff --git "a/\347\256\200\345\215\225\345\235\207\347\272\277\347\255\226\347\225\245|Moving Average Bot 30 lines.md" "b/\347\256\200\345\215\225\345\235\207\347\272\277\347\255\226\347\225\245|Moving Average Bot 30 lines.md" index 91549a77..62fff3bf 100644 --- "a/\347\256\200\345\215\225\345\235\207\347\272\277\347\255\226\347\225\245|Moving Average Bot 30 lines.md" +++ "b/\347\256\200\345\215\225\345\235\207\347\272\277\347\255\226\347\225\245|Moving Average Bot 30 lines.md" @@ -37,9 +37,6 @@ https://dn-filebox.qbox.me/fb4d0c7d773ca83e9d0230927705d419dc0bbeaa.png > 源码 (javascript) ``` javascript -if (exchange.GetName() != 'BotVS'){ - throw 'only support BotVS'; -} function main() { Log('started'); var initAccount = _C(exchange.GetAccount); @@ -81,4 +78,4 @@ https://www.fmz.com/strategy/103070 > 更新时间 -2018-10-16 10:59:06 +2019-04-13 13:48:29 diff --git "a/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.md" "b/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.md" index 5eeea7b5..fa9264fb 100644 --- "a/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.md" +++ "b/\350\256\260\345\275\225\345\207\200\350\265\204\344\272\247\345\217\230\345\212\250\346\203\205\345\206\2652.0.md" @@ -10,7 +10,7 @@ > 策略描述 说明 -- 本策略由https://www.botvs.com/strategy/5349 演变而来,主要是计算在含有借币的情况下,账户策略的净收入变动情况 +- 本策略由https://www.fmz.com/strategy/5349 演变而来,主要是计算在含有借币的情况下,账户策略的净收入变动情况 - 净资产变动: 账户净资产变动情况 - 状态信息栏会显示如下信息: - 初始净资产 / 初始净钱 / 初始净币: 显示最开始时的净资产,净钱币情况 diff --git "a/\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" "b/\350\256\276\345\256\232\346\257\224\347\211\271\345\270\201\344\273\267\346\240\274\345\271\266\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" similarity index 80% rename from "\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" rename to "\350\256\276\345\256\232\346\257\224\347\211\271\345\270\201\344\273\267\346\240\274\345\271\266\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" index 6f1406db..8dd5d148 100644 --- "a/\350\256\276\345\256\232\344\273\267\346\240\274\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" +++ "b/\350\256\276\345\256\232\346\257\224\347\211\271\345\270\201\344\273\267\346\240\274\345\271\266\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" @@ -1,13 +1,18 @@ > 策略名称 -设定价格微信推送(教学)| Push the price information to telegram +设定比特币价格并微信推送(教学)| Push the price information to telegram > 策略作者 botvsing +> 策略描述 +教学策略: +当币价高于或低于设定值后,自动推送一条消息到微信。可设定最小推送间隔。 + +When the price of the currency is higher or lower than the set value, a message is automatically pushed to WeChat or telegram. The minimum push interval can be set. > 策略参数 @@ -53,4 +58,4 @@ https://www.fmz.com/strategy/125482 > 更新时间 -2019-04-09 17:06:16 +2019-07-03 16:18:51 diff --git "a/\350\277\220\347\224\250\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\214\207\346\240\207\345\234\250\346\225\260\345\255\227\350\264\247\345\270\201\344\270\255\351\207\217\345\214\226\344\272\244\346\230\223\357\274\214\351\231\204\345\270\246My\350\257\255\350\250\200\347\255\226\347\225\245\346\272\220\347\240\201.md" "b/\350\277\220\347\224\250\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\214\207\346\240\207\345\234\250\346\225\260\345\255\227\350\264\247\345\270\201\344\270\255\351\207\217\345\214\226\344\272\244\346\230\223\357\274\214\351\231\204\345\270\246My\350\257\255\350\250\200\347\255\226\347\225\245\346\272\220\347\240\201.md" new file mode 100644 index 00000000..03c424e4 --- /dev/null +++ "b/\350\277\220\347\224\250\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\214\207\346\240\207\345\234\250\346\225\260\345\255\227\350\264\247\345\270\201\344\270\255\351\207\217\345\214\226\344\272\244\346\230\223\357\274\214\351\231\204\345\270\246My\350\257\255\350\250\200\347\255\226\347\225\245\346\272\220\347\240\201.md" @@ -0,0 +1,139 @@ + +> 策略名称 + +运用阿隆(Aroon)指标在数字货币中量化交易,附带My语言策略源码 + +> 策略作者 + +Hukybo + +> 策略描述 + +# 1、阿隆指标简介 + +本篇文章根据[阿隆(Aroon)技术指标在量化交易中的应用](https://www.fmz.com/strategy/154547)中的策略改编为数字货币,并且基于My语言。在技术分析中阿隆(Aroon)是一个很独特的技术指标,“Aroon”一词来自梵文,寓意为“黎明曙光”。它不像MA、MACD、KDJ那样广为人所熟悉,它推出的时间更晚,直到1995年才被图莎尔·钱德(Tushar Chande)发明出来,作者还发明了钱德动量摆动指标(CMO)和日内动量指数(IMI)。如果说一个技术指标知道的人越多,使用的人也越多,那么其赚钱能力也越低,那么相对新颖的阿隆指标则恰恰相反,站在这个角度看这是一个不错的选择。 + +# 2、图表中的阿隆指标 + +阿隆指标通过计算当前K线距离前最高价和最低价之间的K线数量,来帮助交易者预测价格走势与趋势区域的相对位置关系变化。它有两部分组成,即:阿隆上线(AroonUp)和阿隆下线(AroonDown),这两条线在0~100之间上下移动,虽然命名为上线和下线,但从图表上看并不像BOLL指标那样是真正意义上的上线和下线。如下图就是阿隆指标: + ![IMG](https://www.fmz.com/upload/asset/38df067f317f4f5cce2b.png) + +# 3、阿隆指标的计算方法 + +阿隆指标要求首先要设置一个时间周期参数,就像设置均线周期参数一样,在传统行情软件中,这个周期数是14,当然这个周期参数并不是固定的,你还可以设置为10或者50等等。为了方便理解,暂且把这个时间周期参数定义为:N。确定N之后,我们就可以计算出阿隆上线(AroonUp)和阿隆下线(AroonDown),具体的计算公式如下: + +- 阿隆上线(AroonUp) = [ ( 设置的周期参数 - 最高价后的周期数 ) / 计算的周期数 ] * 100 +- 阿隆下线(AroonDown) = [ ( 设置的周期参数 - 最低价后的周期数 ) / 计算的周期数 ] * 100 + +从这个公式中,我们就能大致看出,阿隆指标的思想。那就是:有多少个周期,价格在近期高 / 低点之下,辅助预测当前趋势是否会延续,同时衡量当前趋势的强弱。如果我们把这个指标归类的话,很明显它是属于趋势跟踪类型。但是与其他趋势跟踪型指标不同的是,它更重视时间而不是价格。 + +# 4、如何使用阿隆指标 + +阿隆上线(AroonUp)和阿隆下线(AroonDown)反映的是当前时间与之前最高价或最低价的远近,如果时间越近值就越大,如果时间越远值就越小。并且当两条线发生交叉就预示着价格方向可能会发生改变,如果AroonUp在AroonDown之上说明价格处于上涨趋势,未来价格可能会进一步上涨;如果AroonDown在AroonUp之上说明价格处于下跌趋势,未来价格可能会进一步下跌。 + +同时我们还可以设置几个固定的值,来精确入场时机。我们知道阿隆指标是一直在0~100之间上下运行,那么在市场处于上涨趋势,也就是AroonUp在AroonDown之上时,当AroonUp大于50,说明市场上涨的趋势已经形成,未来价格可能会继续上涨;当AroonUp下穿50时,说明价格上涨的动力正在减弱,未来价格可能会震荡和下跌。 + +反之在市场处于下跌趋势,也就是AroonDown在AroonUp之上时,当AroonDown大于50,说明市场下跌趋势已经形成,未来价格可能会继续下跌;当AroonDown下穿50时,说明价格下跌的动力正在减弱,未来价格可能会震荡和上涨。那么根据上面两段理论,我们可以把买卖条件罗列为: + +- 当 AroonUp大于AroonDown,并且AroonUp大于50,多头开仓; +- 当 AroonUp小于AroonDown,或者AroonUp小于50,多头平仓; +- 当 AroonDown大于AroonUp,并且AroonDown大于50,空头开仓; +- 当 AroonDown小于AroonUp,或者AroonDown小于50,空头平仓; + +# 5、基于阿隆指标构建交易策略 + +理清交易逻辑后,我们就可以用代码去实现了,本篇我们改用My语言,品种则换成比特币。动手能力强的小伙伴,也可以把代码翻译成JavaScript语言。OK,话不多说,依次打开:fmz.com > 登录 > 控制中心 > 策略库 > 新建策略,开始编写策略,注意看下面代码中的注释。 + +**第一步:计算阿隆指标** +注意!在左上角选择编程语言为:`My语言`。 +``` +AROONUP := ((N - HHVBARS(H, N)) / N) * 100; // 阿隆指标上线 +AROONDOWN := ((N - LLVBARS(L, N)) / N) * 100; // 阿隆指标下线 +``` + +**第二步:计算交易条件并下单** +``` +AROONUP := ((N - HHVBARS(H, N)) / N) * 100; // 阿隆指标上线 +AROONDOWN := ((N - LLVBARS(L, N)) / N) * 100; // 阿隆指标下线 +AROONUP > AROONDOWN && AROONUP > BKV, BK; // 多头开仓 +AROONDOWN > AROONUP && AROONDOWN > SKV, SK; // 空头开仓 +AROONUP < AROONDOWN || AROONUP < SPV, SP; // 多头平台 +AROONDOWN < AROONUP || AROONDOWN < BPV, BP; // 空头平台 +``` + +**第三步:设置策略信号过滤方式** +``` +AROONUP := ((N - HHVBARS(H, N)) / N) * 100; // 阿隆指标上线 +AROONDOWN := ((N - LLVBARS(L, N)) / N) * 100; // 阿隆指标下线 +AROONUP > AROONDOWN && AROONUP > BKV, BK; // 多头开仓 +AROONDOWN > AROONUP && AROONDOWN > SKV, SK; // 空头开仓 +AROONUP < AROONDOWN || AROONUP < SPV, SP; // 多头平台 +AROONDOWN < AROONUP || AROONDOWN < BPV, BP; // 空头平台 +AUTOFILTER; +``` + +[点击复制完整策略源码](https://www.fmz.com/strategy/155582) + +# 6、策略回测 + +为了更接近真实的交易环境,我们在回测时采用开平仓各2跳的滑点来压力测试,测试环境如下: + +- 行情品种:BTC +- 交易品种:BTC +- 时间:2019年01月01日~2019年07月05日 +- 周期:日线 +- 滑点:开平仓各2跳 + +**测试环境** + ![IMG](https://www.fmz.com/upload/asset/3a3b8ebd1d15f0dad5ff.png) +**收益明细** + ![IMG](https://www.fmz.com/upload/asset/399bd1e8a5207430601c.png) +**资金曲线** + ![IMG](https://www.fmz.com/upload/asset/39211cdf3a96eb811657.png) +从上面的回测结果看,策略在市场行情走势流畅的时候表现很好,无论是在上涨或下跌中,阿隆指标可以完整的跟踪到行情。资金曲线也整体走势向上,并没有出现较大幅度的回撤。但是在震荡行情中,特别是连续的震荡行情中,出现了局部回撤。 + +# 7、阿隆指标的优缺点 + +- 优点:阿隆指标可以判断趋势行情的状态,兼顾发现市场趋势行情以及判断价格转向的能力,帮助交易者提高资金的使用率,这个优势震荡行情中尤为重要。 +- 缺点:阿隆指标只是趋势跟踪系列指标中的一种,同样也有趋势跟踪指标的缺点。并且它只判断指定时间最高价或最低价的周期数,但有时候最高价或最低价在整个行情走势中会有偶然性,这个偶然性会干扰阿隆指标本身,造成虚假信号。 + +# 8、总结 + +在策略中我们固定了一部分参数,如:aroonUp或aroonDown大于小于50,造成策略的滞后性,很多情况下是行情上涨或下跌一段时间才开平仓买卖。这样虽然提高了胜率,减少了最大回撤率,但也错过了很多收益,这也印证了盈亏同源的道理。有兴趣的朋友可以深入研究一下,并加以改进。 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N|30|阿隆指标参数周期| +|Q|50|触发临界点| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2019-01-01 00:00:00 +end: 2019-07-05 00:00:00 +period: 1d +exchanges: [{"eid":"OKEX","currency":"BTC_USDT","balance":10000,"stocks":3}] +*) + +AROONUP := ((N - HHVBARS(H, N)) / N) * 100; // 阿隆指标上线 +AROONDOWN := ((N - LLVBARS(L, N)) / N) * 100; // 阿隆指标下线 +AROONUP > AROONDOWN && AROONUP > Q, BK; // 多头开仓 +AROONDOWN > AROONUP && AROONDOWN > Q, SK; // 空头开仓 +AROONUP < AROONDOWN || AROONUP < Q, SP; // 多头平台 +AROONDOWN < AROONUP || AROONDOWN < Q, BP; // 空头平台 +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/155582 + +> 更新时间 + +2019-07-06 09:08:52 diff --git "a/\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\212\200\346\234\257\346\214\207\346\240\207\345\234\250\345\225\206\345\223\201\346\234\237\350\264\247\344\270\255\347\232\204\345\272\224\347\224\250.md" "b/\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\212\200\346\234\257\346\214\207\346\240\207\345\234\250\345\225\206\345\223\201\346\234\237\350\264\247\344\270\255\347\232\204\345\272\224\347\224\250.md" new file mode 100644 index 00000000..9ac7bb1d --- /dev/null +++ "b/\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\212\200\346\234\257\346\214\207\346\240\207\345\234\250\345\225\206\345\223\201\346\234\237\350\264\247\344\270\255\347\232\204\345\272\224\347\224\250.md" @@ -0,0 +1,196 @@ + +> 策略名称 + +阿隆(Aroon)技术指标在商品期货中的应用 + +> 策略作者 + +Hukybo + +> 策略描述 + +# 1、阿隆指标简介 + +在技术分析中阿隆(Aroon)是一个很独特的技术指标,“Aroon”一词来自梵文,寓意为“黎明曙光”。它不像MA、MACD、KDJ那样广为人所熟悉,它推出的时间更晚,直到1995年才被图莎尔·钱德(Tushar Chande)发明出来,作者还发明了钱德动量摆动指标(CMO)和日内动量指数(IMI)。如果说一个技术指标知道的人越多,使用的人也越多,那么其赚钱能力也越低,那么相对新颖的阿隆指标则恰恰相反,站在这个角度看这是一个不错的选择。 + +# 2、图表中的阿隆指标 + +阿隆指标通过计算当前K线距离前最高价和最低价之间的K线数量,来帮助交易者预测价格走势与趋势区域的相对位置关系变化。它有两部分组成,即:阿隆上线(AroonUp)和阿隆下线(AroonDown),这两条线在0~100之间上下移动,虽然命名为上线和下线,但从图表上看并不像BOLL指标那样是真正意义上的上线和下线。如下图就是阿隆指标: + ![IMG](https://www.fmz.com/upload/asset/395eac8a5478d8736104.png) + +# 3、阿隆指标的计算方法 + +阿隆指标要求首先要设置一个时间周期参数,就像设置均线周期参数一样,在传统行情软件中,这个周期数是14,当然这个周期参数并不是固定的,你还可以设置为10或者50等等。为了方便理解,暂且把这个时间周期参数定义为:N。确定N之后,我们就可以计算出阿隆上线(AroonUp)和阿隆下线(AroonDown),具体的计算公式如下: + +- 阿隆上线(AroonUp) = [ ( 设置的周期参数 - 最高价后的周期数 ) / 计算的周期数 ] * 100 +- 阿隆下线(AroonDown) = [ ( 设置的周期参数 - 最低价后的周期数 ) / 计算的周期数 ] * 100 + +从这个公式中,我们就能大致看出,阿隆指标的思想。那就是:有多少个周期,价格在近期高 / 低点之下,辅助预测当前趋势是否会延续,同时衡量当前趋势的强弱。如果我们把这个指标归类的话,很明显它是属于趋势跟踪类型。但是与其他趋势跟踪型指标不同的是,它更重视时间而不是价格。 + +# 4、如何使用阿隆指标 + +阿隆上线(AroonUp)和阿隆下线(AroonDown)反映的是当前时间与之前最高价或最低价的远近,如果时间越近值就越大,如果时间越远值就越小。并且当两条线发生交叉就预示着价格方向可能会发生改变,如果AroonUp在AroonDown之上说明价格处于上涨趋势,未来价格可能会进一步上涨;如果AroonDown在AroonUp之上说明价格处于下跌趋势,未来价格可能会进一步下跌。 + +同时我们还可以设置几个固定的值,来精确入场时机。我们知道阿隆指标是一直在0~100之间上下运行,那么在市场处于上涨趋势,也就是AroonUp在AroonDown之上时,当AroonUp大于50,说明市场上涨的趋势已经形成,未来价格可能会继续上涨;当AroonUp下穿50时,说明价格上涨的动力正在减弱,未来价格可能会震荡和下跌。 + +反之在市场处于下跌趋势,也就是AroonDown在AroonUp之上时,当AroonDown大于50,说明市场下跌趋势已经形成,未来价格可能会继续下跌;当AroonDown下穿50时,说明价格下跌的动力正在减弱,未来价格可能会震荡和上涨。那么根据上面两段理论,我们可以把买卖条件罗列为: + +- 当 AroonUp大于AroonDown,并且AroonUp大于50,多头开仓; +- 当 AroonUp小于AroonDown,或者AroonUp小于50,多头平仓; +- 当 AroonDown大于AroonUp,并且AroonDown大于50,空头开仓; +- 当 AroonDown小于AroonUp,或者AroonDown小于50,空头平仓; + +# 5、基于阿隆指标构建交易策略 + +理清交易逻辑后,我们就可以用代码去实现了,本篇我们继续使用JavaScript语言,品种还是商品期货。动手能力强的小伙伴,也可以把代码翻译成Python语言,或者数字货币。OK,话不多说,依次打开:fmz.com > 登录 > 控制中心 > 策略库 > 新建策略,开始编写策略,注意看下面代码中的注释。 + +**第一步:使用CTA框架** +注意!一定要点击下方的:`商品期货交易类库`。如果你改编为数字货币就点击:`数字货币现货交易类库`。 +``` +function main() { + // ZC000/ZC888 指用指数做为行情源但交易映射到主力连续合约上 + $.CTA("ZC000/ZC888", function(st) { + + }) +} +``` + +**第二步:获取数据** +``` +function main() { + $.CTA("ZC000/ZC888", function(st) { + var r = st.records; // 获取K线数组 + var mp = st.position.amount; // 获取持仓数量 + }) +} +``` + +**第三步:计算阿隆指标** +``` +function main() { + $.CTA("ZC000/ZC888", function(st) { + var r = st.records; // 获取K线数组 + var mp = st.position.amount; // 获取持仓数量 + if (r.length < 21) { // 判断K线数据是否足够 + return; + } + var aroon = talib.AROON(r, 20); // 阿隆指标 + var aroonUp = aroon[1][aroon[1].length - 2]; // 阿隆指标上线倒数第2根数据 + var aroonDown = aroon[0][aroon[0].length - 2]; // 阿隆指标下线倒数第2根数据 + }) +} + +``` + + +**第四步:计算交易条件并下单** + +``` +function main() { + $.CTA("ZC000/ZC888", function(st) { + var r = st.records; // 获取K线数组 + var mp = st.position.amount; // 获取持仓数量 + if (r.length < 21) { // 判断K线数据是否足够 + return; + } + var aroon = talib.AROON(r, 20); // 阿隆指标 + var aroonUp = aroon[1][aroon[1].length - 2]; // 阿隆指标上线倒数第2根数据 + var aroonDown = aroon[0][aroon[0].length - 2]; // 阿隆指标下线倒数第2根数据 + if (mp == 0 && aroonUp > aroonDown && aroonUp > 50) { + return 1; // 多头开仓 + } + if (mp == 0 && aroonDown > aroonUp && aroonDown > 50) { + return -1; // 空头开仓 + } + if (mp > 0 && (aroonUp < aroonDown || aroonUp < 50)) { + return -1; // 多头平台 + } + if (mp < 0 && (aroonDown < aroonUp || aroonDown < 50)) { + return 1; // 空头平台 + } + }) +} +``` + +# 6、策略回测 + +为了更接近真实的交易环境,我们在回测时采用开平仓各2跳以及2倍的手续费来压力测试,测试环境如下: + +- 行情品种:动力煤指数 +- 交易品种:动力煤主力 +- 时间:2015年06月01日~2019年06月28日 +- 周期:日线 +- 滑点:开平仓各2跳 +- 手续费:交易所2倍 + +**测试环境** + ![IMG](https://www.fmz.com/upload/asset/39907574d57473cf986d.png) +**收益明细** + ![IMG](https://www.fmz.com/upload/asset/394305f56784dce4a690.png) +**资金曲线** + ![IMG](https://www.fmz.com/upload/asset/3a2fe000eebf1ffd7ca1.png) +从上面的回测结果看,策略在市场行情走势流畅的时候表现很好,无论是在上涨或下跌中,阿隆指标可以完整的跟踪到行情。资金曲线也整体走势向上,并没有出现较大幅度的回撤。但是在震荡行情中,特别是连续的震荡行情中,出现了局部回撤。 + +# 7、阿隆指标的优缺点 + +- 优点:阿隆指标可以判断趋势行情的状态,兼顾发现市场趋势行情以及判断价格转向的能力,帮助交易者提高资金的使用率,这个优势震荡行情中尤为重要。 +- 缺点:阿隆指标只是趋势跟踪系列指标中的一种,同样也有趋势跟踪指标的缺点。并且它只判断指定时间最高价或最低价的周期数,但有时候最高价或最低价在整个行情走势中会有偶然性,这个偶然性会干扰阿隆指标本身,造成虚假信号。 + +# 8、总结 + +在策略中我们固定了一部分参数,如:aroonUp或aroonDown大于小于50,造成策略的滞后性,很多情况下是行情上涨或下跌一段时间才开平仓买卖。这样虽然提高了胜率,减少了最大回撤率,但也错过了很多收益,这也印证了盈亏同源的道理。有兴趣的朋友可以深入研究一下,并加以改进。 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|open|50|open| +|close|50|close| +|cycle|20|cycle| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2015-06-01 09:00:00 +end: 2019-06-28 15:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +*/ + +function main() { + $.CTA("ZC000/ZC888", function(st) { + var r = st.records; // 获取K线数组 + var mp = st.position.amount; // 获取持仓数量 + if (r.length < cycle + 1) { // 判断K线数据是否足够 + return; + } + var aroon = talib.AROON(r, cycle); // 阿隆指标 + var aroonUp = aroon[1][aroon[1].length - 2]; // 阿隆指标上线倒数第2根数据 + var aroonDown = aroon[0][aroon[0].length - 2]; // 阿隆指标下线倒数第2根数据 + if (mp > 0 && (aroonUp < aroonDown || aroonUp < close)) { + return -1; // 多头平台 + } + if (mp < 0 && (aroonDown < aroonUp || aroonDown < close)) { + return 1; // 空头平台 + } + if (mp == 0 && aroonUp > aroonDown && aroonUp > open) { + return 1; // 多头开仓 + } + if (mp == 0 && aroonDown > aroonUp && aroonDown > open) { + return -1; // 空头开仓 + } + }) +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/154547 + +> 更新时间 + +2019-07-05 12:09:23 diff --git "a/\351\272\246\350\257\255\350\250\200\347\275\221\346\240\274\347\255\226\347\225\245.md" "b/\351\272\246\350\257\255\350\250\200\347\275\221\346\240\274\347\255\226\347\225\245.md" index 92817804..8da07883 100644 --- "a/\351\272\246\350\257\255\350\250\200\347\275\221\346\240\274\347\255\226\347\225\245.md" +++ "b/\351\272\246\350\257\255\350\250\200\347\275\221\346\240\274\347\255\226\347\225\245.md" @@ -29,10 +29,11 @@ a8269917 VARIABLE:V1:1; IF dtkc>0 AND BKVOL=0 THEN BEGIN 1,BK(dtkc);V1:C;INFO(1,V1);END IF ktkc>0 AND SKVOL=0 THEN BEGIN 1,SK(ktkc);V1:C;INFO(1,V1);END -IF BKVOL>0 AND C>V1*(1+y) THEN BEGIN 1,SP(jian);V1:C;INFO(1,V1);END +IF BKVOL>0 AND C>V1/(1-y) THEN BEGIN 1,SP(jian);V1:C;INFO(1,V1);END IF BKVOL>0 AND C0 AND C0 AND C0 AND C>V1*(1+s) THEN BEGIN 1,SK(jia);V1:C;INFO(1,V1);END +MULTSIG(0,0,60,0); TRADE_AGAIN(1000); ``` @@ -42,4 +43,4 @@ https://www.fmz.com/strategy/142701 > 更新时间 -2019-04-02 13:15:33 +2019-06-21 23:07:47 From bc9ababf88a7e723559fd1c0dee7ff8ec87b5895 Mon Sep 17 00:00:00 2001 From: Zero Date: Sat, 24 Aug 2019 12:26:10 +0800 Subject: [PATCH 14/19] update --- ...\210)|Dual Thrust (MyLanguage version).md" | 6 +- ...73\345\233\276\350\214\203\344\276\213.md" | 5 +- README.md | 48 +- ...10\251\345\210\251\345\231\250 (Copy).md" | 417 ----------- ...26\347\237\277\346\274\224\347\244\272.md" | 2 +- ...17\345\222\214\347\262\276\345\272\246.md" | 2 +- ...y of Traditional MA Index and KD Index.md" | 4 +- ...\347\225\245|DMI and High-Low Strategy.md" | 4 +- ...245|Double Average Lines -DDI Strategy.md" | 6 +- ...0\210|Combination of Double MA and RSI.md" | 4 +- ...6\347\225\245 \350\214\203\344\276\213.md" | 4 +- ...rage of difference - combined with ATR.md" | 6 +- ...\214\201$.CTA\345\207\275\346\225\260).md" | 667 ------------------ ...44\346\230\223\350\275\257\344\273\266.md" | 131 +--- ...ndard deviation price channel strategy.md" | 3 +- ...7\347\255\226\347\225\245|PBX Strategy.md" | 4 +- ...26\347\225\245\346\272\220\347\240\201.md" | 95 +-- ...55\347\232\204\345\272\224\347\224\250.md" | 134 +--- 18 files changed, 71 insertions(+), 1471 deletions(-) delete mode 100644 "RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245-\347\206\212\345\270\202\347\233\210\345\210\251\345\210\251\345\231\250 (Copy).md" delete mode 100644 "\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).md" diff --git "a/Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210)|Dual Thrust (MyLanguage version).md" "b/Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210)|Dual Thrust (MyLanguage version).md" index ede513bc..62511985 100644 --- "a/Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210)|Dual Thrust (MyLanguage version).md" +++ "b/Dual Thrust (\351\272\246\350\257\255\350\250\200\347\211\210)|Dual Thrust (MyLanguage version).md" @@ -16,10 +16,6 @@ littleDreamXX - 在第二天开盘,记录开盘价,然后在价格超过(开盘+触发值)时马上买入,或者价格低于(开盘-触发值)时马上卖空。 - 这个系统是反转系统,没有单独止损。也就是说,反向信号也同时就是平仓信号。 -> 图解 - - https://dn-filebox.qbox.me/ab06814528c0ae8c54c6bebaea4438325968fbe5.jpg - `Dual Thrust 策略包含完整的图表显示, 图表动态更新,模板引用等功能, 可做学习模板使用.` 策略的详细介绍 : http://xueqiu.com/5256769224/32429363 @@ -95,4 +91,4 @@ https://www.fmz.com/strategy/128884 > 更新时间 -2018-12-18 11:28:40 +2019-08-20 10:47:50 diff --git "a/MACD\347\224\273\345\233\276\350\214\203\344\276\213.md" "b/MACD\347\224\273\345\233\276\350\214\203\344\276\213.md" index 8114e50f..7d15b742 100644 --- "a/MACD\347\224\273\345\233\276\350\214\203\344\276\213.md" +++ "b/MACD\347\224\273\345\233\276\350\214\203\344\276\213.md" @@ -24,6 +24,9 @@ exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}] var preTime = 0; var ChartObj = null; function main(){ + // 测试 + Log(aa.Last) // 测试 + LogReset(1); ChartObj = Chart(null); ChartObj.reset(); @@ -103,4 +106,4 @@ https://www.fmz.com/strategy/151972 > 更新时间 -2019-06-12 20:16:58 +2019-08-23 10:36:33 diff --git a/README.md b/README.md index d1cbd3cd..cef58d77 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,46 @@ > 开源策略 + - [C++商品期货高频交易策略之Penny Jump](https://www.fmz.com/strategy/163427) + - [多线程批量任务](https://www.fmz.com/strategy/159978) + - [HFT strategy](https://www.fmz.com/strategy/162372) + - [MACD画图范例](https://www.fmz.com/strategy/151972) + - [MultDualThrust(教学)](https://www.fmz.com/strategy/163212) + - [标准差价格通道策略|Standard deviation price channel strategy](https://www.fmz.com/strategy/128121) + - [Dual Thrust (麦语言版)|Dual Thrust (MyLanguage version)](https://www.fmz.com/strategy/128884) + - [双均线DDI策略|Double Average Lines -DDI Strategy](https://www.fmz.com/strategy/128133) + - [开收盘均价差ATR策略|The average of difference - combined with ATR](https://www.fmz.com/strategy/128136) + - [传统均线指标与KD指标的交易策略|Trading Strategy of Traditional MA Index and KD Index](https://www.fmz.com/strategy/128249) + - [双均线策略与相对强弱RSI指标组合|Combination of Double MA and RSI](https://www.fmz.com/strategy/128250) + - [动向指数(DMI)与高低点策略|DMI and High-Low Strategy](https://www.fmz.com/strategy/128418) + - [瀑布线策略|PBX Strategy](https://www.fmz.com/strategy/128420) + - [基于期货基本面分析的交易策略](https://www.fmz.com/strategy/161412) + - [做市策略(basefex)](https://www.fmz.com/strategy/162413) + - [测试图表](https://www.fmz.com/strategy/162093) + - [钉钉推送](https://www.fmz.com/strategy/159668) + - [火币点卡](https://www.fmz.com/strategy/162055) + - [时间格式工具](https://www.fmz.com/strategy/161505) + - [能量潮OBV在量化交易中的详细用法和实战技巧](https://www.fmz.com/strategy/159997) + - [火币精度](https://www.fmz.com/strategy/159104) + - [简单多品种商品期货均线策略 (Copy)](https://www.fmz.com/strategy/159506) - [交易所最小数量和精度](https://www.fmz.com/strategy/108887) + - [期货看穿式测试](https://www.fmz.com/strategy/152670) + - [肯特纳通道升级版金肯特纳kingkeltner策略](https://www.fmz.com/strategy/159285) + - [基于箱体理论的交易策略,支持商品期货和数字货币](https://www.fmz.com/strategy/158088) + - [多交易所集合行情/下单 策略 范例](https://www.fmz.com/strategy/125569) + - [OKEx跨期对冲策略](https://www.fmz.com/strategy/157635) - [数字货币自适应均线交易系统以及KAMA算法解析——基于发明者量化交易软件](https://www.fmz.com/strategy/155663) + - [RangeBreak策略与波动率相结合的实战应用](https://www.fmz.com/strategy/156836) - [运用阿隆(Aroon)指标在数字货币中量化交易,附带My语言策略源码](https://www.fmz.com/strategy/155582) - [阿隆(Aroon)技术指标在商品期货中的应用](https://www.fmz.com/strategy/154547) + - [【海龟汤策略】反趋势交易策略](https://www.fmz.com/strategy/157372) + - [RSI统计套利策略](https://www.fmz.com/strategy/157366) + - [获取USDT和USD的实时汇率](https://www.fmz.com/strategy/157364) + - [【经典趋势策略】海龟交易策略](https://www.fmz.com/strategy/157270) + - [OKEX期现对冲](https://www.fmz.com/strategy/157269) + - [现现对冲(多交易所搬砖)](https://www.fmz.com/strategy/157267) + - [均线策略范例02](https://www.fmz.com/strategy/156699) + - [网格策略](https://www.fmz.com/strategy/156663) - [山寨币指数(2018.02.22基点1000)](https://www.fmz.com/strategy/73461) - [指数平衡策略|Index Balance Bot](https://www.fmz.com/strategy/116012) - [简单固定价格止损机器人|Stop Loss Below Fixed Price](https://www.fmz.com/strategy/121081) @@ -25,7 +61,6 @@ - [麦语言网格策略](https://www.fmz.com/strategy/142701) - [annotation属性](https://www.fmz.com/strategy/149661) - [日志|Logger](https://www.fmz.com/strategy/151754) - - [MACD画图范例](https://www.fmz.com/strategy/151972) - [三角套利-基础版](https://www.fmz.com/strategy/151145) - [期货反手加倍算法](https://www.fmz.com/strategy/3648) - [FCoin杠杆交易模板](https://www.fmz.com/strategy/151157) @@ -52,8 +87,6 @@ - [恒温器 Thermostat 择时策略研究](https://www.fmz.com/strategy/127033) - [API 测试新手入门](https://www.fmz.com/strategy/4) - [基于随机森林的趋势策略](https://www.fmz.com/strategy/140199) - - [RSI统计套利策略-熊市盈利利器 (Copy)](https://www.fmz.com/strategy/138171) - - [多交易所集合行情/下单 策略 范例](https://www.fmz.com/strategy/125569) - [海龟汤策略](https://www.fmz.com/strategy/139249) - [策略框架](https://www.fmz.com/strategy/20663) - [商品期货跟单系统](https://www.fmz.com/strategy/79351) @@ -75,27 +108,19 @@ - [升级版恒温器策略|Upgraded Thermostat Strategy](https://www.fmz.com/strategy/129086) - [基于ATR波动率指标构建的通道策略|Channel strategy based on ATR](https://www.fmz.com/strategy/128126) - [三轨道波动率策略|Three-track Volatility Strategy](https://www.fmz.com/strategy/128129) - - [Dual Thrust (麦语言版)|Dual Thrust (MyLanguage version)](https://www.fmz.com/strategy/128884) - [高胜率ORB交易策略|High Winning Rate - ORB Trading Strategy](https://www.fmz.com/strategy/129084) - [混沌操作法策略|Trading Chaos Strategy](https://www.fmz.com/strategy/129077) - [均线和高低点相对强弱策略|Relative Strength Strategy Based on Price](https://www.fmz.com/strategy/129078) - [日本云图简化版策略|Simplified Version of ICHIMOKU KINKO HYO Strategy](https://www.fmz.com/strategy/129083) - [双均线与形态策略|Double MA and Formation Strategy](https://www.fmz.com/strategy/129079) - [RUMI策略|RUMI Strategy](https://www.fmz.com/strategy/129082) - - [瀑布线策略|PBX Strategy](https://www.fmz.com/strategy/128420) - - [动向指数(DMI)与高低点策略|DMI and High-Low Strategy](https://www.fmz.com/strategy/128418) - [价格高低点与一目均线双重趋势策略|Price high and low - Ichimoku trend strategy](https://www.fmz.com/strategy/128415) - [高低点与波动率ROC指标策略|Price high and low - ROC index strategy](https://www.fmz.com/strategy/128417) - [波动率ATR轨道突破策略|Volatility ATR - Track Breakthrough Strategy](https://www.fmz.com/strategy/128252) - [抛物线转向SAR与价格高低点策略|SAR and Price High and Low Strategy](https://www.fmz.com/strategy/128251) - [三均线顺势价格突破策略|Three-MA Price Breakthrough Strategy](https://www.fmz.com/strategy/128130) - [多级止盈趋势策略|Multilevel Take Profit Strategy](https://www.fmz.com/strategy/128122) - - [传统均线指标与KD指标的交易策略|Trading Strategy of Traditional MA Index and KD Index](https://www.fmz.com/strategy/128249) - - [双均线策略与相对强弱RSI指标组合|Combination of Double MA and RSI](https://www.fmz.com/strategy/128250) - - [开收盘均价差ATR策略|The average of difference - combined with ATR](https://www.fmz.com/strategy/128136) - - [双均线DDI策略|Double Average Lines -DDI Strategy](https://www.fmz.com/strategy/128133) - [高低点突破成交量指数加权策略|Break High and Low - Volume Index Weighting Strategy](https://www.fmz.com/strategy/128125) - - [标准差价格通道策略|Standard deviation price channel strategy](https://www.fmz.com/strategy/128121) - [你不知道的MACD+MA指标组合策略|MACD+MA Indicator Combination Strategy](https://www.fmz.com/strategy/127101) - [商品期货交易类库(旧版)](https://www.fmz.com/strategy/127341) - [BitMEX 高级API功能 V.1.1.0 (期货:批量下单,编辑订单,冰山订单,一键撤单,定时撤单) Python2/3](https://www.fmz.com/strategy/114148) @@ -178,7 +203,6 @@ - [CTP商品期货多品种海龟交易策略](https://www.fmz.com/strategy/17289) - [python版 Dual Thrust OKCoin 期货](https://www.fmz.com/strategy/21856) - [五线向上&&突破前高](https://www.fmz.com/strategy/76827) - - [数字货币交易类库 (期货支持OKCoin期货/BitVC, 支持$.CTA函数)](https://www.fmz.com/strategy/57267) - [C++ API调用例子](https://www.fmz.com/strategy/61533) - [双平台对冲js版本(two platforms hedging-JS)](https://www.fmz.com/strategy/57556) - [代替废弃的GetMinStock()函数](https://www.fmz.com/strategy/69436) diff --git "a/RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245-\347\206\212\345\270\202\347\233\210\345\210\251\345\210\251\345\231\250 (Copy).md" "b/RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245-\347\206\212\345\270\202\347\233\210\345\210\251\345\210\251\345\231\250 (Copy).md" deleted file mode 100644 index 9049b5fb..00000000 --- "a/RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245-\347\206\212\345\270\202\347\233\210\345\210\251\345\210\251\345\231\250 (Copy).md" +++ /dev/null @@ -1,417 +0,0 @@ - -> 策略名称 - -RSI统计套利策略-熊市盈利利器 (Copy) - -> 策略作者 - -安成蜗牛 - -> 策略描述 - -策略介绍: - -此策略是基于RSI指标的统计套利策略,根据实测在熊市中也能有很高的胜率。策略会对行情进行RSI数据分析,一旦捕获到预定义的K线形态即进行短期套利。 - -RSI指标说明: - -RSI最早被用于期货交易中,后来人们发现用该指标来指导股票市场投资效果也十分不错,并对该指标的特点不断进行归纳和总结。现在,RSI已经成为被投资者应用最广泛的技术指标之一。投资的一般原理认为,投资者的买卖行为是各种因素综合结果的反映,行情的变化最终取决于供求关系,而RSI指标正是根据供求平衡的原理,通过测量某一个期间内股价上涨总幅度占股价变化总幅度平均值的百分比,来评估多空力量的强弱程度,进而提示具体操作的。 - -策略特点: - -支持任意级别的趋势跟踪(分钟K,小时K,日K,周K等) -支持任意交易对(ETH/BTC, BSV/BTC等) -支持任意交易所 -详细的策略报表(包括策略状态,交易历史记录等) -支持接近10个自定义个性化参数 - -使用说明: - -此策略基于Botvs实现,在使用之前需要有一个botvs账户 -上传策略并创建机器人 -配置参数并运行策略 - -参数说明: -http://www.pcclean.io/rsi%E7%BB%9F%E8%AE%A1%E5%A5%97%E5%88%A9%E7%AD%96%E7%95%A5/ - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|wq|true|wq| -|wq2|true|wq2| - - - - -|按钮|默认值|描述| -|----|----|----| -|2|12|安全| - - -> 源码 (javascript) - -``` javascript -/* -RSI策略:仅用于学习用途,用于实盘后果自负 -*/ - -var ExchangProcessor={ - createNew: function(exc_obj){ - //策略参数 - var manage_assets=1;//bch - var max_positions=4;//max=4N - var price_n={BTC_BCH:8,ETH_BCH:8,XRP_BCH:8,EOS_BCH:8,LTC_BCH:8,DASH_BCH:8,CET_BCH:8}; //价格精度 - var num_n={BTC_BCH:8,ETH_BCH:8,XRP_BCH:8,EOS_BCH:8,LTC_BCH:8,DASH_BCH:8,CET_BCH:8}; //数量精度 - var minest_buy={BTC_BCH:0.001,ETH_BCH:0.01,XRP_BCH:1,EOS_BCH:1,LTC_BCH:0.1,DASH_BCH:0.01,CET_BCH:1};//最小买入量 - var minest_sell={BTC_BCH:0.001,ETH_BCH:0.01,XRP_BCH:1,EOS_BCH:1,LTC_BCH:0.1,DASH_BCH:0.01,CET_BCH:1};//最小卖出量 - var order_wait_secs=120000; //订单的最长等待时间 毫秒 - var wait_ms=1000;//默认等待毫秒 - var sxf=0.0005;//用来计算手续费消耗 - - - //全局状态变量 - var positions=[];//记录仓位 - var init_asset=0; //初始资产 - var trades=[];//所有交易 - var trades_recorder=true;//记录所有交易 - var pre_time=null; //记录轮询间隔时间 - var approximate_profit=0;//盈亏近似值 - var add_already=0;//已经加仓次数 - - var processor={}; - //重试购买,直到成功返回 - processor.retryBuy=function(ex,price,num) - { - var currency=ex.GetCurrency(); - var r=ex.Buy(_N(price,price_n[currency]), _N(num,num_n[currency])); - while (!r){ - Log("Buy失败,正在retry。"); - Sleep(wait_ms); - var account=_C(ex.GetAccount); - var ticker=_C(ex.GetTicker); - var last=ticker.Last; - var fixedAmount=(price===-1?Math.min(account.Balance*0.95,num):Math.min(account.Balance/last*0.95,num)); - r=ex.Buy(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); - } - return r; - } - - //重试卖出,直到成功返回 - processor.retrySell=function(ex,price,num){ - var currency=ex.GetCurrency(); - var r=ex.Sell(_N(price,price_n[currency]), _N(num,num_n[currency])); - while (!r){ - Log("Sell失败,正在retry。"); - Sleep(wait_ms); - var account=_C(ex.GetAccount); - var fixedAmount=Math.min(account.Stocks,num); - r=ex.Sell(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); - } - return r; - } - - - processor.get_ChinaTimeString=function(){ - var date = new Date(); - var now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), - date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); - var cdate=new Date(now_utc); - cdate.setHours(cdate.getHours()+8); - var localstring=cdate.getFullYear()+'/'+(cdate.getMonth()+1)+'/'+cdate.getDate()+' '+cdate.getHours()+':'+cdate.getMinutes()+':'+cdate.getSeconds(); - return localstring; - } - - processor.init_obj=function(){ - _CDelay(wait_ms); - pre_time = new Date(); - - //init - { - var account=_C(exc_obj.GetAccount); - var ticker=_C(exc_obj.GetTicker); - var last=ticker.Last; - init_asset=(account.Balance+account.FrozenBalance)+(account.Stocks+account.FrozenStocks)*last; - Sleep(wait_ms); - } - } - - - processor.work=function(){ - var cur_time = new Date(); - var passedtime=cur_time-pre_time; - pre_time=cur_time; - - //计算n,头寸 - var exname=exc_obj.GetName(); - var currency=exc_obj.GetCurrency(); - var account=_C(exc_obj.GetAccount); - var ticker=_C(exc_obj.GetTicker); - var depth = _C(exc_obj.GetDepth); - var last=ticker.Last; - var ask1=depth.Asks[0].Price; - var bid1=depth.Bids[0].Price; - var bestprice=bid1+(Math.abs(ask1-bid1)/2); - var records = _C(exc_obj.GetRecords); - if (records.length<=50){ - Log("records.length is not valid."); - Sleep(wait_ms); - return; - } - var atr = TA.ATR(records, 20); - if (atr.length<=1){ - Log("atr.length is not valid."); - Sleep(wait_ms); - return; - } - var N=atr[atr.length-1]; - var position_unit=Math.min(manage_assets*0.01/N,account.Balance/last*0.95);//cet - //Log("N="+N+", 头寸单位="+position_unit+"CET"); - var highest=TA.Highest(records, 20, 'High'); - var Lowest=TA.Lowest(records, 10, 'Low'); - var cur_asset=(account.Balance+account.FrozenBalance)+(account.Stocks+account.FrozenStocks)*last; - var rsi6 = TA.RSI(records, 6); - var rsi12 = TA.RSI(records, 12); - if (rsi6.length<=5 || rsi12.length<=5){ - Log("rsi is not valid."); - Sleep(wait_ms); - return; - } - var rsi_in=false; - if (rsi6[rsi6.length-1]-rsi6[rsi6.length-2]>1 && rsi6[rsi6.length-2]<=65){ - //Log("rsi_in=true"); - rsi_in=true; - } - var rsi_out=false; - if (rsi6[rsi6.length-1]>=60){ - //Log("rsi_out=true"); - rsi_out=true; - } - - //建仓 - if (positions.length==0 && position_unit>minest_buy[currency]){ - if (rsi_in) - { - var buyID = processor.retryBuy(exc_obj,last,position_unit); - Sleep(order_wait_secs); - var buyOrder=_C(exc_obj.GetOrder,buyID); - if (buyOrder.Status!=ORDER_STATE_CLOSED){ - exc_obj.CancelOrder(buyID); - } - if (buyOrder.DealAmount>0){ - var postion = { - amount:buyOrder.DealAmount, - buy_price:buyOrder.AvgPrice, - stoploss_price:buyOrder.AvgPrice-N}; - positions.push(postion); - - var details={ - type:"建仓", - time:processor.get_ChinaTimeString(), - RealAmount:buyOrder.DealAmount, - WantAmount:position_unit, - RealPrice:buyOrder.AvgPrice, - WantPrice:buyOrder.Price, - Memo:"" - }; - if (trades_recorder){ - trades.push(details); - } - - add_already=1; - } - } - } - - //加仓 - if (positions.length>0 && position_unit>minest_buy[currency]){ - var last_buy_price=positions[positions.length-1].buy_price; - if (add_already=0.5*N){ - var buyID = processor.retryBuy(exc_obj,last,position_unit); - Sleep(order_wait_secs); - var buyOrder=_C(exc_obj.GetOrder,buyID); - if (buyOrder.Status!=ORDER_STATE_CLOSED){ - exc_obj.CancelOrder(buyID); - } - if (buyOrder.DealAmount>0){ - var postion = { - amount:buyOrder.DealAmount, - buy_price:buyOrder.AvgPrice, - stoploss_price:buyOrder.AvgPrice-N}; - positions.push(postion); - - var details={ - type:"加仓", - time:processor.get_ChinaTimeString(), - RealAmount:buyOrder.DealAmount, - WantAmount:position_unit, - RealPrice:buyOrder.AvgPrice, - WantPrice:last, - Memo:"" - }; - if (trades_recorder){ - trades.push(details); - } - - add_already=add_already+1; - } - } - } - } - - //止损 - if (positions.length>0){ - var positions_new=[]; - for (var i=0; i < positions.length; i++){ - if (last<=positions[i].stoploss_price){ - account=_C(exc_obj.GetAccount); - var fixedAmount=Math.min(account.Stocks,positions[i].amount); - if (fixedAmount>minest_sell[currency]){ - var sellID = processor.retrySell(exc_obj, last, fixedAmount); - Sleep(order_wait_secs); - var sellOrder=_C(exc_obj.GetOrder,sellID); - approximate_profit+=(sellOrder.AvgPrice*sellOrder.DealAmount*(1-sxf)-positions[i].buy_price*sellOrder.DealAmount*(1+sxf)); - Log("定价卖出: 数量-"+sellOrder.DealAmount+",approximate_profit="+approximate_profit); - if (sellOrder.Status!=ORDER_STATE_CLOSED){ - exc_obj.CancelOrder(sellID); - if (Math.min(account.Stocks,fixedAmount-sellOrder.DealAmount)>minest_sell[currency]){ - var marketsellOrderID=processor.retrySell(exc_obj, -1, fixedAmount-sellOrder.DealAmount); - Sleep(order_wait_secs); - var marketsellOrderData=_C(exc_obj.GetOrder,marketsellOrderID); - approximate_profit+=(marketsellOrderData.AvgPrice*marketsellOrderData.DealAmount*(1-sxf)-positions[i].buy_price*marketsellOrderData.DealAmount*(1+sxf)); - Log("市价卖出: 数量-"+marketsellOrderData.DealAmount+",approximate_profit="+approximate_profit); - } - } - - var details={ - type:"止损", - time:processor.get_ChinaTimeString(), - RealAmount:-1, - WantAmount:fixedAmount, - RealPrice:-1, - WantPrice:last, - Memo:(last>positions[i].buy_price?"盈利":"亏损") - }; - if (trades_recorder){ - trades.push(details); - } - } - }else{ - positions_new.push(positions[i]); - } - } - positions=positions_new; - } - - //清仓 - if (positions.length>0){ - if (rsi_out){ - var positions_new=[]; - for (var i=0; i < positions.length; i++){ - account=_C(exc_obj.GetAccount); - var fixedAmount=Math.min(account.Stocks,positions[i].amount); - if (fixedAmount>minest_sell[currency]){ - var sellID = processor.retrySell(exc_obj, last, fixedAmount); - Sleep(order_wait_secs); - var sellOrder=_C(exc_obj.GetOrder,sellID); - approximate_profit+=(sellOrder.AvgPrice*sellOrder.DealAmount*(1-sxf)-positions[i].buy_price*sellOrder.DealAmount*(1+sxf)); - Log("定价卖出: 数量-"+sellOrder.DealAmount+",approximate_profit="+approximate_profit); - if (sellOrder.Status!=ORDER_STATE_CLOSED){ - exc_obj.CancelOrder(sellID); - if (Math.min(account.Stocks,fixedAmount-sellOrder.DealAmount)>minest_sell[currency]){ - var marketsellOrderID=processor.retrySell(exc_obj, -1, fixedAmount-sellOrder.DealAmount); - Sleep(order_wait_secs); - var marketsellOrderData=_C(exc_obj.GetOrder,marketsellOrderID); - approximate_profit+=(marketsellOrderData.AvgPrice*marketsellOrderData.DealAmount*(1-sxf)-positions[i].buy_price*marketsellOrderData.DealAmount*(1+sxf)); - Log("市价卖出: 数量-"+marketsellOrderData.DealAmount+",approximate_profit="+approximate_profit); - } - } - - var details={ - type:"清仓", - time:processor.get_ChinaTimeString(), - RealAmount:-1, - WantAmount:fixedAmount, - RealPrice:-1, - WantPrice:last, - Memo:(last>positions[i].buy_price?"盈利":"亏损") - }; - if (trades_recorder){ - trades.push(details); - } - } - } - positions=positions_new; - } - } - - - //显示状态 - var table1 = {type: 'table', title: '仓位-'+exname+'('+currency+')', cols: ['数量', '成交价','止损价'], rows: []}; - var table2 = {type: 'table', title: '状态-'+exname+'('+currency+')', cols: ['平均真实波幅(N)','头寸单位','初始资产','当前资产','轮询时间','最新价','Highest','Lowest','加仓次数','【近似盈亏】'], rows: []}; - var table3 = {type: 'table', title: '交易历史-'+exname+'('+currency+')', cols: ['日期','类型', '成交数量','发单数量','成交价','发单价','备注'], rows: []}; - for (var i=0; i < positions.length; i++){ - table1.rows.push([positions[i].amount,positions[i].buy_price,positions[i].stoploss_price]); - } - table2.rows.push([N,position_unit,init_asset,cur_asset,passedtime+'ms',last,highest,Lowest,add_already,approximate_profit]); - for (i=0; i < trades.length; i++){ - table3.rows.push([trades[i].time,trades[i].type,trades[i].RealAmount,trades[i].WantAmount,trades[i].RealPrice,trades[i].WantPrice,trades[i].Memo]); - } - processor.logstatus=('`' + JSON.stringify([table1, table2, table3])+'`'+'\n'); - - //记录盈利 - processor.logprofit=approximate_profit; - - //rest - Sleep(wait_ms); - } - - return processor; - } -}; - - - -//主函数 -function main(){ - var exchange_num=exchanges.length; - var processors=[]; - for (var i=0; i 策略出处 - -https://www.fmz.com/strategy/138171 - -> 更新时间 - -2019-03-13 18:16:38 diff --git "a/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.md" "b/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.md" index 4e10e67c..c605b92f 100644 --- "a/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.md" +++ "b/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.md" @@ -5,7 +5,7 @@ fcoin挖矿演示 > 策略作者 -爆仓小王子 +华丽转身 > 策略描述 diff --git "a/\344\272\244\346\230\223\346\211\200\346\234\200\345\260\217\346\225\260\351\207\217\345\222\214\347\262\276\345\272\246.md" "b/\344\272\244\346\230\223\346\211\200\346\234\200\345\260\217\346\225\260\351\207\217\345\222\214\347\262\276\345\272\246.md" index 210cbc45..61409a0b 100644 --- "a/\344\272\244\346\230\223\346\211\200\346\234\200\345\260\217\346\225\260\351\207\217\345\222\214\347\262\276\345\272\246.md" +++ "b/\344\272\244\346\230\223\346\211\200\346\234\200\345\260\217\346\225\260\351\207\217\345\222\214\347\262\276\345\272\246.md" @@ -1671,4 +1671,4 @@ https://www.fmz.com/strategy/108887 > 更新时间 -2019-07-07 11:51:41 +2019-07-30 02:35:13 diff --git "a/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245|Trading Strategy of Traditional MA Index and KD Index.md" "b/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245|Trading Strategy of Traditional MA Index and KD Index.md" index 7abdc97b..0fe5cab4 100644 --- "a/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245|Trading Strategy of Traditional MA Index and KD Index.md" +++ "b/\344\274\240\347\273\237\345\235\207\347\272\277\346\214\207\346\240\207\344\270\216KD\346\214\207\346\240\207\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245|Trading Strategy of Traditional MA Index and KD Index.md" @@ -12,7 +12,7 @@ littleDreamXX [trans] - 策略名称:传统均线指标与KD指标的交易策略 - 数据周期:15M,30M等 -- 支持:商品期货 +- 支持:商品期货、数字货币 - 指标使用了EMA,KD线,其中KD线使用的是默认参数(指标参数固定3,3,9) - 官方网站:www.quantinfo.com @@ -95,4 +95,4 @@ https://www.fmz.com/strategy/128249 > 更新时间 -2018-12-15 16:06:00 +2019-08-20 10:30:47 diff --git "a/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|DMI and High-Low Strategy.md" "b/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|DMI and High-Low Strategy.md" index 833c736f..75d06032 100644 --- "a/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|DMI and High-Low Strategy.md" +++ "b/\345\212\250\345\220\221\346\214\207\346\225\260\357\274\210DMI\357\274\211\344\270\216\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245|DMI and High-Low Strategy.md" @@ -12,7 +12,7 @@ littleDreamXX [trans] - 策略名称:动向指数(DMI)与高低点策略 - 数据周期:5M -- 支持:商品期货 +- 支持:商品期货,数字货币 - 官方网站:www.quantinfo.com @@ -92,4 +92,4 @@ https://www.fmz.com/strategy/128418 > 更新时间 -2018-12-17 17:40:05 +2019-08-20 10:24:43 diff --git "a/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245|Double Average Lines -DDI Strategy.md" "b/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245|Double Average Lines -DDI Strategy.md" index 0e670b21..6b8126e7 100644 --- "a/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245|Double Average Lines -DDI Strategy.md" +++ "b/\345\217\214\345\235\207\347\272\277DDI\347\255\226\347\225\245|Double Average Lines -DDI Strategy.md" @@ -12,9 +12,7 @@ littleDreamXX [trans] - 策略思路:双均线确定方向,用DDI指标,确定进场时点,比例止损和回撤止盈 - 数据周期:15M -- 数据合约:指数合约 -- 交易合约:主力合约 -- 适合品种:沪银/沪镍/热卷/铁矿石/焦煤/焦炭/鸡蛋/郑醇/PP/螺纹/橡胶/锰硅/郑煤等 +- 策略适用:数字货币、商品期货 - 官方网站:www.quantinfo.com - 主图指标线: @@ -109,4 +107,4 @@ https://www.fmz.com/strategy/128133 > 更新时间 -2018-12-15 15:43:04 +2019-08-20 10:35:47 diff --git "a/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210|Combination of Double MA and RSI.md" "b/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210|Combination of Double MA and RSI.md" index 08a8aad1..99f24a3b 100644 --- "a/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210|Combination of Double MA and RSI.md" +++ "b/\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245\344\270\216\347\233\270\345\257\271\345\274\272\345\274\261RSI\346\214\207\346\240\207\347\273\204\345\220\210|Combination of Double MA and RSI.md" @@ -13,7 +13,7 @@ littleDreamXX - 策略名称:双均线策略与相对强弱RSI指标组合 - 数据周期:15M,30M等 -- 支持:商品期货 +- 支持:商品期货、数字货币 - 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/9955a36cca1be0e9d73f99fa8bdb4ac8.png) @@ -95,4 +95,4 @@ https://www.fmz.com/strategy/128250 > 更新时间 -2018-12-15 15:44:22 +2019-08-20 10:29:50 diff --git "a/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" "b/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" index 0f0958fd..18439e59 100644 --- "a/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" +++ "b/\345\244\232\344\272\244\346\230\223\346\211\200\351\233\206\345\220\210\350\241\214\346\203\205-\344\270\213\345\215\225 \347\255\226\347\225\245 \350\214\203\344\276\213.md" @@ -228,6 +228,8 @@ function main(){ // 处理交互 var cmd = GetCommand() if(cmd){ + Log("cmd:", cmd) // 测试 + var arr = cmd.split("_") if(arr.length == 3){ var idx = parseInt(arr[1]) @@ -267,4 +269,4 @@ https://www.fmz.com/strategy/125569 > 更新时间 -2019-03-02 13:49:51 +2019-07-19 11:44:04 diff --git "a/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245|The average of difference - combined with ATR.md" "b/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245|The average of difference - combined with ATR.md" index 7308d0f2..e16afc5f 100644 --- "a/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245|The average of difference - combined with ATR.md" +++ "b/\345\274\200\346\224\266\347\233\230\345\235\207\344\273\267\345\267\256ATR\347\255\226\347\225\245|The average of difference - combined with ATR.md" @@ -13,9 +13,7 @@ littleDreamXX - 策略进场:开盘价和收盘价均价差决定趋势,与ATR结合,进场点也是反向出场点; - 策略出场:开仓就定好止损点,趋势转向出场; - 数据周期:日线 -- 数据合约:指数合约 -- 交易合约:主力合约 -- 适合品种:沪铝、沥青、淀粉、热卷、铁矿石、焦炭、鸡蛋、郑醇、螺纹、橡胶、锰硅、郑煤等 +- 策略适用:数字货币、商品期货 - 官方网站:[www.quantinfo.com](www.quantinfo.com) - 主图: @@ -104,4 +102,4 @@ https://www.fmz.com/strategy/128136 > 更新时间 -2018-12-15 15:43:24 +2019-08-20 10:32:06 diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).md" "b/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).md" deleted file mode 100644 index 1a72349a..00000000 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\344\272\244\346\230\223\347\261\273\345\272\223 (\346\234\237\350\264\247\346\224\257\346\214\201OKCoin\346\234\237\350\264\247-BitVC, \346\224\257\346\214\201$.CTA\345\207\275\346\225\260).md" +++ /dev/null @@ -1,667 +0,0 @@ - -> 策略名称 - -数字货币交易类库 (期货支持OKCoin期货-BitVC, 支持$.CTA函数) - -> 策略作者 - -小小梦 - -> 策略描述 - -数字货币交易类库 (期货支持OKCoin期货/BitVC) 目前测试阶段,使用请留意,如有问题 ,请联系作者 ,十分感谢! - -- ### 新增了 $.CTA 函数 - - 可以用 $.CTA 函数 快速构建 均线等 类型的策略 - 使用模板的 $.CTA 函数 构建的 策略代码如下(很精简): - 文章 参看 商品期货交易类库 的 $.CTA 函数 使用 (使用、架构是类似的) : https://zhuanlan.zhihu.com/p/30016518 -``` -function main() { - $.CTA(exchanges[0], 0.01, function(r, mp, pair){ // 第一个参数 是 要做的 交易所对象, 第二个参数 0.01 是交易所 要求的 最小下单数量, 第三个 匿名函数 function(){...} - // 是 回调函数, 交易逻辑 就写在这个函数中, 该回调函数 第一个参数 r 接收最新的 K线数据, 第二个参数 接收 持仓数, 第 - // 三个参数 接收 交易对 名称 - if (r.length < 20) { // 判断 K线柱数量 - return - } - var emaSlow = TA.EMA(r, 20) - var emaFast = TA.EMA(r, 5) - var cross = _Cross(emaFast, emaSlow); // 判断指标 相交状态, _Cross 参看 : https://www.fmz.com/bbs-topic/1140 - if (mp <= 0 && cross > 1) { - Log(pair, "买, 金叉周期", cross, "mp:", mp); - return 0.1 * (mp < 0 ? 2 : 1) // 返回的数值 就是 要开仓的 数量, 正数是 开多 ,负数是 开空, 0 是 全部平掉。 - } else if (mp >= 0 && cross < -1) { - Log(pair, "卖, 死叉周期", cross, "mp:", mp); - return -0.1 * (mp > 0 ? 2 : 1) - } - }) -} -``` - -https://dn-filebox.qbox.me/c230753d3fd584c15ad3e39e33f970aafffe722f.png -https://dn-filebox.qbox.me/a74f74b34e32897868086e6b771f81fd1468306e.png -https://dn-filebox.qbox.me/1671268eba20870c7820542448dc0ef541d65a5b.png - -- ### 注意: - - - #### 使用期货 功能下单时: - 注意不要忘记 先设置 合约类型 :exchange.SetContractType("this_week") 否则会报错。 - ``` - var p = $.NewPositionManager() - // this_week 即 当周合约 开多仓 , PositionManager.prototype.OpenLong = function(contractType, shares, price) - exchange.SetContractType("this_week") - p.OpenLong("this_week", 1, 1000) - // 这样就 1000 美元价格 开多仓 合约 1张 - ``` - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|OpMode|0|现货-下单方式: 吃单|挂单| -|MaxSpace|0.5|现货-挂单失效距离| -|SlidePrice|0.1|现货-下单滑动价(元)| -|MaxAmount|0.8|现货-开仓最大单次下单量| -|RetryDelay|500|现货-失败重试(毫秒)| -|MAType|0|现货-均线算法: EMA|MA|AMA(自适应均线)| -|Interval|300|期货—失败重试间隔(毫秒)| -|F_SlidePrice|2|期货—下单滑价(元)| -|lv|0.5|期货—滑价增长率| -|max_open_lv|true|期货—开仓滑价最大增长率| -|max_cover_lv|true|期货—平仓滑价最大增长率| -|_GetMinStocks|0.01|最小交易数量| -|isCTAshowTable|false|是否显示 模板生成状态栏表格| - - -> 源码 (javascript) - -``` javascript -// 现货部分 -function CancelPendingOrders(e, orderType) { - while (true) { - var orders = e.GetOrders(); - if (!orders) { - Sleep(RetryDelay); - continue; - } - var processed = 0; - for (var j = 0; j < orders.length; j++) { - if (typeof(orderType) === 'number' && orders[j].Type !== orderType) { - continue; - } - e.CancelOrder(orders[j].Id, orders[j]); - processed++; - if (j < (orders.length - 1)) { - Sleep(RetryDelay); - } - } - if (processed === 0) { - break; - } - } -} - -function GetAccount(e, waitFrozen) { - if (typeof(waitFrozen) == 'undefined') { - waitFrozen = false; - } - var account = null; - var alreadyAlert = false; - while (true) { - account = _C(e.GetAccount); - if (!waitFrozen || (account.FrozenStocks < _GetMinStocks && account.FrozenBalance < 0.01)) { - break; - } - if (!alreadyAlert) { - alreadyAlert = true; - Log("发现账户有冻结的钱或币", account); - } - Sleep(RetryDelay); - } - return account; -} - - -function StripOrders(e, orderId) { - var order = null; - if (typeof(orderId) == 'undefined') { - orderId = null; - } - while (true) { - var dropped = 0; - var orders = _C(e.GetOrders); - for (var i = 0; i < orders.length; i++) { - if (orders[i].Id == orderId) { - order = orders[i]; - } else { - var extra = ""; - if (orders[i].DealAmount > 0) { - extra = "成交: " + orders[i].DealAmount; - } else { - extra = "未成交"; - } - e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); - dropped++; - } - } - if (dropped === 0) { - break; - } - Sleep(RetryDelay); - } - return order; -} - -// mode = 0 : direct buy, 1 : buy as buy1 -function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, retryDelay) { - var initAccount = GetAccount(e, true); - var nowAccount = initAccount; - var orderId = null; - var prePrice = 0; - var dealAmount = 0; - var diffMoney = 0; - var isFirst = true; - var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell; - var isBuy = tradeType == ORDER_TYPE_BUY; - while (true) { - var ticker = _C(e.GetTicker); - var tradePrice = 0; - if (isBuy) { - tradePrice = _N((mode === 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4); - } else { - tradePrice = _N((mode === 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4); - } - if (!orderId) { - if (isFirst) { - isFirst = false; - } else { - nowAccount = GetAccount(e, true); - } - var doAmount = 0; - if (isBuy) { - diffMoney = _N(initAccount.Balance - nowAccount.Balance, 4); - dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 8); // 如果保留小数过少,会引起在小交易量交易时,计算出的成交价格误差较大。 - doAmount = Math.min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance * 0.95) / tradePrice, 4)); - } else { - diffMoney = _N(nowAccount.Balance - initAccount.Balance, 4); - dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 8); - doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); - } - if (doAmount < _GetMinStocks) { - break; - } - prePrice = tradePrice; - orderId = tradeFunc(tradePrice, doAmount, ticker); - if (!orderId) { - CancelPendingOrders(e, tradeType); - } - } else { - if (mode === 0 || (Math.abs(tradePrice - prePrice) > maxSpace)) { - orderId = null; - } - var order = StripOrders(e, orderId); - if (!order) { - orderId = null; - } - } - Sleep(retryDelay); - } - - if (dealAmount <= 0) { - return null; - } - - return { - price: _N(diffMoney / dealAmount, 4), - amount: dealAmount - }; -} - -$.Buy = function(e, amount) { - if (typeof(e) === 'number') { - amount = e; - e = exchange; - } - return Trade(e, ORDER_TYPE_BUY, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); -}; - -$.Sell = function(e, amount) { - if (typeof(e) === 'number') { - amount = e; - e = exchange; - } - return Trade(e, ORDER_TYPE_SELL, amount, OpMode, SlidePrice, MaxAmount, MaxSpace, RetryDelay); -}; - -$.CancelPendingOrders = function(e, orderType) { - if (typeof(orderType) === 'undefined') { - if (typeof(e) === 'number') { - orderType = e; - e = exchange; - } else if (typeof(e) === 'undefined') { - e = exchange; - } - } - return CancelPendingOrders(e, orderType); -}; - -$.GetAccount = function(e) { - if (typeof(e) === 'undefined') { - e = exchange; - } - return _C(e.GetAccount); -}; - -var _MACalcMethod = [TA.EMA, TA.MA, talib.KAMA][MAType]; - -// 返回上穿的周期数. 正数为上穿周数, 负数表示下穿的周数, 0指当前价格一样 -$.Cross = function(a, b) { - var crossNum = 0; - var arr1 = []; - var arr2 = []; - if (Array.isArray(a)) { - arr1 = a; - arr2 = b; - } else { - var records = null; - while (true) { - records = exchange.GetRecords(); - if (records && records.length > a && records.length > b) { - break; - } - Sleep(RetryDelay); - } - arr1 = _MACalcMethod(records, a); - arr2 = _MACalcMethod(records, b); - } - if (arr1.length !== arr2.length) { - throw "array length not equal"; - } - for (var i = arr1.length-1; i >= 0; i--) { - if (typeof(arr1[i]) !== 'number' || typeof(arr2[i]) !== 'number') { - break; - } - if (arr1[i] < arr2[i]) { - if (crossNum > 0) { - break; - } - crossNum--; - } else if (arr1[i] > arr2[i]) { - if (crossNum < 0) { - break; - } - crossNum++; - } else { - break; - } - } - return crossNum; -}; - -// 期货部分 -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) && direction == PD_LONG) || ((positions[i].Type == PD_SHORT) && 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; - var step = 0; - while (true) { - var needOpen = opAmount; - if (isFirst) { - isFirst = false; - } else { - positionNow = GetPosition(e, contractType, direction); - if (positionNow) { - needOpen = opAmount - (positionNow.Amount - initAmount); - } - } - if (needOpen < 1) { - break; - } - if (step > max_open_lv) { - break; - } - var amount = needOpen; - e.SetDirection(direction == PD_LONG ? "buy" : "sell"); - var orderId; - if (direction == PD_LONG) { - orderId = e.Buy(price + F_SlidePrice * (1 + step), amount, "开多仓", contractType, price); - } else { - orderId = e.Sell(price - F_SlidePrice * (1 + step), amount, "开空仓", contractType, price); - } - while (true) { - var orders = _C(e.GetOrders); - if (orders.length === 0) { - break; - } - Sleep(Interval); - for (var j = 0; j < orders.length; j++) { - e.CancelOrder(orders[j].Id); - if (j < (orders.length - 1)) { - Sleep(Interval); - } - } - } - step += lv; - } - 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, OP_amount, direction) { - var initP = null; - var positions = null; - var isFirst = true; - var ID = null; - var step = 0; - var index = 0; - while (true) { - var n = 0; - positions = _C(e.GetPosition); - if (isFirst === true) { - if (typeof(direction) === 'undefined' && positions.length > 1 || (direction !== PD_LONG && direction !== PD_SHORT && typeof(direction) !== 'undefined')) { - throw "有多,空双向持仓,并且参数direction未明确方向!或 direction 参数异常:" + direction; - } - initP = positions; - isFirst = false; - } - for (var i = 0; i < positions.length; i++) { - if (positions[i].ContractType != contractType || (positions[i].Type !== direction && typeof(direction) !== 'undefined')) { - continue; - } - var amount = 0; - if (typeof(OP_amount) === 'undefined') { - amount = positions[i].Amount; - } else { - amount = OP_amount - (initP[i].Amount - positions[i].Amount); - } - - if (amount === 0) { - continue; - } - if (positions[i].Type == PD_LONG) { - e.SetDirection("closebuy"); - ID = e.Sell(price - F_SlidePrice * (1 + step), amount, "平多仓", contractType, price); - n++; - } else if (positions[i].Type == PD_SHORT) { - e.SetDirection("closesell"); - ID = e.Buy(price + F_SlidePrice * (1 + step), amount, "平空仓", contractType, price); - n++; - } - index = i; - } - if (n === 0) { - break; - } - Sleep(Interval); - if (typeof(ID) !== 'number') { - Log("ID:", ID); - continue; - } - - e.CancelOrder(ID); - step += lv; - if (step > max_cover_lv) { - break; - } - } - - var nowP = _C(e.GetPosition); - if (!nowP[index] || nowP[index].Type !== initP[index].Type) { - return initP.length === 0 ? 0 : initP[index].Amount; - } else { - var diff = initP[index].Amount - nowP[index].Amount; - return diff; - } -} - -var PositionManager = (function() { - function PositionManager(e) { - if (typeof(e) === 'undefined') { - e = exchange; - } - if (e.GetName() !== 'Futures_OKCoin' && e.GetName() !== 'Futures_BitVC') { - throw 'Only support Futures_OKCoin & Futures_BitVC'; - } - 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); - }; - - 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, OP_amount, direction) { - if (!this.account) { - this.account = _C(exchange.GetAccount); - } - return Cover(this.e, contractType, price, OP_amount, direction); - }; - - PositionManager.prototype.Profit = function(contractType) { - var accountNow = _C(this.e.GetAccount); - Log("NOW:", accountNow, "--account:", this.account); - return _N(accountNow.Balance - this.account.Balance); - }; - - return PositionManager; -})(); - -$.NewPositionManager = function(e) { - return new PositionManager(e); -}; - -// $.CTA 函数 -$.CTA = function(Exchange, MinStock, onTick, interval){ - if(typeof(interval) !== "number"){ - interval = 500 - } - - var lastUpdate = 0 - var e = Exchange - var pair = e.GetCurrency() - var hold = 0 - var tradeInfo = null - var initAccount = _C(e.GetAccount) - var nowAccount = initAccount - - var CTAshowTable = function(r){ - var tbl = { - type : "table", - title : "策略信息,交易对" + pair, - cols : ["变量", "值"], - rows : [], - } - tbl.rows.push(["初始账户:", initAccount]) - tbl.rows.push(["当前账户:", nowAccount]) - tbl.rows.push(["上次交易信息:", tradeInfo]) - tbl.rows.push(["持仓:", hold]) - tbl.rows.push(["最新K线柱:", r[r.length - 1]]) - tbl.rows.push(["Bar 数量:", r.length]) - LogStatus(_D() + '\n`' + JSON.stringify([tbl]) + '`') - } - - Log("$.CTA 初始化 完成。") - - while(true){ - var ts = new Date().getTime() - - var r = e.GetRecords() - if(!r || r.length == 0){ - continue - } - - hold = nowAccount.Stocks - initAccount.Stocks - if(Math.abs(hold) < MinStock){ - hold = 0 - } - var n = onTick(r, hold, pair) - var callBack = null - if (typeof(n) == 'object' && typeof(n.length) == 'number' && n.length > 1) { - if (typeof(n[1]) == 'function') { - callBack = n[1] - } - n = n[0] - } - if(typeof(n) !== "number"){ - if(isCTAshowTable){ - CTAshowTable(r) - } - continue - } - - if(n > 0){ // buy - if(hold < 0){ - Log("平仓") // 测试 - tradeInfo = $.Buy(e, Math.min(-hold, n)) - if(typeof(callBack) == 'function'){ - callBack(tradeInfo) - } - n += hold - } - if(n > 0){ - Log("开仓 或 反手") // 测试 - tradeInfo = $.Buy(e, n) - if(typeof(callBack) == 'function'){ - callBack(tradeInfo) - } - } - nowAccount = _C(e.GetAccount) - }else if(n < 0){ // sell - if(hold > 0){ - Log("平仓") // 测试 - tradeInfo = $.Sell(e, Math.min(hold, -n)) - if(typeof(callBack) == 'function'){ - callBack(tradeInfo) - } - n += hold - } - if(n < 0){ - Log("开仓 或 反手") // 测试 - tradeInfo = $.Sell(e, -n) - if(typeof(callBack) == 'function'){ - callBack(tradeInfo) - } - } - nowAccount = _C(e.GetAccount) - }else{ // keep balance - // nowAccount = _C(e.GetAccount) - if(hold > 0){ - tradeInfo = $.Sell(e, hold) - if(typeof(callBack) == 'function'){ - callBack(tradeInfo) - } - nowAccount = _C(e.GetAccount) - }else if(hold < 0){ - tradeInfo = $.Buy(e, -hold) - if(typeof(callBack) == 'function'){ - callBack(tradeInfo) - } - nowAccount = _C(e.GetAccount) - } - } - - if(isCTAshowTable){ - CTAshowTable(r) - } - - Sleep(interval) - } -} - - - -// 测试代码 -/* -2017.5.1 - 2017.10.11 , K线 天, 模拟级别, OK国际 , BTC -*/ -function main() { - $.CTA(exchanges[0], 0.01, function(r, mp, pair){ // $.CTA = function(Exchange, MinStock, onTick, interval) - // Log(r.length) // 测试 - if (r.length < 20) { - return - } - var emaSlow = TA.EMA(r, 20) - var emaFast = TA.EMA(r, 5) - var cross = _Cross(emaFast, emaSlow); - - if (mp <= 0 && cross > 1) { - Log(pair, "买, 金叉周期", cross, "mp:", mp); - return 0.1 * (mp < 0 ? 2 : 1) - } else if (mp >= 0 && cross < -1) { - Log(pair, "卖, 死叉周期", cross, "mp:", mp); - return -0.1 * (mp > 0 ? 2 : 1) - } - }) -} - -``` - -> 策略出处 - -https://www.fmz.com/strategy/57267 - -> 更新时间 - -2018-03-05 12:56:46 diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\350\207\252\351\200\202\345\272\224\345\235\207\347\272\277\344\272\244\346\230\223\347\263\273\347\273\237\344\273\245\345\217\212KAMA\347\256\227\346\263\225\350\247\243\346\236\220\342\200\224\342\200\224\345\237\272\344\272\216\345\217\221\346\230\216\350\200\205\351\207\217\345\214\226\344\272\244\346\230\223\350\275\257\344\273\266.md" "b/\346\225\260\345\255\227\350\264\247\345\270\201\350\207\252\351\200\202\345\272\224\345\235\207\347\272\277\344\272\244\346\230\223\347\263\273\347\273\237\344\273\245\345\217\212KAMA\347\256\227\346\263\225\350\247\243\346\236\220\342\200\224\342\200\224\345\237\272\344\272\216\345\217\221\346\230\216\350\200\205\351\207\217\345\214\226\344\272\244\346\230\223\350\275\257\344\273\266.md" index fa17647f..9020a12c 100644 --- "a/\346\225\260\345\255\227\350\264\247\345\270\201\350\207\252\351\200\202\345\272\224\345\235\207\347\272\277\344\272\244\346\230\223\347\263\273\347\273\237\344\273\245\345\217\212KAMA\347\256\227\346\263\225\350\247\243\346\236\220\342\200\224\342\200\224\345\237\272\344\272\216\345\217\221\346\230\216\350\200\205\351\207\217\345\214\226\344\272\244\346\230\223\350\275\257\344\273\266.md" +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\350\207\252\351\200\202\345\272\224\345\235\207\347\272\277\344\272\244\346\230\223\347\263\273\347\273\237\344\273\245\345\217\212KAMA\347\256\227\346\263\225\350\247\243\346\236\220\342\200\224\342\200\224\345\237\272\344\272\216\345\217\221\346\230\216\350\200\205\351\207\217\345\214\226\344\272\244\346\230\223\350\275\257\344\273\266.md" @@ -9,132 +9,9 @@ Hukybo > 策略描述 -# 1、自适应均线KAMA简介 - -顾名思义自适应均线(KAMA)属于移动平均线(Moving Average)类别,但是与传统移动平均线不一样的是它很“聪明”。我们知道普通均线有很多缺点,比如:短期均线贴近价格走势,非常敏感,但是很容易产生虚假信号;长期均线在趋势判断上非常准确,但是往往行情已经走了一段,它才反应过来。 - -KAMA的“聪明”就体现在,它能根据当前的市场状态,也就是波动率,来自主调节敏感性。其变现形式就是:在震荡行情中,KAMA的变化明显减慢;当趋势来临的时候,又反应迅速。那么在实盘中,它的好处就是:既能减少因“日常杂波”产生的交易成本,又能在行情起飞时及时上车。 - -# 2、图表中的KAMA - ![IMG](https://www.fmz.com/upload/asset/39cae99a1e12e456fa33.png) - - -# 3、KAMA的计算方法 - -- 方向(DIR) = 收盘价 - n日前收盘价 -- 波动率(VIR) = sum(abs(收盘价 - 上一个交易日收盘价), n) -- 效率(ER) = 方向 / 波动率 -- 快速 = 2 / (n1 + 1) -- 慢速 = 2 / (n2 + 1) -- 平滑(CS) = 效率 * (快速 - 慢速) + 慢速 -- 系数(CQ) = 平滑 * 平滑 -- KAMA = 指数加权平均(动态移动平均(收盘价, 系数), 2) - -其中,n、n1、n2都是周期参数,默认情况下n周期数是10,n1是短期周期数为2,n2是长期周期数为30。这也是KAMA作者Perry Kaufman认同的一组参数,n用于方向和波动率计算效率,n1和n2是快速均线和慢速均线的周期数,理论上n1的参数越大,KAMA就越平滑。 - -KAMA的计算方法是:首先计算出方向(DIR)和波动率(VIR),然后在跟两者的比例计算出效率。效率(ER)是衡量价格的变化程度,计算方式也很简单:方向 / 波动率。计算结果是0~1之间,当ER的值越接近0表明市场处于震荡状态,当ER的值越接近1表明市场处于趋势状态。 - -当计算出效率(ER)就可以结合快速均线和慢速均线推导出平滑常数(CS):效率 * (快速 - 慢速) + 慢速。CS代表了趋势运行的速度,根据CS的计算公式,我们可以发现,CS的变化始终与ER的变化成正比。 - -然后根据平滑的乘方计算出系数(CQ),其目的是使慢周期参数在计算中起到更重要的作用,这也是一个较为保守的做法。KAMA最终的平滑程度是由系数(CQ)决定,在KAMA的计算中,系数(CQ)决定了最后两次均线平滑的周期参数,即:指数加权平均(动态移动平均(收盘价, 系数), 2)。 - -# 4、如何使用KAMA - -尽管KAMA的计算方法非常复杂,但是使用方法与普通均线类似,在实际应用中,它不仅可以判断行情走势,还可以用于精确的买卖点。由于它非常“聪明”,可以用于很多交易策略中,甚至在数字货币中也值得一试。 - -- 当价格大于KAMA,并且KAMA向上时,多头开仓。 -- 当价格小于KAMA,并且KAMA向下时,空头开仓。 -- 当价格小于KAMA,或者KAMA向下时,多头平仓。 -- 当价格大于KAMA,或者KAMA向上时,空头平仓。 - -# 5、基于KAMA构建交易策略 - -**第一步:计算KAMA** -注意!在左上角选择编程语言为:`My语言`。在talib库中已经有现成的KAMA,但是它只有一个外部参数(n)周期,n1和n2已经默认为2和30。本篇中的策略只作抛砖引玉直接使用,动手能力强的小伙伴也可以自己写哈。那么在My语言中也可以直接与JavaScript语言混合,注意看下面的代码: -``` -%% // My语言内JavaScript的标准格式 -scope.KAMA = function() { - var r = _C(exchange.GetRecords); // 获取K线数组 - if (r.length > 140) { // 过滤K线长度 - var kama = talib.KAMA(r, 140); // 调用talib库计算KAMA - return kama[kama.length - 2]; // 返回KAMA的具体数值 - } - return; -} -%% // My语言内JavaScript的标准格式 -``` - -**第二步:计算交易条件并下单** -``` -%% -scope.KAMA = function() { - var r = _C(exchange.GetRecords); - if (r.length > 140) { - var kama = talib.KAMA(r, 140); - return kama[kama.length - 2]; - } - return; -} -%% - -K^^KAMA; // 把KAMA打印到图表上 -A:CLOSE; // 把收盘价打印到图表上 - -K > REF(K, 1) && CLOSE > K,BK; // 开多 -K < REF(K, 1) && CLOSE < K,SK; // 开空 -K < REF(K, 1) || CLOSE < K,SP; // 平多 -K > REF(K, 1) || CLOSE > K,BP; // 平空 -``` - -**第三步:设置策略信号过滤方式** -``` -%% -scope.KAMA = function() { - var r = _C(exchange.GetRecords); - if (r.length > 140) { - var kama = talib.KAMA(r, 140); - return kama[kama.length - 2]; - } - return; -} -%% - -K^^KAMA; -A:CLOSE; - -K > REF(K, 1) && CLOSE > K,BK; -K < REF(K, 1) && CLOSE < K,SK; -K < REF(K, 1) || CLOSE < K,SP; -K > REF(K, 1) || CLOSE > K,BP; - -AUTOFILTER; // 启用一开一平信号过滤机制 -``` - -[点击复制完整策略源码](https://www.fmz.com/strategy/155663) - -# 6、策略回测 - -为了更接近真实的交易环境,我们在回测时采用开平仓各2跳的滑点来压力测试,测试环境如下: - -- 交易所:BitMEX -- 行情品种:XBTUSD -- 交易品种:XBTUSD -- 时间:2017年07月01日~2019年07月01日 -- K线周期:日线 -- 滑点:开平仓各2跳 - -**测试环境** - ![IMG](https://www.fmz.com/upload/asset/399923632ea2b1e1ebc8.png) -**收益明细** - ![IMG](https://www.fmz.com/upload/asset/3a2eb03e368a8b48d9d0.png) -**资金曲线** - ![IMG](https://www.fmz.com/upload/asset/39c54ce3928c3c8c15cb.png) - -单从上面的回测结果看,这个简单的KAMA策略果然不负众望,即使在数字货币2018年的超级大熊市中,资金曲线并没有出现较大的回撤,并且在行情长期处于震荡时期,也没有来回开平仓,造成不必要的亏损。同时在2019年的牛市中也有不错的表现。 - -# 7、总结 - -一个优秀的可以实盘的策略一定是经过千锤百炼的打磨,本篇中的策略还有很多可以优化升级的空间,比如增加一定的过滤条件、主动的止盈止损条件等等。作为均线的一种,KAMA继承了普通均线优缺点,同时又进行了升华。在一个变化莫测的市场,即便是固定一个“最好的参数”也很难适应未来的行情,因此这种随势而动,随行情变化而变化的方法或许是一个更好的选择。 +**策略简介** +顾名思义自适应均线(KAMA)属于移动平均线(Moving Average)类别,但是与传统移动平均线不一样的是它很“聪明”。我们知道普通均线有很多缺点,比如:短期均线贴近价格走势,非常敏感,但是很容易产生虚假信号;长期均线在趋势判断上非常准确,但是往往行情已经走了一段,它才反应过来。KAMA的“聪明”就体现在,它能根据当前的市场状态,也就是波动率,来自主调节敏感性。其变现形式就是:在震荡行情中,KAMA的变化明显减慢;当趋势来临的时候,又反应迅速。那么在实盘中,它的好处就是:既能减少因“日常杂波”产生的交易成本,又能在行情起飞时及时上车。 +点击:[阅读更加详细的策略介绍](https://www.fmz.com/digest-topic/4011) @@ -177,4 +54,4 @@ https://www.fmz.com/strategy/155663 > 更新时间 -2019-07-06 16:36:04 +2019-07-16 16:50:15 diff --git "a/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245|Standard deviation price channel strategy.md" "b/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245|Standard deviation price channel strategy.md" index 05bd0ea9..3383a35e 100644 --- "a/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245|Standard deviation price channel strategy.md" +++ "b/\346\240\207\345\207\206\345\267\256\344\273\267\346\240\274\351\200\232\351\201\223\347\255\226\347\225\245|Standard deviation price channel strategy.md" @@ -12,7 +12,6 @@ littleDreamXX [trans] - 数据周期:30分钟左右 - 支持 数字货币现货、数字货币期货 -- 支持 商品期货,适合品种:热卷、焦炭、豆粕、郑醇、沪镍、郑油、聚丙烯、螺纹、橡胶、锰硅、PTA、豆油 - 官方网站:www.quantinfo.com 商品期货回测 @@ -107,4 +106,4 @@ https://www.fmz.com/strategy/128121 > 更新时间 -2018-12-15 15:41:45 +2019-08-20 11:02:10 diff --git "a/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245|PBX Strategy.md" "b/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245|PBX Strategy.md" index 086784dd..3141972b 100644 --- "a/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245|PBX Strategy.md" +++ "b/\347\200\221\345\270\203\347\272\277\347\255\226\347\225\245|PBX Strategy.md" @@ -12,7 +12,7 @@ littleDreamXX [trans] - 策略名称:瀑布线PUBU交易策略 - 数据周期:15M -- 支持:商品期货 +- 支持:商品期货 , 数字货币 - 官方网站:www.quantinfo.com ![IMG](https://www.fmz.com/upload/asset/3ba2dba0c6b01773b2c296438ff77d25.png) @@ -82,4 +82,4 @@ https://www.fmz.com/strategy/128420 > 更新时间 -2018-12-17 17:54:10 +2019-08-20 10:24:12 diff --git "a/\350\277\220\347\224\250\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\214\207\346\240\207\345\234\250\346\225\260\345\255\227\350\264\247\345\270\201\344\270\255\351\207\217\345\214\226\344\272\244\346\230\223\357\274\214\351\231\204\345\270\246My\350\257\255\350\250\200\347\255\226\347\225\245\346\272\220\347\240\201.md" "b/\350\277\220\347\224\250\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\214\207\346\240\207\345\234\250\346\225\260\345\255\227\350\264\247\345\270\201\344\270\255\351\207\217\345\214\226\344\272\244\346\230\223\357\274\214\351\231\204\345\270\246My\350\257\255\350\250\200\347\255\226\347\225\245\346\272\220\347\240\201.md" index 03c424e4..ebe3eb8c 100644 --- "a/\350\277\220\347\224\250\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\214\207\346\240\207\345\234\250\346\225\260\345\255\227\350\264\247\345\270\201\344\270\255\351\207\217\345\214\226\344\272\244\346\230\223\357\274\214\351\231\204\345\270\246My\350\257\255\350\250\200\347\255\226\347\225\245\346\272\220\347\240\201.md" +++ "b/\350\277\220\347\224\250\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\214\207\346\240\207\345\234\250\346\225\260\345\255\227\350\264\247\345\270\201\344\270\255\351\207\217\345\214\226\344\272\244\346\230\223\357\274\214\351\231\204\345\270\246My\350\257\255\350\250\200\347\255\226\347\225\245\346\272\220\347\240\201.md" @@ -9,97 +9,10 @@ Hukybo > 策略描述 -# 1、阿隆指标简介 +**策略简介** +本策略基于My语言,可用于商品期货和数字货币。在技术分析中阿隆(Aroon)是一个很独特的技术指标,“Aroon”一词来自梵文,寓意为“黎明曙光”。它不像MA、MACD、KDJ那样广为人所熟悉,它推出的时间更晚,直到1995年才被图莎尔·钱德(Tushar Chande)发明出来,作者还发明了钱德动量摆动指标(CMO)和日内动量指数(IMI)。如果说一个技术指标知道的人越多,使用的人也越多,那么其赚钱能力也越低,那么相对新颖的阿隆指标则恰恰相反,站在这个角度看这是一个不错的选择。 -本篇文章根据[阿隆(Aroon)技术指标在量化交易中的应用](https://www.fmz.com/strategy/154547)中的策略改编为数字货币,并且基于My语言。在技术分析中阿隆(Aroon)是一个很独特的技术指标,“Aroon”一词来自梵文,寓意为“黎明曙光”。它不像MA、MACD、KDJ那样广为人所熟悉,它推出的时间更晚,直到1995年才被图莎尔·钱德(Tushar Chande)发明出来,作者还发明了钱德动量摆动指标(CMO)和日内动量指数(IMI)。如果说一个技术指标知道的人越多,使用的人也越多,那么其赚钱能力也越低,那么相对新颖的阿隆指标则恰恰相反,站在这个角度看这是一个不错的选择。 - -# 2、图表中的阿隆指标 - -阿隆指标通过计算当前K线距离前最高价和最低价之间的K线数量,来帮助交易者预测价格走势与趋势区域的相对位置关系变化。它有两部分组成,即:阿隆上线(AroonUp)和阿隆下线(AroonDown),这两条线在0~100之间上下移动,虽然命名为上线和下线,但从图表上看并不像BOLL指标那样是真正意义上的上线和下线。如下图就是阿隆指标: - ![IMG](https://www.fmz.com/upload/asset/38df067f317f4f5cce2b.png) - -# 3、阿隆指标的计算方法 - -阿隆指标要求首先要设置一个时间周期参数,就像设置均线周期参数一样,在传统行情软件中,这个周期数是14,当然这个周期参数并不是固定的,你还可以设置为10或者50等等。为了方便理解,暂且把这个时间周期参数定义为:N。确定N之后,我们就可以计算出阿隆上线(AroonUp)和阿隆下线(AroonDown),具体的计算公式如下: - -- 阿隆上线(AroonUp) = [ ( 设置的周期参数 - 最高价后的周期数 ) / 计算的周期数 ] * 100 -- 阿隆下线(AroonDown) = [ ( 设置的周期参数 - 最低价后的周期数 ) / 计算的周期数 ] * 100 - -从这个公式中,我们就能大致看出,阿隆指标的思想。那就是:有多少个周期,价格在近期高 / 低点之下,辅助预测当前趋势是否会延续,同时衡量当前趋势的强弱。如果我们把这个指标归类的话,很明显它是属于趋势跟踪类型。但是与其他趋势跟踪型指标不同的是,它更重视时间而不是价格。 - -# 4、如何使用阿隆指标 - -阿隆上线(AroonUp)和阿隆下线(AroonDown)反映的是当前时间与之前最高价或最低价的远近,如果时间越近值就越大,如果时间越远值就越小。并且当两条线发生交叉就预示着价格方向可能会发生改变,如果AroonUp在AroonDown之上说明价格处于上涨趋势,未来价格可能会进一步上涨;如果AroonDown在AroonUp之上说明价格处于下跌趋势,未来价格可能会进一步下跌。 - -同时我们还可以设置几个固定的值,来精确入场时机。我们知道阿隆指标是一直在0~100之间上下运行,那么在市场处于上涨趋势,也就是AroonUp在AroonDown之上时,当AroonUp大于50,说明市场上涨的趋势已经形成,未来价格可能会继续上涨;当AroonUp下穿50时,说明价格上涨的动力正在减弱,未来价格可能会震荡和下跌。 - -反之在市场处于下跌趋势,也就是AroonDown在AroonUp之上时,当AroonDown大于50,说明市场下跌趋势已经形成,未来价格可能会继续下跌;当AroonDown下穿50时,说明价格下跌的动力正在减弱,未来价格可能会震荡和上涨。那么根据上面两段理论,我们可以把买卖条件罗列为: - -- 当 AroonUp大于AroonDown,并且AroonUp大于50,多头开仓; -- 当 AroonUp小于AroonDown,或者AroonUp小于50,多头平仓; -- 当 AroonDown大于AroonUp,并且AroonDown大于50,空头开仓; -- 当 AroonDown小于AroonUp,或者AroonDown小于50,空头平仓; - -# 5、基于阿隆指标构建交易策略 - -理清交易逻辑后,我们就可以用代码去实现了,本篇我们改用My语言,品种则换成比特币。动手能力强的小伙伴,也可以把代码翻译成JavaScript语言。OK,话不多说,依次打开:fmz.com > 登录 > 控制中心 > 策略库 > 新建策略,开始编写策略,注意看下面代码中的注释。 - -**第一步:计算阿隆指标** -注意!在左上角选择编程语言为:`My语言`。 -``` -AROONUP := ((N - HHVBARS(H, N)) / N) * 100; // 阿隆指标上线 -AROONDOWN := ((N - LLVBARS(L, N)) / N) * 100; // 阿隆指标下线 -``` - -**第二步:计算交易条件并下单** -``` -AROONUP := ((N - HHVBARS(H, N)) / N) * 100; // 阿隆指标上线 -AROONDOWN := ((N - LLVBARS(L, N)) / N) * 100; // 阿隆指标下线 -AROONUP > AROONDOWN && AROONUP > BKV, BK; // 多头开仓 -AROONDOWN > AROONUP && AROONDOWN > SKV, SK; // 空头开仓 -AROONUP < AROONDOWN || AROONUP < SPV, SP; // 多头平台 -AROONDOWN < AROONUP || AROONDOWN < BPV, BP; // 空头平台 -``` - -**第三步:设置策略信号过滤方式** -``` -AROONUP := ((N - HHVBARS(H, N)) / N) * 100; // 阿隆指标上线 -AROONDOWN := ((N - LLVBARS(L, N)) / N) * 100; // 阿隆指标下线 -AROONUP > AROONDOWN && AROONUP > BKV, BK; // 多头开仓 -AROONDOWN > AROONUP && AROONDOWN > SKV, SK; // 空头开仓 -AROONUP < AROONDOWN || AROONUP < SPV, SP; // 多头平台 -AROONDOWN < AROONUP || AROONDOWN < BPV, BP; // 空头平台 -AUTOFILTER; -``` - -[点击复制完整策略源码](https://www.fmz.com/strategy/155582) - -# 6、策略回测 - -为了更接近真实的交易环境,我们在回测时采用开平仓各2跳的滑点来压力测试,测试环境如下: - -- 行情品种:BTC -- 交易品种:BTC -- 时间:2019年01月01日~2019年07月05日 -- 周期:日线 -- 滑点:开平仓各2跳 - -**测试环境** - ![IMG](https://www.fmz.com/upload/asset/3a3b8ebd1d15f0dad5ff.png) -**收益明细** - ![IMG](https://www.fmz.com/upload/asset/399bd1e8a5207430601c.png) -**资金曲线** - ![IMG](https://www.fmz.com/upload/asset/39211cdf3a96eb811657.png) -从上面的回测结果看,策略在市场行情走势流畅的时候表现很好,无论是在上涨或下跌中,阿隆指标可以完整的跟踪到行情。资金曲线也整体走势向上,并没有出现较大幅度的回撤。但是在震荡行情中,特别是连续的震荡行情中,出现了局部回撤。 - -# 7、阿隆指标的优缺点 - -- 优点:阿隆指标可以判断趋势行情的状态,兼顾发现市场趋势行情以及判断价格转向的能力,帮助交易者提高资金的使用率,这个优势震荡行情中尤为重要。 -- 缺点:阿隆指标只是趋势跟踪系列指标中的一种,同样也有趋势跟踪指标的缺点。并且它只判断指定时间最高价或最低价的周期数,但有时候最高价或最低价在整个行情走势中会有偶然性,这个偶然性会干扰阿隆指标本身,造成虚假信号。 - -# 8、总结 - -在策略中我们固定了一部分参数,如:aroonUp或aroonDown大于小于50,造成策略的滞后性,很多情况下是行情上涨或下跌一段时间才开平仓买卖。这样虽然提高了胜率,减少了最大回撤率,但也错过了很多收益,这也印证了盈亏同源的道理。有兴趣的朋友可以深入研究一下,并加以改进。 +点击:[阅读更加详细的策略介绍](https://www.fmz.com/digest-topic/3982) > 策略参数 @@ -136,4 +49,4 @@ https://www.fmz.com/strategy/155582 > 更新时间 -2019-07-06 09:08:52 +2019-07-16 15:50:33 diff --git "a/\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\212\200\346\234\257\346\214\207\346\240\207\345\234\250\345\225\206\345\223\201\346\234\237\350\264\247\344\270\255\347\232\204\345\272\224\347\224\250.md" "b/\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\212\200\346\234\257\346\214\207\346\240\207\345\234\250\345\225\206\345\223\201\346\234\237\350\264\247\344\270\255\347\232\204\345\272\224\347\224\250.md" index 9ac7bb1d..c044e984 100644 --- "a/\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\212\200\346\234\257\346\214\207\346\240\207\345\234\250\345\225\206\345\223\201\346\234\237\350\264\247\344\270\255\347\232\204\345\272\224\347\224\250.md" +++ "b/\351\230\277\351\232\206\357\274\210Aroon\357\274\211\346\212\200\346\234\257\346\214\207\346\240\207\345\234\250\345\225\206\345\223\201\346\234\237\350\264\247\344\270\255\347\232\204\345\272\224\347\224\250.md" @@ -9,136 +9,10 @@ Hukybo > 策略描述 -# 1、阿隆指标简介 +**策略简介** +本策略基于JavaScript语言,可用于商品期货。在技术分析中阿隆(Aroon)是一个很独特的技术指标,“Aroon”一词来自梵文,寓意为“黎明曙光”。它不像MA、MACD、KDJ那样广为人所熟悉,它推出的时间更晚,直到1995年才被图莎尔·钱德(Tushar Chande)发明出来,作者还发明了钱德动量摆动指标(CMO)和日内动量指数(IMI)。如果说一个技术指标知道的人越多,使用的人也越多,那么其赚钱能力也越低,那么相对新颖的阿隆指标则恰恰相反,站在这个角度看这是一个不错的选择。 -在技术分析中阿隆(Aroon)是一个很独特的技术指标,“Aroon”一词来自梵文,寓意为“黎明曙光”。它不像MA、MACD、KDJ那样广为人所熟悉,它推出的时间更晚,直到1995年才被图莎尔·钱德(Tushar Chande)发明出来,作者还发明了钱德动量摆动指标(CMO)和日内动量指数(IMI)。如果说一个技术指标知道的人越多,使用的人也越多,那么其赚钱能力也越低,那么相对新颖的阿隆指标则恰恰相反,站在这个角度看这是一个不错的选择。 - -# 2、图表中的阿隆指标 - -阿隆指标通过计算当前K线距离前最高价和最低价之间的K线数量,来帮助交易者预测价格走势与趋势区域的相对位置关系变化。它有两部分组成,即:阿隆上线(AroonUp)和阿隆下线(AroonDown),这两条线在0~100之间上下移动,虽然命名为上线和下线,但从图表上看并不像BOLL指标那样是真正意义上的上线和下线。如下图就是阿隆指标: - ![IMG](https://www.fmz.com/upload/asset/395eac8a5478d8736104.png) - -# 3、阿隆指标的计算方法 - -阿隆指标要求首先要设置一个时间周期参数,就像设置均线周期参数一样,在传统行情软件中,这个周期数是14,当然这个周期参数并不是固定的,你还可以设置为10或者50等等。为了方便理解,暂且把这个时间周期参数定义为:N。确定N之后,我们就可以计算出阿隆上线(AroonUp)和阿隆下线(AroonDown),具体的计算公式如下: - -- 阿隆上线(AroonUp) = [ ( 设置的周期参数 - 最高价后的周期数 ) / 计算的周期数 ] * 100 -- 阿隆下线(AroonDown) = [ ( 设置的周期参数 - 最低价后的周期数 ) / 计算的周期数 ] * 100 - -从这个公式中,我们就能大致看出,阿隆指标的思想。那就是:有多少个周期,价格在近期高 / 低点之下,辅助预测当前趋势是否会延续,同时衡量当前趋势的强弱。如果我们把这个指标归类的话,很明显它是属于趋势跟踪类型。但是与其他趋势跟踪型指标不同的是,它更重视时间而不是价格。 - -# 4、如何使用阿隆指标 - -阿隆上线(AroonUp)和阿隆下线(AroonDown)反映的是当前时间与之前最高价或最低价的远近,如果时间越近值就越大,如果时间越远值就越小。并且当两条线发生交叉就预示着价格方向可能会发生改变,如果AroonUp在AroonDown之上说明价格处于上涨趋势,未来价格可能会进一步上涨;如果AroonDown在AroonUp之上说明价格处于下跌趋势,未来价格可能会进一步下跌。 - -同时我们还可以设置几个固定的值,来精确入场时机。我们知道阿隆指标是一直在0~100之间上下运行,那么在市场处于上涨趋势,也就是AroonUp在AroonDown之上时,当AroonUp大于50,说明市场上涨的趋势已经形成,未来价格可能会继续上涨;当AroonUp下穿50时,说明价格上涨的动力正在减弱,未来价格可能会震荡和下跌。 - -反之在市场处于下跌趋势,也就是AroonDown在AroonUp之上时,当AroonDown大于50,说明市场下跌趋势已经形成,未来价格可能会继续下跌;当AroonDown下穿50时,说明价格下跌的动力正在减弱,未来价格可能会震荡和上涨。那么根据上面两段理论,我们可以把买卖条件罗列为: - -- 当 AroonUp大于AroonDown,并且AroonUp大于50,多头开仓; -- 当 AroonUp小于AroonDown,或者AroonUp小于50,多头平仓; -- 当 AroonDown大于AroonUp,并且AroonDown大于50,空头开仓; -- 当 AroonDown小于AroonUp,或者AroonDown小于50,空头平仓; - -# 5、基于阿隆指标构建交易策略 - -理清交易逻辑后,我们就可以用代码去实现了,本篇我们继续使用JavaScript语言,品种还是商品期货。动手能力强的小伙伴,也可以把代码翻译成Python语言,或者数字货币。OK,话不多说,依次打开:fmz.com > 登录 > 控制中心 > 策略库 > 新建策略,开始编写策略,注意看下面代码中的注释。 - -**第一步:使用CTA框架** -注意!一定要点击下方的:`商品期货交易类库`。如果你改编为数字货币就点击:`数字货币现货交易类库`。 -``` -function main() { - // ZC000/ZC888 指用指数做为行情源但交易映射到主力连续合约上 - $.CTA("ZC000/ZC888", function(st) { - - }) -} -``` - -**第二步:获取数据** -``` -function main() { - $.CTA("ZC000/ZC888", function(st) { - var r = st.records; // 获取K线数组 - var mp = st.position.amount; // 获取持仓数量 - }) -} -``` - -**第三步:计算阿隆指标** -``` -function main() { - $.CTA("ZC000/ZC888", function(st) { - var r = st.records; // 获取K线数组 - var mp = st.position.amount; // 获取持仓数量 - if (r.length < 21) { // 判断K线数据是否足够 - return; - } - var aroon = talib.AROON(r, 20); // 阿隆指标 - var aroonUp = aroon[1][aroon[1].length - 2]; // 阿隆指标上线倒数第2根数据 - var aroonDown = aroon[0][aroon[0].length - 2]; // 阿隆指标下线倒数第2根数据 - }) -} - -``` - - -**第四步:计算交易条件并下单** - -``` -function main() { - $.CTA("ZC000/ZC888", function(st) { - var r = st.records; // 获取K线数组 - var mp = st.position.amount; // 获取持仓数量 - if (r.length < 21) { // 判断K线数据是否足够 - return; - } - var aroon = talib.AROON(r, 20); // 阿隆指标 - var aroonUp = aroon[1][aroon[1].length - 2]; // 阿隆指标上线倒数第2根数据 - var aroonDown = aroon[0][aroon[0].length - 2]; // 阿隆指标下线倒数第2根数据 - if (mp == 0 && aroonUp > aroonDown && aroonUp > 50) { - return 1; // 多头开仓 - } - if (mp == 0 && aroonDown > aroonUp && aroonDown > 50) { - return -1; // 空头开仓 - } - if (mp > 0 && (aroonUp < aroonDown || aroonUp < 50)) { - return -1; // 多头平台 - } - if (mp < 0 && (aroonDown < aroonUp || aroonDown < 50)) { - return 1; // 空头平台 - } - }) -} -``` - -# 6、策略回测 - -为了更接近真实的交易环境,我们在回测时采用开平仓各2跳以及2倍的手续费来压力测试,测试环境如下: - -- 行情品种:动力煤指数 -- 交易品种:动力煤主力 -- 时间:2015年06月01日~2019年06月28日 -- 周期:日线 -- 滑点:开平仓各2跳 -- 手续费:交易所2倍 - -**测试环境** - ![IMG](https://www.fmz.com/upload/asset/39907574d57473cf986d.png) -**收益明细** - ![IMG](https://www.fmz.com/upload/asset/394305f56784dce4a690.png) -**资金曲线** - ![IMG](https://www.fmz.com/upload/asset/3a2fe000eebf1ffd7ca1.png) -从上面的回测结果看,策略在市场行情走势流畅的时候表现很好,无论是在上涨或下跌中,阿隆指标可以完整的跟踪到行情。资金曲线也整体走势向上,并没有出现较大幅度的回撤。但是在震荡行情中,特别是连续的震荡行情中,出现了局部回撤。 - -# 7、阿隆指标的优缺点 - -- 优点:阿隆指标可以判断趋势行情的状态,兼顾发现市场趋势行情以及判断价格转向的能力,帮助交易者提高资金的使用率,这个优势震荡行情中尤为重要。 -- 缺点:阿隆指标只是趋势跟踪系列指标中的一种,同样也有趋势跟踪指标的缺点。并且它只判断指定时间最高价或最低价的周期数,但有时候最高价或最低价在整个行情走势中会有偶然性,这个偶然性会干扰阿隆指标本身,造成虚假信号。 - -# 8、总结 - -在策略中我们固定了一部分参数,如:aroonUp或aroonDown大于小于50,造成策略的滞后性,很多情况下是行情上涨或下跌一段时间才开平仓买卖。这样虽然提高了胜率,减少了最大回撤率,但也错过了很多收益,这也印证了盈亏同源的道理。有兴趣的朋友可以深入研究一下,并加以改进。 +点击:[阅读更加详细的策略介绍](https://www.fmz.com/digest-topic/3982) > 策略参数 @@ -193,4 +67,4 @@ https://www.fmz.com/strategy/154547 > 更新时间 -2019-07-05 12:09:23 +2019-07-16 15:47:17 From 0b6c45ecbb5508b8d3da5438de541d77a8286937 Mon Sep 17 00:00:00 2001 From: Zero Date: Sat, 24 Aug 2019 12:29:03 +0800 Subject: [PATCH 15/19] update --- ...\226\347\225\245\344\271\213Penny Jump.md" | 346 ++++++++++++ HFT strategy.md | 299 +++++++++++ "MultDualThrust(\346\225\231\345\255\246).md" | 150 ++++++ ...71\345\206\262\347\255\226\347\225\245.md" | 497 ++++++++++++++++++ ...27\345\210\251\347\255\226\347\225\245.md" | 392 ++++++++++++++ ...36\346\210\230\345\272\224\347\224\250.md" | 54 ++ ...44\346\230\223\347\255\226\347\225\245.md" | 286 ++++++++++ ...44\346\230\223\347\255\226\347\225\245.md" | 405 ++++++++++++++ ...0\202\347\255\226\347\225\245(basefex).md" | 449 ++++++++++++++++ ...\347\225\245\350\214\203\344\276\21302.md" | 32 ++ ...44\346\230\223\347\255\226\347\225\245.md" | 256 +++++++++ ...60\345\255\227\350\264\247\345\270\201.md" | 54 ++ ...71\351\207\217\344\273\273\345\212\241.md" | 114 ++++ ...74\345\274\217\345\267\245\345\205\267.md" | 164 ++++++ ...77\345\274\217\346\265\213\350\257\225.md" | 76 +++ ...13\350\257\225\345\233\276\350\241\250.md" | 183 +++++++ ...53\345\270\201\347\202\271\345\215\241.md" | 49 ++ ...53\345\270\201\347\262\276\345\272\246.md" | 160 ++++++ ...3\346\211\200\346\220\254\347\240\226).md" | 400 ++++++++++++++ ...72\277\347\255\226\347\225\245 (Copy).md" | 72 +++ ...21\346\240\274\347\255\226\347\225\245.md" | 250 +++++++++ ...263kingkeltner\347\255\226\347\225\245.md" | 54 ++ ...36\346\210\230\346\212\200\345\267\247.md" | 43 ++ ...36\346\227\266\346\261\207\347\216\207.md" | 35 ++ ...11\351\222\211\346\216\250\351\200\201.md" | 50 ++ 25 files changed, 4870 insertions(+) create mode 100644 "C++\345\225\206\345\223\201\346\234\237\350\264\247\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213Penny Jump.md" create mode 100644 HFT strategy.md create mode 100644 "MultDualThrust(\346\225\231\345\255\246).md" create mode 100644 "OKEx\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.md" create mode 100644 "RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245.md" create mode 100644 "RangeBreak\347\255\226\347\225\245\344\270\216\346\263\242\345\212\250\347\216\207\347\233\270\347\273\223\345\220\210\347\232\204\345\256\236\346\210\230\345\272\224\347\224\250.md" create mode 100644 "\343\200\220\346\265\267\351\276\237\346\261\244\347\255\226\347\225\245\343\200\221\345\217\215\350\266\213\345\212\277\344\272\244\346\230\223\347\255\226\347\225\245.md" create mode 100644 "\343\200\220\347\273\217\345\205\270\350\266\213\345\212\277\347\255\226\347\225\245\343\200\221\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.md" create mode 100644 "\345\201\232\345\270\202\347\255\226\347\225\245(basefex).md" create mode 100644 "\345\235\207\347\272\277\347\255\226\347\225\245\350\214\203\344\276\21302.md" create mode 100644 "\345\237\272\344\272\216\346\234\237\350\264\247\345\237\272\346\234\254\351\235\242\345\210\206\346\236\220\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" create mode 100644 "\345\237\272\344\272\216\347\256\261\344\275\223\347\220\206\350\256\272\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245\357\274\214\346\224\257\346\214\201\345\225\206\345\223\201\346\234\237\350\264\247\345\222\214\346\225\260\345\255\227\350\264\247\345\270\201.md" create mode 100644 "\345\244\232\347\272\277\347\250\213\346\211\271\351\207\217\344\273\273\345\212\241.md" create mode 100644 "\346\227\266\351\227\264\346\240\274\345\274\217\345\267\245\345\205\267.md" create mode 100644 "\346\234\237\350\264\247\347\234\213\347\251\277\345\274\217\346\265\213\350\257\225.md" create mode 100644 "\346\265\213\350\257\225\345\233\276\350\241\250.md" create mode 100644 "\347\201\253\345\270\201\347\202\271\345\215\241.md" create mode 100644 "\347\201\253\345\270\201\347\262\276\345\272\246.md" create mode 100644 "\347\216\260\347\216\260\345\257\271\345\206\262(\345\244\232\344\272\244\346\230\223\346\211\200\346\220\254\347\240\226).md" create mode 100644 "\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245 (Copy).md" create mode 100644 "\347\275\221\346\240\274\347\255\226\347\225\245.md" create mode 100644 "\350\202\257\347\211\271\347\272\263\351\200\232\351\201\223\345\215\207\347\272\247\347\211\210\351\207\221\350\202\257\347\211\271\347\272\263kingkeltner\347\255\226\347\225\245.md" create mode 100644 "\350\203\275\351\207\217\346\275\256OBV\345\234\250\351\207\217\345\214\226\344\272\244\346\230\223\344\270\255\347\232\204\350\257\246\347\273\206\347\224\250\346\263\225\345\222\214\345\256\236\346\210\230\346\212\200\345\267\247.md" create mode 100644 "\350\216\267\345\217\226USDT\345\222\214USD\347\232\204\345\256\236\346\227\266\346\261\207\347\216\207.md" create mode 100644 "\351\222\211\351\222\211\346\216\250\351\200\201.md" diff --git "a/C++\345\225\206\345\223\201\346\234\237\350\264\247\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213Penny Jump.md" "b/C++\345\225\206\345\223\201\346\234\237\350\264\247\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213Penny Jump.md" new file mode 100644 index 00000000..f4eba767 --- /dev/null +++ "b/C++\345\225\206\345\223\201\346\234\237\350\264\247\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213Penny Jump.md" @@ -0,0 +1,346 @@ + +> 策略名称 + +C++商品期货高频交易策略之Penny Jump + +> 策略作者 + +Zero + +> 策略描述 + +> 高频交易分类 + +* 以最快的速度抹平市场的一切不合理现象, 常见于炒单与高频套利, 主动出击, 拼速度 +* 提前在不合理的价位埋伏并跟随市场快速移动, 常见于市商策略, 守株待兔, 拼知识面 +* 其它各种作者只学习了理论没有实盘, 先不讲 + +> 动手实现 + +* 观察盘口的概率极低的不合理现像并做出相应策略进行测试更改 +* 如果逻辑复杂, 就需要利用现有的数学知识尽可能的用模型描述不合理现象的本质, 尽量减少拟合 +* 必须用可以见量成交又可以见价成交的回测模型去验证, 发明者量化目前是唯一支持这两种回测模式的平台 +* 平台的C++例子很少, 这里就用C++写本策略, 方便大家学习 + +> 策略原理 + + 正常情况下商品期货的盘口买一卖一差价只有一跳, 偶尔会有两跳,三跳基本很少见, 主力合约交易比较频繁, 这种现像发生后瞬间消失, 难以有下手机会, 我们就把精力放到次主力合约上面,比如MA001为主力, MA909为次主力时, MA909盘口下面这种情况 + + ![IMG](https://www.fmz.com/upload/asset/10c6ef53263999aec8e.png) + + 卖一为2225量551, 买一2223量565, 向下看几秒, 出现这种情况后, 几个tick推送后消失, 这种情况,我们视为市场的自我纠正, 我们要做的就是赶在市场主动纠正前, 杀进去, 这种逻辑看人工去盯盘是天方夜谈, 因为商品期货盘口差价两跳的情况级少出现, 三跳最安全, 但三跳极少出现, 导致交易频率太低, 意义不大, 接下来, 我们观察盘口之前卖一买一与现在两跳时买一卖一的区别, 去填补盘口差价空隙, 如果速度够快, 就可以排在委托单的最前位置, 做为Maker以最快的速度成交后反手卖出, 持仓时间很短, 有了这个交易逻辑, 实现为策略以后, 以MA909为例, 实盘测试推荐易盛而非CTP接口, 易盛仓位与资金变化是推送机制, 非常适合高频 + +> 回测结果 + + ![IMG](https://www.fmz.com/upload/asset/1209a7f1c3125148a76.png) + +> 交易逻辑 + + ![IMG](https://www.fmz.com/upload/asset/e2afad523b119c9a23.png) + +> 必看声明 + +为满足对高频交易的好奇心, 为了更明显的看到结果, 此策略回测手续费设定为0, 实现了一个简单的拼速度逻辑, 想要覆盖手续费实现盈利, 实盘需做更多优化, 仅凭这个简单的逻辑很难致胜, 要考虑更多操作, 比如锁仓(降低平今手续费), 利用定单薄流进行短期预测提高胜率, 再加上交易所手续费返还, 从而实现一个可持久盈利的策略, 关于高频交易的书籍很多, 希望大家多去思考,多去实盘,而不是只停留在原理上. + +> 关于我们 + + 发明者量化是一个纯技术驱动的团队, 为量化交易爱好者提供了一个高可用的回测机制, 我们的回测机制是真实的模拟了一个交易所的存在, 而不是简单的见价撮合, 希望用户能够利用到平台的优点更好的去发挥自己的能力 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Symbol|MA909|品种| +|RetryMax|true|重试最多| +|ProfitTick|true|利润跳数| +|TolerateTick|5|容忍跳数| + + +> 源码 (cpp) + +``` cpp +/*backtest +start: 2019-08-19 09:00:00 +end: 2019-08-23 15:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","balance":10000,"minfee":0,"fee":[0,0]}] +mode: 1 +*/ + +enum State { + STATE_NA, + STATE_IDLE, + STATE_HOLD_LONG, + STATE_HOLD_SHORT, +}; + +typedef struct { + double bidPrice; + double bidAmount; + double askPrice; + double askAmount; +} Book; + +class HFT { + public: + HFT() { + _tradingDay = getTradingWeekDay(); + Log("current trading weekday", _tradingDay); + } + int getTradingWeekDay() { + int seconds = Unix() + 28800; + int hour = (seconds/3600)%24; + int weekDay = (seconds/(60*60*24))%7+4; + if (hour > 20) { + weekDay += 1; + } + return weekDay; + } + State getState() { + auto orders = exchange.GetOrders(); + if (!orders.Valid || orders.size() == 2) { + return STATE_NA; + } + + bool foundCover = false; + for (auto &order : orders) { + if (order.Id == _coverId) { + if ((order.Type == ORDER_TYPE_BUY && order.Price < _book.bidPrice - _toleratePrice) || + (order.Type == ORDER_TYPE_SELL && order.Price > _book.askPrice + _toleratePrice)) { + exchange.CancelOrder(order.Id, "Cancel Cover Order"); + _countCancel++; + _countRetry++; + } else { + foundCover = true; + } + } else { + exchange.CancelOrder(order.Id); + _countCancel++; + } + } + + if (foundCover) { + return STATE_NA; + } + + auto positions = exchange.GetPosition(); + if (!positions.Valid) { + return STATE_NA; + } + + for (auto &pos : positions) { + if (pos.ContractType == Symbol) { + _holdPrice = pos.Price; + _holdAmount = pos.Amount; + _holdType = pos.Type; + return pos.Type == PD_LONG || pos.Type == PD_LONG_YD ? STATE_HOLD_LONG : STATE_HOLD_SHORT; + } + } + return STATE_IDLE; + } + + void stop() { + Log(exchange.GetOrders()); + Log(exchange.GetPosition()); + Log("Stop"); + } + + bool Loop() { + if (exchange.IO("status") == 0) { + LogStatus(_D(), "Server not connect ...."); + Sleep(1000); + return true; + } + if (_initBalance == 0) { + _initBalance = _C(exchange.GetAccount).Balance; + } + auto day = getTradingWeekDay(); + if (day != _tradingDay) { + _tradingDay = day; + _countCancel = 0; + } + + if (_ct.is_null()) { + Log(_D(), "subscribe", Symbol); + _ct = exchange.SetContractType(Symbol); + if (!_ct.is_null()) { + auto obj = _ct["Commodity"]["CommodityTickSize"]; + int volumeMultiple = 1; + if (obj.is_null()) { // CTP + obj = _ct["PriceTick"]; + volumeMultiple = _ct["VolumeMultiple"]; + _exchangeId = _ct["ExchangeID"]; + } else { // Esunny + volumeMultiple = _ct["Commodity"]["ContractSize"]; + _exchangeId = _ct["Commodity"]["ExchangeNo"]; + } + if (obj.is_null() || obj <= 0) { + Panic("PriceTick not found"); + } + if (_priceTick < 1) { + exchange.SetPrecision(1, 0); + } + _priceTick = double(obj); + _toleratePrice = _priceTick * TolerateTick; + _ins = _ct["InstrumentID"]; + + Log(_ins, _exchangeId, "PriceTick:", _priceTick, "VolumeMultiple:", volumeMultiple); + } + Sleep(1000); + return true; + } + // Check orders and positions to set state + auto depth = exchange.GetDepth(); + if (!depth.Valid) { + LogStatus(_D(), "Market not ready"); + Sleep(1000); + return true; + } + _countTick++; + _preBook = _book; + _book.bidPrice = depth.Bids[0].Price; + _book.bidAmount = depth.Bids[0].Amount; + _book.askPrice = depth.Asks[0].Price; + _book.askAmount = depth.Asks[0].Amount; + // _book not init + if (_preBook.bidAmount == 0) { + return true; + } + auto st = getState(); + + LogStatus(_D(), _ins, "State:", st, + "Ask:", depth.Asks[0].Price, depth.Asks[0].Amount, + "Bid:", depth.Bids[0].Price, depth.Bids[0].Amount, + "Cancel:", _countCancel, + "Tick:", _countTick); + + bool forceCover = _countRetry >= _retryMax; + if (st == STATE_IDLE) { + if (_holdAmount > 0) { + if (_countRetry > 0) { + _countLoss++; + } else { + _countWin++; + } + auto account = exchange.GetAccount(); + if (account.Valid) { + LogProfit(_N(account.Balance+account.FrozenBalance-_initBalance, 2), "Win:", _countWin, "Loss:", _countLoss); + } + } + _countRetry = 0; + _holdAmount = 0; + + if (_countCancel > _cancelMax) { + Log("Cancel Exceed", _countCancel); + return false; + } + + bool canDo = false; + if (abs(_book.bidPrice - _book.askPrice) > _priceTick * 1) { + canDo = true; + } + if (!canDo) { + return true; + } + + + auto bidPrice = depth.Bids[0].Price; + auto askPrice = depth.Asks[0].Price; + auto bidAmount = 1.0; + auto askAmount = 1.0; + + if (_preBook.bidPrice > _book.bidPrice && _book.askAmount < _book.bidAmount) { + bidPrice += _priceTick; + bidAmount = 2; + } else if (_preBook.askPrice < _book.askPrice && _book.bidAmount < _book.askAmount) { + askPrice -= _priceTick; + askAmount = 2; + } else { + return true; + } + Log(_book.bidPrice, _book.bidAmount, _book.askPrice, _book.askAmount); + exchange.SetDirection("buy"); + exchange.Buy(bidPrice, bidAmount); + exchange.SetDirection("sell"); + exchange.Sell(askPrice, askAmount); + } else if (st == STATE_HOLD_LONG) { + exchange.SetDirection((_holdType == PD_LONG && _exchangeId == "SHFE") ? "closebuy_today" : "closebuy"); + auto sellPrice = depth.Asks[0].Price; + if (sellPrice > _holdPrice) { + Log(_holdPrice, "Hit #ff0000"); + sellPrice = _holdPrice + ProfitTick; + } else if (sellPrice < _holdPrice) { + forceCover = true; + } + if (forceCover) { + Log("StopLoss"); + } + _coverId = exchange.Sell(forceCover ? depth.Bids[0].Price : sellPrice, _holdAmount); + if (!_coverId.Valid) { + return false; + } + } else if (st == STATE_HOLD_SHORT) { + exchange.SetDirection((_holdType == PD_SHORT && _exchangeId == "SHFE") ? "closesell_today" : "closesell"); + auto buyPrice = depth.Bids[0].Price; + if (buyPrice < _holdPrice) { + Log(_holdPrice, "Hit #ff0000"); + buyPrice = _holdPrice - ProfitTick; + } else if (buyPrice > _holdPrice) { + forceCover = true; + } + if (forceCover) { + Log("StopLoss"); + } + _coverId = exchange.Buy(forceCover ? depth.Asks[0].Price : buyPrice, _holdAmount); + if (!_coverId.Valid) { + return false; + } + } + return true; + } + private: + double _holdPrice = 0; + double _holdAmount = 0; + int _holdType; + int _countTick = 0; + int _countRetry = 0; + int _countCancel = 0; + int _period = 20; + int _tradingDay = 0; + double _initBalance; + const int _retryMax = RetryMax; + const int _cancelMax = 300; + + int _countLoss = 0; + int _countWin = 0; + + json _ct; + string _ins; + string _exchangeId; + double _priceTick; + double _toleratePrice; + Book _book; + Book _preBook; + TId _coverId; +}; + + +void main() { + LogReset(); + SetErrorFilter("ready|timeout"); + Log("Init OK"); + HFT hft; + while (hft.Loop()); + Log("Exit"); +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/163427 + +> 更新时间 + +2019-08-24 12:23:42 diff --git a/HFT strategy.md b/HFT strategy.md new file mode 100644 index 00000000..f9a6798b --- /dev/null +++ b/HFT strategy.md @@ -0,0 +1,299 @@ + +> 策略名称 + +HFT strategy + +> 策略作者 + +Hukybo + +> 策略描述 + +策略回测什么才是最重要的?速度?花里胡哨的绩效指标?答案是准确!是的,回测的目的是为了验证策略的逻辑和可行性。这也是回测本身的意义,其他都是次要的。一个能够真正反映策略在历史数据上的回测才具有参考价值,那些看似完美的回测曲线讲故事可以,实盘它不行。 +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4195) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Symbol|MA909|品种| +|RetryMax|3|重试最多| +|ProfitTick|5|利润调数| + + +> 源码 (cpp) + +``` cpp +/*backtest +start: 2019-07-12 09:00:00 +end: 2019-07-12 15:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +mode: 1 +*/ + +enum State { + STATE_NA, + STATE_IDLE, + STATE_HOLD_LONG, + STATE_HOLD_SHORT, +}; + +typedef struct { + double bidPrice; + double bidAmount; + double askPrice; + double askAmount; +} Book; + +class HFT { + public: + State getState() { + auto orders = exchange.GetOrders(); + if (!orders.Valid || orders.size() == 2) { + return STATE_NA; + } + + bool foundCover = false; + for (auto &order : orders) { + if (order.Id == _coverId) { + if ((order.Type == ORDER_TYPE_BUY && order.Price < _book.bidPrice - _slidePrice) || + (order.Type == ORDER_TYPE_SELL && order.Price > _book.askPrice + _slidePrice)) { + exchange.CancelOrder(order.Id, "Cancel Cover Order"); + _countCancel++; + _countRetry++; + } else { + foundCover = true; + } + } else { + exchange.CancelOrder(order.Id); + _countCancel++; + } + } + + if (foundCover) { + return STATE_NA; + } + + auto positions = exchange.GetPosition(); + if (!positions.Valid) { + return STATE_NA; + } + + for (auto &pos : positions) { + if (pos.ContractType == Symbol) { + _holdPrice = pos.Price; + _holdAmount = pos.Amount; + _holdType = pos.Type; + return pos.Type == PD_LONG || pos.Type == PD_LONG_YD ? STATE_HOLD_LONG : STATE_HOLD_SHORT; + } + } + return STATE_IDLE; + } + + void stop() { + Log(exchange.GetOrders()); + Log(exchange.GetPosition()); + Log("Stop"); + } + + bool Loop() { + if (exchange.IO("status") == 0) { + LogStatus(_D(), "Server not connect ...."); + Sleep(1000); + return true; + } + + if (_ct.is_null()) { + Log(_D(), "subscribe", Symbol); + _ct = exchange.SetContractType(Symbol); + if (!_ct.is_null()) { + auto obj = _ct["Commodity"]["CommodityTickSize"]; + int volumeMultiple = 1; + if (obj.is_null()) { + obj = _ct["PriceTick"]; + volumeMultiple = _ct["VolumeMultiple"]; + _exchangeId = _ct["ExchangeID"]; + } else { + volumeMultiple = _ct["Commodity"]["ContractSize"]; + _exchangeId = _ct["Commodity"]["ExchangeNo"]; + } + if (obj.is_null() || obj <= 0) { + Panic("PriceTick not found"); + } + if (_priceTick < 1) { + exchange.SetPrecision(1, 0); + } + _priceTick = double(obj); + _slidePrice = _priceTick * ProfitTick; + _ins = _ct["InstrumentID"]; + + Log(_ins, _exchangeId, "PriceTick:", _priceTick, "VolumeMultiple:", volumeMultiple); + } + Sleep(1000); + return true; + } + // Check orders and positions to set state + auto depth = exchange.GetDepth(); + if (!depth.Valid) { + LogStatus(_D(), "Market not ready"); + Sleep(1000); + return true; + } + _countTick++; + // _book not init + if (_book.bidAmount == 0) { + return true; + } + _preBook = _book; + _book.bidPrice = depth.Bids[0].Price; + _book.bidAmount = depth.Bids[0].Amount; + _book.askPrice = depth.Asks[0].Price; + _book.askAmount = depth.Asks[0].Amount; + + double weight = depth.Asks[0].Price + depth.Bids[0].Price; + _priceHis.push_back(weight); + if (_priceHis.size() > 100) { + _priceHis.erase(_priceHis.begin()); + } + + auto st = getState(); + + LogStatus(_D(), _ins, "State:", st, + "Ask:", depth.Asks[0].Price, depth.Asks[0].Amount, + "Bid:", depth.Bids[0].Price, depth.Bids[0].Amount, + "Cancel:", _countCancel, + "Tick:", _countTick); + Log(depth.Asks[0], depth.Bids[0]); + + bool forceCover = _countRetry >= _retryMax; + if (st == STATE_IDLE) { + if (_holdAmount > 0) { + if (_countRetry > 0) { + _countLoss++; + } else { + _countWin++; + } + auto account = exchange.GetAccount(); + if (account.Valid) { + LogProfit(_N(account.Balance+account.FrozenBalance, 2), "Win:", _countWin, "Loss:", _countLoss); + } + } + _countRetry = 0; + _holdAmount = 0; + + if (_countCancel > _cancelMax) { + Log("Cancel Exceed", _countCancel); + return false; + } + if (IsVirtual()) { + if (_priceHis.size() < _period) { + LogStatus("calc history", _priceHis.size()); + return true; + } + auto arr = talib.STDDEV(_priceHis, _period); + double diff = abs(weight - _priceHis[_priceHis.size() - 2]); + if (diff < arr[arr.size()-1]) { + return true; + } + } else { + bool canDo = false; + if (_book.bidPrice == _preBook.bidPrice && _book.bidAmount > 50 && abs(_preBook.bidAmount-_book.bidAmount) > 50) { + canDo = true; + Log("Bid Amount", _preBook.bidAmount, "->", _book.bidAmount); + } + if (_book.askPrice == _preBook.askPrice && _book.askAmount > 50 && abs(_preBook.askAmount-_book.askAmount) > 50) { + canDo = true; + Log("Ask Amount", _preBook.askAmount, "->", _book.askAmount); + } + if (!canDo) { + return true; + } + } + exchange.SetDirection("buy"); + exchange.Buy(depth.Bids[0].Price, 1); + exchange.SetDirection("sell"); + exchange.Sell(depth.Asks[0].Price, 1); + } else if (st == STATE_HOLD_LONG) { + + exchange.SetDirection((_holdType == PD_LONG && _exchangeId == "SHFE") ? "closebuy_today" : "closebuy"); + auto sellPrice = depth.Asks[0].Price; + if (sellPrice > _holdPrice) { + Log(_holdPrice, "Hit #ff0000"); + //sellPrice = depth.Asks[0].Price + _slidePrice; + } else if (sellPrice < _holdPrice) { + //forceCover = true; + } + if (forceCover) { + Log("StopLoss"); + } + _coverId = exchange.Sell(forceCover ? depth.Bids[0].Price : sellPrice, _holdAmount); + if (!_coverId.Valid) { + return false; + } + } else if (st == STATE_HOLD_SHORT) { + + exchange.SetDirection((_holdType == PD_SHORT && _exchangeId == "SHFE") ? "closesell_today" : "closesell"); + auto buyPrice = depth.Bids[0].Price; + if (buyPrice < _holdPrice) { + Log(_holdPrice, "Hit #ff0000"); + } else if (buyPrice > _holdPrice) { + //forceCover = true; + } + if (forceCover) { + Log("StopLoss"); + } + _coverId = exchange.Buy(forceCover ? depth.Asks[0].Price : buyPrice, _holdAmount); + if (!_coverId.Valid) { + return false; + } + } + return true; + } + private: + double _holdPrice = 0; + double _holdAmount = 0; + int _holdType; + int _countTick = 0; + int _countRetry = 0; + int _countCancel = 0; + int _period = 20; + const int _retryMax = RetryMax; + const int _cancelMax = 300; + + int _countLoss = 0; + int _countWin = 0; + + json _ct; + string _ins; + string _exchangeId; + double _priceTick; + double _slidePrice; + vector _priceHis; + Book _book; + Book _preBook; + TId _coverId; +}; + + +void main() { + LogReset(); + SetErrorFilter("ready|timeout"); + Log("Init OK"); + HFT hft; + while (hft.Loop()); + Log("Exit"); +} + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/162372 + +> 更新时间 + +2019-08-23 16:05:13 diff --git "a/MultDualThrust(\346\225\231\345\255\246).md" "b/MultDualThrust(\346\225\231\345\255\246).md" new file mode 100644 index 00000000..c498ff3d --- /dev/null +++ "b/MultDualThrust(\346\225\231\345\255\246).md" @@ -0,0 +1,150 @@ + +> 策略名称 + +MultDualThrust(教学) + +> 策略作者 + +小小梦 + + + + + +> 源码 (javascript) + +``` javascript +/* +## 商品期货 多品种 Dual Thrust 策略 + +*/ + +var _Symbols = [ + { + ContractTypeName : "rb1910", + NPeriod : 4, + Ks : 0.5, + Kx : 0.5, + AmountOP : 1, + }, + { + ContractTypeName : "i1909", + NPeriod : 4, + Ks : 0.5, + Kx : 0.5, + AmountOP : 1, + }, + { + ContractTypeName : "pp1909", + NPeriod : 4, + Ks : 0.5, + Kx : 0.5, + AmountOP : 1, + }, + { + ContractTypeName : "MA909", + NPeriod : 4, + Ks : 0.5, + Kx : 0.5, + AmountOP : 1, + }, +] + +var manager = $.NewPositionManager() +var STATE_IDLE = 0; +var STATE_LONG = 1; +var STATE_SHORT = 2; + +function init () { + for (var i = 0 ; i < _Symbols.length ; i++) { + _Symbols[i].State = STATE_IDLE + _Symbols[i].LastBarTime = 0 + _Symbols[i].UpTrack = 0 + _Symbols[i].DownTrack = 0 + } +} + +function DualThrustProcess (symbols) { + for (var i = 0 ; i < symbols.length ; i++) { + var ContractTypeName = symbols[i].ContractTypeName + var NPeriod = symbols[i].NPeriod + var Ks = symbols[i].Ks + var Kx = symbols[i].Kx + var AmountOP = symbols[i].AmountOP + + // 首先判断是不是在交易时间 + if (!$.IsTrading(ContractTypeName)) { + continue + } + + // 切换为当前 symbol 参数的合约 + var insDetail = _C(exchange.SetContractType, ContractTypeName) + + // 判断K线长度 + var records = _C(exchange.GetRecords); + if (!records || records.length <= NPeriod) { + LogStatus("Calc Bars..."); + continue + } + + var Bar = records[records.length - 1] + if (symbols[i].LastBarTime !== Bar.Time) { + var HH = TA.Highest(records, NPeriod, 'High') + var HC = TA.Highest(records, NPeriod, 'Close') + var LL = TA.Lowest(records, NPeriod, 'Low') + var LC = TA.Lowest(records, NPeriod, 'Close') + var Range = Math.max(HH - LC, HC - LL) + + symbols[i].UpTrack = _N(Bar.Open + (Ks * Range)) + symbols[i].DownTrack = _N(Bar.Open - (Kx * Range)) + + symbols[i].LastBarTime = Bar.Time; + } + + if (symbols[i].State === STATE_IDLE || symbols[i].State === STATE_SHORT) { + if (Bar.Close >= symbols[i].UpTrack) { + if (symbols[i].State !== STATE_IDLE) { + Log(ContractTypeName, "平空仓") + manager.Cover(ContractTypeName); + } + Log(ContractTypeName, "开多仓") + manager.OpenLong(ContractTypeName, AmountOP); + symbols[i].State = STATE_LONG; + } + } + + if (symbols[i].State === STATE_IDLE || symbols[i].State === STATE_LONG) { + if (Bar.Close <= symbols[i].DownTrack) { + if (symbols[i].State !== STATE_IDLE) { + Log(ContractTypeName, "平多仓") + manager.Cover(ContractTypeName); + } + Log(ContractTypeName, "开空仓") + manager.OpenShort(ContractTypeName, AmountOP); + symbols[i].State = STATE_SHORT; + } + } + } +} + + +function main(){ + while(true){ + if(exchange.IO("status")){ + LogStatus(_D(), "已经连接CTP !") + DualThrustProcess(_Symbols) + } else { + LogStatus(_D(), "未连接CTP !") + } + Sleep(1000) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/163212 + +> 更新时间 + +2019-08-22 15:39:24 diff --git "a/OKEx\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.md" "b/OKEx\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.md" new file mode 100644 index 00000000..55fdb96d --- /dev/null +++ "b/OKEx\350\267\250\346\234\237\345\257\271\345\206\262\347\255\226\347\225\245.md" @@ -0,0 +1,497 @@ + +> 策略名称 + +OKEx跨期对冲策略 + +> 策略作者 + +reboting + +> 策略描述 + +什么是跨期对冲? +所谓跨期套利就是在同一期货品种的不同月份合约上建立数量相等、方向相反的交易头寸,最后以对冲或交割方式结束交易、获得收益的方式。最简单的跨期套利就是买入近期的期货品种,卖出远期的期货品种。比如Okex的BTC次周和当周合约。交割期不同,最多相差3个月。当合约价差出现时,投资者可进行买入一个合约同时卖出另外一个合约,待到价差回归后再进行相应的反向平仓,进而利用价差的合理回归获得利润。 + +如何在Okex上进行跨期对冲? +okex上当周、次周和季度合约的价格经常会存在价差,如果价差达到或超过一定的阈值,则可以进行跨期对冲,然后在价差消失时进行反向平仓,进而利用价差的合理回归获得利润。比如,BTC当周和次周合约存在价差且当周合约低于次周合约价格,当价差达到设定阈值,投资者可以做多当周合约和做空次周合约(数量一致)进行对冲,等到当周合约和次周合约价差回归正常值时进行相应的反向平仓,获取利润。 + +跨期对冲的风险: +因为两种合约的交割时间不同,当近期合约强制交割时,价差未能回归则可能出现亏损。 + +策略实现的功能和特点: +支持Okex跨期对冲 +支持Okex的当周、次周和季度合约 +支持Okex的所有合约交易品种(BTC、BCH、EOS、BSV、ETH等等) + +特别注意:此策略需要依赖Botvstools模板库才能运行! +请到此处下载模板库: +https://www.pcclean.io/45gd +(下载zip文件后解压缩会有两个js文件,一个是策略,一个是模板库,请注意区分) + +策略参数说明: +https://www.pcclean.io/45gd + + + +> 源码 (javascript) + +``` javascript +var strategy_version="1.2.0.7(adjust parameters)"; + +/* +使用说明: +1. 请先针对交易所和交易对设置策略参数后再运行此策略。 +2. fmz中添加交易所: okex期货交易所 +3. 参数里面contract_min表示单个合约价值,不要随意更改 +4. 建议okex里面设置为全仓模式,以免出现保证金不足的情况 +5. 尽量使用okex api v1 +6. 此策略仅用于学习分享,实盘风险自担。 +*/ + +/********************************************策略参数**********************************/ +var price_n={Futures_OKCoin_BSV_USD:2};//价格精度设置 +var num_n={Futures_OKCoin_BSV_USD:0};//数量精度设置 +var minestbuy={Futures_OKCoin_BSV_USD:1};//最小买入量 +var price_step={Futures_OKCoin_BSV_USD:0.05};//定价单调整量 +var contract_min={Futures_OKCoin_BSV_USD:10};//最小合约金额 +var wait_ms=3000;//重试等待时间(ms) +var max_wait_order=10000;//订单等待时间(ms) +var margin_lv=10;//杠杆倍数 +var jiacha_monitor={tw_nw:0.02,tw_qt:0.02,nw_qt:0.02};//开仓差价 +var hulie_monitor={tw_nw:0.003,tw_qt:0.003,nw_qt:0.003};//忽略的差价 +var ok_future_target='bsv';//目标合约 +var keep_risk_rate=10;//保证金率 +var trade_unit=100;//每次交易多少张 +var push_notification=true;//微信通知交易机会 +/********************************************策略参数**********************************/ + + +//全局变量 +var total_loop=0; + +//主函数 +function main(){ + Log("strategy_version="+strategy_version); + $.set_params(price_n,num_n,minestbuy,price_step,wait_ms,max_wait_order); + + if (push_notification){ + Log("策略开始运行!已开启推送。@"); + } + + while(true){ + exchange.SetMarginLevel(margin_lv); + var exname=exchange.GetName(); + var currency=exchange.GetCurrency(); + var account=$.retry_get_account(exchange); + var f_orders=_C(exchange.GetOrders); + + exchange.SetContractType("this_week"); + var tw_depth=_C(exchange.GetDepth); + var tw_sell1=tw_depth.Asks[0].Price; + var tw_buy1=tw_depth.Bids[0].Price; + var tw_records=_C(exchange.GetRecords,PERIOD_H1); + if (tw_records.length<=50){ + Log("tw_records.length无效,跳过此次执行..."); + Sleep(wait_ms); + continue; + } + + exchange.SetContractType("next_week"); + var nw_depth=_C(exchange.GetDepth); + var nw_sell1=nw_depth.Asks[0].Price; + var nw_buy1=nw_depth.Bids[0].Price; + var nw_records=_C(exchange.GetRecords,PERIOD_H1); + if (nw_records.length<=50){ + Log("nw_records.length无效,跳过此次执行..."); + Sleep(wait_ms); + continue; + } + + exchange.SetContractType("quarter"); + var qt_depth=_C(exchange.GetDepth); + var qt_sell1=qt_depth.Asks[0].Price; + var qt_buy1=qt_depth.Bids[0].Price; + var qt_records=_C(exchange.GetRecords,PERIOD_H1); + if (qt_records.length<=50){ + Log("qt_records.length无效,跳过此次执行..."); + Sleep(wait_ms); + continue; + } + + var tw_price_ma = TA.MA(tw_records, 30).slice(-1)[0]; + var nw_price_ma = TA.MA(nw_records, 30).slice(-1)[0]; + var qt_price_ma = TA.MA(qt_records, 30).slice(-1)[0]; + + var position=_C(exchange.GetPosition); + + var tw_zuoduo_zhangshu=0; + var tw_zuoduo_avg_price=0; + var tw_zuoduo_amount=0; + var tw_zuokong_zhangshu=0; + var tw_zuokong_avg_price=0; + var tw_zuokong_amount=0; + + var nw_zuoduo_zhangshu=0; + var nw_zuoduo_avg_price=0; + var nw_zuoduo_amount=0; + var nw_zuokong_zhangshu=0; + var nw_zuokong_avg_price=0; + var nw_zuokong_amount=0; + + var qt_zuoduo_zhangshu=0; + var qt_zuoduo_avg_price=0; + var qt_zuoduo_amount=0; + var qt_zuokong_zhangshu=0; + var qt_zuokong_avg_price=0; + var qt_zuokong_amount=0; + + + for (var i=0; i < position.length; i++){ + if (position[i].ContractType==="this_week"){ + if (position[i].Type===PD_LONG){ + tw_zuoduo_zhangshu=position[i].Amount; + tw_zuoduo_avg_price=position[i].Price; + tw_zuoduo_amount=tw_zuoduo_zhangshu*contract_min[$.get_exchange_id(exchange)]*(1/tw_zuoduo_avg_price-1/tw_buy1+1/tw_zuoduo_avg_price); + } + if (position[i].Type===PD_SHORT){ + tw_zuokong_zhangshu=position[i].Amount; + tw_zuokong_avg_price=position[i].Price; + tw_zuokong_amount=tw_zuokong_zhangshu*contract_min[$.get_exchange_id(exchange)]*(1/tw_sell1-1/tw_zuokong_avg_price+1/tw_zuokong_avg_price); + } + } + if (position[i].ContractType==="next_week"){ + if (position[i].Type===PD_LONG){ + nw_zuoduo_zhangshu=position[i].Amount; + nw_zuoduo_avg_price=position[i].Price; + nw_zuoduo_amount=nw_zuoduo_zhangshu*contract_min[$.get_exchange_id(exchange)]*(1/nw_zuoduo_avg_price-1/nw_buy1+1/nw_zuoduo_avg_price); + } + if (position[i].Type===PD_SHORT){ + nw_zuokong_zhangshu=position[i].Amount; + nw_zuokong_avg_price=position[i].Price; + nw_zuokong_amount=nw_zuokong_zhangshu*contract_min[$.get_exchange_id(exchange)]*(1/nw_sell1-1/nw_zuokong_avg_price+1/nw_zuokong_avg_price); + } + } + if (position[i].ContractType==="quarter"){ + if (position[i].Type===PD_LONG){ + qt_zuoduo_zhangshu=position[i].Amount; + qt_zuoduo_avg_price=position[i].Price; + qt_zuoduo_amount=qt_zuoduo_zhangshu*contract_min[$.get_exchange_id(exchange)]*(1/qt_zuoduo_avg_price-1/qt_buy1+1/qt_zuoduo_avg_price); + } + if (position[i].Type===PD_SHORT){ + qt_zuokong_zhangshu=position[i].Amount; + qt_zuokong_avg_price=position[i].Price; + qt_zuokong_amount=qt_zuokong_zhangshu*contract_min[$.get_exchange_id(exchange)]*(1/qt_sell1-1/qt_zuokong_avg_price+1/qt_zuokong_avg_price); + } + } + } + + var account_rights=account.Info.info[ok_future_target].account_rights;//账户权益 + var keep_deposit=account.Info.info[ok_future_target].keep_deposit;//保证金 + var profit_real=account.Info.info[ok_future_target].profit_real;//已实现盈亏 + var profit_unreal=account.Info.info[ok_future_target].profit_unreal;//未实现盈亏 + var risk_rate=account.Info.info[ok_future_target].risk_rate;//保证金率 10倍杠杆,当保证金率小于等于10%,才会触发爆仓线;20倍杠杆,当保证金率小于等于20%,才会触发爆仓线。 这意味着如果您开10倍LTC合约,当您的亏损达到开仓保证金的90%时,会触发爆仓线;若开20倍杠杆的合约,当您的亏损达到开仓保证金的80%时,才会触发爆仓线。 + + + var tw_buy1_fixed=tw_buy1; + var tw_sell1_fixed=tw_sell1; + var nw_buy1_fixed=nw_buy1-(nw_price_ma-tw_price_ma); + var nw_sell1_fixed=nw_sell1-(nw_price_ma-tw_price_ma); + var qt_buy1_fixed=qt_buy1-(qt_price_ma-tw_price_ma); + var qt_sell1_fixed=qt_sell1-(qt_price_ma-tw_price_ma); + + //this week - next week - kaichang + if (tw_sell1_fixedjiacha_monitor['tw_nw']){ + if (push_notification){ + Log("次周_当周_套利机会:"+exname+" "+((nw_buy1_fixed-tw_sell1_fixed)/tw_sell1_fixed)+"@"); + } + if (risk_rate>keep_risk_rate && account.Stocks>0){ + exchange.SetContractType("this_week"); + exchange.SetDirection("buy"); + var dealamount=$.perform_limited_order("buy",exchange,tw_sell1,trade_unit,false,"futures","buy"); + if (dealamount>0){ + exchange.SetContractType("next_week"); + exchange.SetDirection("sell"); + $.perform_limited_order("buy",exchange,nw_buy1,dealamount,true,"futures","sell"); + } + } + } + else if (nw_sell1_fixedjiacha_monitor['tw_nw']){ + if (push_notification){ + Log("当周_次周_套利机会:"+exname+" "+((tw_buy1_fixed-nw_sell1_fixed)/nw_sell1_fixed)+"@"); + } + if (risk_rate>keep_risk_rate && account.Stocks>0){ + exchange.SetContractType("next_week"); + exchange.SetDirection("buy"); + var dealamount=$.perform_limited_order("buy",exchange,nw_sell1,trade_unit,false,"futures","buy"); + if (dealamount>0){ + exchange.SetContractType("this_week"); + exchange.SetDirection("sell"); + $.perform_limited_order("buy",exchange,tw_buy1,dealamount,true,"futures","sell"); + } + } + } + //this week - quarter - kaichang + else if (tw_sell1_fixedjiacha_monitor['tw_qt']){ + if (push_notification){ + Log("季度_当周_套利机会:"+exname+" "+((qt_buy1_fixed-tw_sell1_fixed)/tw_sell1_fixed)+"@"); + } + if (risk_rate>keep_risk_rate && account.Stocks>0){ + exchange.SetContractType("this_week"); + exchange.SetDirection("buy"); + var dealamount=$.perform_limited_order("buy",exchange,tw_sell1,trade_unit,false,"futures","buy"); + if (dealamount>0){ + exchange.SetContractType("quarter"); + exchange.SetDirection("sell"); + $.perform_limited_order("buy",exchange,qt_buy1,dealamount,true,"futures","sell"); + } + } + } + else if (qt_sell1_fixedjiacha_monitor['tw_qt']){ + if (push_notification){ + Log("当周_季度_套利机会:"+exname+" "+((tw_buy1_fixed-qt_sell1_fixed)/qt_sell1_fixed)+"@"); + } + if (risk_rate>keep_risk_rate && account.Stocks>0){ + exchange.SetContractType("quarter"); + exchange.SetDirection("buy"); + var dealamount=$.perform_limited_order("buy",exchange,qt_sell1,trade_unit,false,"futures","buy"); + if (dealamount>0){ + exchange.SetContractType("this_week"); + exchange.SetDirection("sell"); + $.perform_limited_order("buy",exchange,tw_buy1,dealamount,true,"futures","sell"); + } + } + } + //next week - quarter - kaichang + else if (nw_sell1_fixedjiacha_monitor['nw_qt']){ + if (push_notification){ + Log("季度_次周_套利机会:"+exname+" "+((qt_buy1_fixed-nw_sell1_fixed)/nw_sell1_fixed)+"@"); + } + if (risk_rate>keep_risk_rate && account.Stocks>0){ + exchange.SetContractType("next_week"); + exchange.SetDirection("buy"); + var dealamount=$.perform_limited_order("buy",exchange,nw_sell1,trade_unit,false,"futures","buy"); + if (dealamount>0){ + exchange.SetContractType("quarter"); + exchange.SetDirection("sell"); + $.perform_limited_order("buy",exchange,qt_buy1,dealamount,true,"futures","sell"); + } + } + } + else if (qt_sell1_fixedjiacha_monitor['nw_qt']){ + if (push_notification){ + Log("次周_季度_套利机会:"+exname+" "+((nw_buy1_fixed-qt_sell1_fixed)/qt_sell1_fixed)+"@"); + } + if (risk_rate>keep_risk_rate && account.Stocks>0){ + exchange.SetContractType("quarter"); + exchange.SetDirection("buy"); + var dealamount=$.perform_limited_order("buy",exchange,qt_sell1,trade_unit,false,"futures","buy"); + if (dealamount>0){ + exchange.SetContractType("next_week"); + exchange.SetDirection("sell"); + $.perform_limited_order("buy",exchange,nw_buy1,dealamount,true,"futures","sell"); + } + } + } + //this week - next week - pingchang + else if (Math.abs((nw_sell1_fixed-tw_buy1_fixed)/tw_buy1_fixed)0 && nw_zuokong_zhangshu>0){ + var pingchang_zhangshu=Math.min(tw_zuoduo_zhangshu,nw_zuokong_zhangshu); + exchange.SetContractType("this_week"); + exchange.SetDirection("closebuy"); + var dealamount=$.perform_limited_order("sell",exchange,tw_buy1,pingchang_zhangshu,false,"futures","closebuy"); + if (dealamount>0){ + exchange.SetContractType("next_week"); + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,nw_sell1,dealamount,true,"futures","closesell"); + } + } + else if (Math.abs((tw_sell1_fixed-nw_buy1_fixed)/nw_buy1_fixed)0 && nw_zuoduo_zhangshu>0){ + var pingchang_zhangshu=Math.min(tw_zuokong_zhangshu,nw_zuoduo_zhangshu); + exchange.SetContractType("next_week"); + exchange.SetDirection("closebuy"); + var dealamount=$.perform_limited_order("sell",exchange,nw_buy1,pingchang_zhangshu,false,"futures","closebuy"); + if (dealamount>0){ + exchange.SetContractType("this_week"); + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,tw_sell1,dealamount,true,"futures","closesell"); + } + } + //this week - quarter - pingchang + else if (Math.abs((qt_sell1_fixed-tw_buy1_fixed)/tw_buy1_fixed)0 && qt_zuokong_zhangshu>0){ + var pingchang_zhangshu=Math.min(tw_zuoduo_zhangshu,qt_zuokong_zhangshu); + exchange.SetContractType("this_week"); + exchange.SetDirection("closebuy"); + var dealamount=$.perform_limited_order("sell",exchange,tw_buy1,pingchang_zhangshu,false,"futures","closebuy"); + if (dealamount>0){ + exchange.SetContractType("quarter"); + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,qt_sell1,dealamount,true,"futures","closesell"); + } + } + else if (Math.abs((tw_sell1_fixed-qt_buy1_fixed)/qt_buy1_fixed)0 && qt_zuoduo_zhangshu>0){ + var pingchang_zhangshu=Math.min(tw_zuokong_zhangshu,qt_zuoduo_zhangshu); + exchange.SetContractType("quarter"); + exchange.SetDirection("closebuy"); + var dealamount=$.perform_limited_order("sell",exchange,qt_buy1,pingchang_zhangshu,false,"futures","closebuy"); + if (dealamount>0){ + exchange.SetContractType("this_week"); + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,tw_sell1,dealamount,true,"futures","closesell"); + } + } + //next week - quarter - pingchang + else if (Math.abs((qt_sell1_fixed-nw_buy1_fixed)/nw_buy1_fixed)0 && qt_zuokong_zhangshu>0){ + var pingchang_zhangshu=Math.min(nw_zuoduo_zhangshu,qt_zuokong_zhangshu); + exchange.SetContractType("next_week"); + exchange.SetDirection("closebuy"); + var dealamount=$.perform_limited_order("sell",exchange,nw_buy1,pingchang_zhangshu,false,"futures","closebuy"); + if (dealamount>0){ + exchange.SetContractType("quarter"); + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,qt_sell1,dealamount,true,"futures","closesell"); + } + } + else if (Math.abs((nw_sell1_fixed-qt_buy1_fixed)/qt_buy1_fixed)0 && qt_zuoduo_zhangshu>0){ + var pingchang_zhangshu=Math.min(nw_zuokong_zhangshu,qt_zuoduo_zhangshu); + exchange.SetContractType("quarter"); + exchange.SetDirection("closebuy"); + var dealamount=$.perform_limited_order("sell",exchange,qt_buy1,pingchang_zhangshu,false,"futures","closebuy"); + if (dealamount>0){ + exchange.SetContractType("next_week"); + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,nw_sell1,dealamount,true,"futures","closesell"); + } + } + else{ + //处理交割 + var total_zuoduo=tw_zuoduo_zhangshu+nw_zuoduo_zhangshu+qt_zuoduo_zhangshu; + var total_zuokong=tw_zuokong_zhangshu+nw_zuokong_zhangshu+qt_zuokong_zhangshu; + if (total_zuoduo!==total_zuokong){ + if (total_zuoduo>total_zuokong){ + var diff_num=total_zuoduo-total_zuokong; + + //强制平多 + Log("开始强制平多:"+diff_num+'@'); + if (qt_zuoduo_zhangshu>=diff_num){ + exchange.SetContractType("quarter"); + exchange.SetDirection("closebuy"); + $.perform_limited_order("sell",exchange,qt_buy1,diff_num,true,"futures","closebuy"); + }else{ + exchange.SetContractType("quarter"); + exchange.SetDirection("closebuy"); + $.perform_limited_order("sell",exchange,qt_buy1,qt_zuoduo_zhangshu,true,"futures","closebuy"); + var diff2=diff_num-qt_zuoduo_zhangshu; + if (nw_zuoduo_zhangshu>=diff2){ + exchange.SetContractType("next_week"); + exchange.SetDirection("closebuy"); + $.perform_limited_order("sell",exchange,nw_buy1,diff2,true,"futures","closebuy"); + }else{ + exchange.SetContractType("next_week"); + exchange.SetDirection("closebuy"); + $.perform_limited_order("sell",exchange,nw_buy1,nw_zuoduo_zhangshu,true,"futures","closebuy"); + var diff3=diff2-nw_zuoduo_zhangshu; + if (tw_zuoduo_zhangshu>=diff3){ + exchange.SetContractType("this_week"); + exchange.SetDirection("closebuy"); + $.perform_limited_order("sell",exchange,tw_buy1,diff3,true,"futures","closebuy"); + }else{ + exchange.SetContractType("this_week"); + exchange.SetDirection("closebuy"); + $.perform_limited_order("sell",exchange,tw_buy1,tw_zuoduo_zhangshu,true,"futures","closebuy"); + } + } + } + } + else if (total_zuokong>total_zuoduo){ + var diff_num=total_zuokong-total_zuoduo; + + //强制平空 + Log("开始强制平空:"+diff_num+'@'); + if (qt_zuokong_zhangshu>=diff_num){ + exchange.SetContractType("quarter"); + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,qt_sell1,diff_num,true,"futures","closesell"); + }else{ + exchange.SetContractType("quarter"); + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,qt_sell1,qt_zuokong_zhangshu,true,"futures","closesell"); + var diff2=diff_num-qt_zuokong_zhangshu; + if (nw_zuokong_zhangshu>=diff2){ + exchange.SetContractType("next_week"); + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,nw_sell1,diff2,true,"futures","closesell"); + }else{ + exchange.SetContractType("next_week"); + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,nw_sell1,nw_zuokong_zhangshu,true,"futures","closesell"); + var diff3=diff2-nw_zuokong_zhangshu; + if (tw_zuokong_zhangshu>=diff3){ + exchange.SetContractType("this_week"); + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,tw_sell1,diff3,true,"futures","closesell"); + }else{ + exchange.SetContractType("this_week"); + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,tw_sell1,tw_zuokong_zhangshu,true,"futures","closesell"); + } + } + } + } + } + } + + + + LogStatus( + "合约近期均价="+tw_price_ma+'/'+nw_price_ma+'/'+qt_price_ma+"\n"+ + '-----------------------------------------------------------\n'+ + '次周_当周_开仓差价='+(nw_buy1_fixed-tw_sell1_fixed)/tw_sell1_fixed+'/'+jiacha_monitor['tw_nw']+"\n"+ + '当周_次周_开仓差价='+(tw_buy1_fixed-nw_sell1_fixed)/nw_sell1_fixed+'/'+jiacha_monitor['tw_nw']+"\n"+ + '季度_当周_开仓差价='+(qt_buy1_fixed-tw_sell1_fixed)/tw_sell1_fixed+'/'+jiacha_monitor['tw_qt']+"\n"+ + '当周_季度_开仓差价='+(tw_buy1_fixed-qt_sell1_fixed)/qt_sell1_fixed+'/'+jiacha_monitor['tw_qt']+"\n"+ + '季度_次周_开仓差价='+(qt_buy1_fixed-nw_sell1_fixed)/nw_sell1_fixed+'/'+jiacha_monitor['nw_qt']+"\n"+ + '次周_季度_开仓差价='+(nw_buy1_fixed-qt_sell1_fixed)/qt_sell1_fixed+'/'+jiacha_monitor['nw_qt']+"\n"+ + '-----------------------------------------------------------\n'+ + '次周_当周_平仓差价='+Math.abs((nw_sell1_fixed-tw_buy1_fixed)/tw_buy1_fixed)+'/'+hulie_monitor['tw_nw']+"\n"+ + '当周_次周_平仓差价='+Math.abs((tw_sell1_fixed-nw_buy1_fixed)/nw_buy1_fixed)+'/'+hulie_monitor['tw_nw']+"\n"+ + '季度_当周_平仓差价='+Math.abs((qt_sell1_fixed-tw_buy1_fixed)/tw_buy1_fixed)+'/'+hulie_monitor['tw_qt']+"\n"+ + '当周_季度_平仓差价='+Math.abs((tw_sell1_fixed-qt_buy1_fixed)/qt_buy1_fixed)+'/'+hulie_monitor['tw_qt']+"\n"+ + '季度_次周_平仓差价='+Math.abs((qt_sell1_fixed-nw_buy1_fixed)/nw_buy1_fixed)+'/'+hulie_monitor['nw_qt']+"\n"+ + '次周_季度_平仓差价='+Math.abs((nw_sell1_fixed-qt_buy1_fixed)/qt_buy1_fixed)+'/'+hulie_monitor['nw_qt']+"\n"+ + '-----------------------------------------------------------\n'+ + '账户权益='+account_rights+'\n'+ + '已用保证金='+keep_deposit+'\n'+ + '可用保证金='+account.Stocks+'\n'+ + '保证金率='+risk_rate+'\n'+ + '当周做多/做空张数='+tw_zuoduo_zhangshu+'/'+tw_zuokong_zhangshu+'\n'+ + '次周做多/做空张数='+nw_zuoduo_zhangshu+'/'+nw_zuokong_zhangshu+'\n'+ + '季度做多/做空张数='+qt_zuoduo_zhangshu+'/'+qt_zuokong_zhangshu+'\n'+ + '期货仓位='+position.length+'\n'+ + '未完成订单='+f_orders.length+'\n'+ + '当周做多/做空均价='+tw_zuoduo_avg_price+'/'+tw_zuokong_avg_price+'\n'+ + '次周做多/做空均价='+nw_zuoduo_avg_price+'/'+nw_zuokong_avg_price+'\n'+ + '季度做多/做空均价='+qt_zuoduo_avg_price+'/'+qt_zuokong_avg_price+'\n'+ + '♜轮询次数: '+total_loop+'\n'+ + '♜更新时间: '+$.get_ChinaTimeString()+'\n'+ + '♜微信: alinwo(验证消息:botvs) #0000ff'+'\n'+ + '♜霖霖量化-实盘策略: http://www.pcclean.io/quant #ff0000'+'\n' + ); + + if (total_loop%200===0){ + LogProfit(account_rights); + } + + total_loop++; + Sleep(wait_ms); + + }//while end +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/157635 + +> 更新时间 + +2019-07-17 22:39:05 diff --git "a/RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245.md" "b/RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245.md" new file mode 100644 index 00000000..5a9154f6 --- /dev/null +++ "b/RSI\347\273\237\350\256\241\345\245\227\345\210\251\347\255\226\347\225\245.md" @@ -0,0 +1,392 @@ + +> 策略名称 + +RSI统计套利策略 + +> 策略作者 + +quant777 + +> 策略描述 + +此策略是基于RSI指标的统计套利策略,根据实测在熊市中也能有很高的胜率。策略会对行情进行RSI数据分析,一旦捕获到预定义的K线形态即进行短期套利。 + +RSI指标说明: +RSI最早被用于期货交易中,后来人们发现用该指标来指导股票市场投资效果也十分不错,并对该指标的特点不断进行归纳和总结。现在,RSI已经成为被投资者应用最广泛的技术指标之一。投资的一般原理认为,投资者的买卖行为是各种因素综合结果的反映,行情的变化最终取决于供求关系,而RSI指标正是根据供求平衡的原理,通过测量某一个期间内股价上涨总幅度占股价变化总幅度平均值的百分比,来评估多空力量的强弱程度,进而提示具体操作的。 + +策略特点: +支持任意级别的趋势跟踪(分钟K,小时K,日K,周K等) +支持任意交易对(ETH/BTC, BSV/BTC等) +支持任意交易所 +详细的策略报表(包括策略状态,交易历史记录等) +支持接近10个自定义个性化参数 + +策略参数说明: +https://www.pcclean.io/8cut + + + +> 源码 (javascript) + +``` javascript +/* +RSI策略:仅用于学习用途,用于实盘后果自负 +*/ + +var ExchangProcessor={ + createNew: function(exc_obj){ + //策略参数 + var manage_assets=1;//bch + var max_positions=4;//max=4N + var price_n={BTC_BCH:8,ETH_BCH:8,XRP_BCH:8,EOS_BCH:8,LTC_BCH:8,DASH_BCH:8,CET_BCH:8}; //价格精度 + var num_n={BTC_BCH:8,ETH_BCH:8,XRP_BCH:8,EOS_BCH:8,LTC_BCH:8,DASH_BCH:8,CET_BCH:8}; //数量精度 + var minest_buy={BTC_BCH:0.001,ETH_BCH:0.01,XRP_BCH:1,EOS_BCH:1,LTC_BCH:0.1,DASH_BCH:0.01,CET_BCH:1};//最小买入量 + var minest_sell={BTC_BCH:0.001,ETH_BCH:0.01,XRP_BCH:1,EOS_BCH:1,LTC_BCH:0.1,DASH_BCH:0.01,CET_BCH:1};//最小卖出量 + var order_wait_secs=120000; //订单的最长等待时间 毫秒 + var wait_ms=1000;//默认等待毫秒 + var sxf=0.0005;//用来计算手续费消耗 + + + //全局状态变量 + var positions=[];//记录仓位 + var init_asset=0; //初始资产 + var trades=[];//所有交易 + var trades_recorder=true;//记录所有交易 + var pre_time=null; //记录轮询间隔时间 + var approximate_profit=0;//盈亏近似值 + var add_already=0;//已经加仓次数 + + var processor={}; + //重试购买,直到成功返回 + processor.retryBuy=function(ex,price,num) + { + var currency=ex.GetCurrency(); + var r=ex.Buy(_N(price,price_n[currency]), _N(num,num_n[currency])); + while (!r){ + Log("Buy失败,正在retry。"); + Sleep(wait_ms); + var account=_C(ex.GetAccount); + var ticker=_C(ex.GetTicker); + var last=ticker.Last; + var fixedAmount=(price===-1?Math.min(account.Balance*0.95,num):Math.min(account.Balance/last*0.95,num)); + r=ex.Buy(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); + } + return r; + } + + //重试卖出,直到成功返回 + processor.retrySell=function(ex,price,num){ + var currency=ex.GetCurrency(); + var r=ex.Sell(_N(price,price_n[currency]), _N(num,num_n[currency])); + while (!r){ + Log("Sell失败,正在retry。"); + Sleep(wait_ms); + var account=_C(ex.GetAccount); + var fixedAmount=Math.min(account.Stocks,num); + r=ex.Sell(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); + } + return r; + } + + + processor.get_ChinaTimeString=function(){ + var date = new Date(); + var now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), + date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); + var cdate=new Date(now_utc); + cdate.setHours(cdate.getHours()+8); + var localstring=cdate.getFullYear()+'/'+(cdate.getMonth()+1)+'/'+cdate.getDate()+' '+cdate.getHours()+':'+cdate.getMinutes()+':'+cdate.getSeconds(); + return localstring; + } + + processor.init_obj=function(){ + _CDelay(wait_ms); + pre_time = new Date(); + + //init + { + var account=_C(exc_obj.GetAccount); + var ticker=_C(exc_obj.GetTicker); + var last=ticker.Last; + init_asset=(account.Balance+account.FrozenBalance)+(account.Stocks+account.FrozenStocks)*last; + Sleep(wait_ms); + } + } + + + processor.work=function(){ + var cur_time = new Date(); + var passedtime=cur_time-pre_time; + pre_time=cur_time; + + //计算n,头寸 + var exname=exc_obj.GetName(); + var currency=exc_obj.GetCurrency(); + var account=_C(exc_obj.GetAccount); + var ticker=_C(exc_obj.GetTicker); + var depth = _C(exc_obj.GetDepth); + var last=ticker.Last; + var ask1=depth.Asks[0].Price; + var bid1=depth.Bids[0].Price; + var bestprice=bid1+(Math.abs(ask1-bid1)/2); + var records = _C(exc_obj.GetRecords); + if (records.length<=50){ + Log("records.length is not valid."); + Sleep(wait_ms); + return; + } + var atr = TA.ATR(records, 20); + if (atr.length<=1){ + Log("atr.length is not valid."); + Sleep(wait_ms); + return; + } + var N=atr[atr.length-1]; + var position_unit=Math.min(manage_assets*0.01/N,account.Balance/last*0.95);//cet + //Log("N="+N+", 头寸单位="+position_unit+"CET"); + var highest=TA.Highest(records, 20, 'High'); + var Lowest=TA.Lowest(records, 10, 'Low'); + var cur_asset=(account.Balance+account.FrozenBalance)+(account.Stocks+account.FrozenStocks)*last; + var rsi6 = TA.RSI(records, 6); + var rsi12 = TA.RSI(records, 12); + if (rsi6.length<=5 || rsi12.length<=5){ + Log("rsi is not valid."); + Sleep(wait_ms); + return; + } + var rsi_in=false; + if (rsi6[rsi6.length-1]-rsi6[rsi6.length-2]>1 && rsi6[rsi6.length-2]<=65){ + //Log("rsi_in=true"); + rsi_in=true; + } + var rsi_out=false; + if (rsi6[rsi6.length-1]>=60){ + //Log("rsi_out=true"); + rsi_out=true; + } + + //建仓 + if (positions.length==0 && position_unit>minest_buy[currency]){ + if (rsi_in) + { + var buyID = processor.retryBuy(exc_obj,last,position_unit); + Sleep(order_wait_secs); + var buyOrder=_C(exc_obj.GetOrder,buyID); + if (buyOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(buyID); + } + if (buyOrder.DealAmount>0){ + var postion = { + amount:buyOrder.DealAmount, + buy_price:buyOrder.AvgPrice, + stoploss_price:buyOrder.AvgPrice-N}; + positions.push(postion); + + var details={ + type:"建仓", + time:processor.get_ChinaTimeString(), + RealAmount:buyOrder.DealAmount, + WantAmount:position_unit, + RealPrice:buyOrder.AvgPrice, + WantPrice:buyOrder.Price, + Memo:"" + }; + if (trades_recorder){ + trades.push(details); + } + + add_already=1; + } + } + } + + //加仓 + if (positions.length>0 && position_unit>minest_buy[currency]){ + var last_buy_price=positions[positions.length-1].buy_price; + if (add_already=0.5*N){ + var buyID = processor.retryBuy(exc_obj,last,position_unit); + Sleep(order_wait_secs); + var buyOrder=_C(exc_obj.GetOrder,buyID); + if (buyOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(buyID); + } + if (buyOrder.DealAmount>0){ + var postion = { + amount:buyOrder.DealAmount, + buy_price:buyOrder.AvgPrice, + stoploss_price:buyOrder.AvgPrice-N}; + positions.push(postion); + + var details={ + type:"加仓", + time:processor.get_ChinaTimeString(), + RealAmount:buyOrder.DealAmount, + WantAmount:position_unit, + RealPrice:buyOrder.AvgPrice, + WantPrice:last, + Memo:"" + }; + if (trades_recorder){ + trades.push(details); + } + + add_already=add_already+1; + } + } + } + } + + //止损 + if (positions.length>0){ + var positions_new=[]; + for (var i=0; i < positions.length; i++){ + if (last<=positions[i].stoploss_price){ + account=_C(exc_obj.GetAccount); + var fixedAmount=Math.min(account.Stocks,positions[i].amount); + if (fixedAmount>minest_sell[currency]){ + var sellID = processor.retrySell(exc_obj, last, fixedAmount); + Sleep(order_wait_secs); + var sellOrder=_C(exc_obj.GetOrder,sellID); + approximate_profit+=(sellOrder.AvgPrice*sellOrder.DealAmount*(1-sxf)-positions[i].buy_price*sellOrder.DealAmount*(1+sxf)); + Log("定价卖出: 数量-"+sellOrder.DealAmount+",approximate_profit="+approximate_profit); + if (sellOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(sellID); + if (Math.min(account.Stocks,fixedAmount-sellOrder.DealAmount)>minest_sell[currency]){ + var marketsellOrderID=processor.retrySell(exc_obj, -1, fixedAmount-sellOrder.DealAmount); + Sleep(order_wait_secs); + var marketsellOrderData=_C(exc_obj.GetOrder,marketsellOrderID); + approximate_profit+=(marketsellOrderData.AvgPrice*marketsellOrderData.DealAmount*(1-sxf)-positions[i].buy_price*marketsellOrderData.DealAmount*(1+sxf)); + Log("市价卖出: 数量-"+marketsellOrderData.DealAmount+",approximate_profit="+approximate_profit); + } + } + + var details={ + type:"止损", + time:processor.get_ChinaTimeString(), + RealAmount:-1, + WantAmount:fixedAmount, + RealPrice:-1, + WantPrice:last, + Memo:(last>positions[i].buy_price?"盈利":"亏损") + }; + if (trades_recorder){ + trades.push(details); + } + } + }else{ + positions_new.push(positions[i]); + } + } + positions=positions_new; + } + + //清仓 + if (positions.length>0){ + if (rsi_out){ + var positions_new=[]; + for (var i=0; i < positions.length; i++){ + account=_C(exc_obj.GetAccount); + var fixedAmount=Math.min(account.Stocks,positions[i].amount); + if (fixedAmount>minest_sell[currency]){ + var sellID = processor.retrySell(exc_obj, last, fixedAmount); + Sleep(order_wait_secs); + var sellOrder=_C(exc_obj.GetOrder,sellID); + approximate_profit+=(sellOrder.AvgPrice*sellOrder.DealAmount*(1-sxf)-positions[i].buy_price*sellOrder.DealAmount*(1+sxf)); + Log("定价卖出: 数量-"+sellOrder.DealAmount+",approximate_profit="+approximate_profit); + if (sellOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(sellID); + if (Math.min(account.Stocks,fixedAmount-sellOrder.DealAmount)>minest_sell[currency]){ + var marketsellOrderID=processor.retrySell(exc_obj, -1, fixedAmount-sellOrder.DealAmount); + Sleep(order_wait_secs); + var marketsellOrderData=_C(exc_obj.GetOrder,marketsellOrderID); + approximate_profit+=(marketsellOrderData.AvgPrice*marketsellOrderData.DealAmount*(1-sxf)-positions[i].buy_price*marketsellOrderData.DealAmount*(1+sxf)); + Log("市价卖出: 数量-"+marketsellOrderData.DealAmount+",approximate_profit="+approximate_profit); + } + } + + var details={ + type:"清仓", + time:processor.get_ChinaTimeString(), + RealAmount:-1, + WantAmount:fixedAmount, + RealPrice:-1, + WantPrice:last, + Memo:(last>positions[i].buy_price?"盈利":"亏损") + }; + if (trades_recorder){ + trades.push(details); + } + } + } + positions=positions_new; + } + } + + + //显示状态 + var table1 = {type: 'table', title: '仓位-'+exname+'('+currency+')', cols: ['数量', '成交价','止损价'], rows: []}; + var table2 = {type: 'table', title: '状态-'+exname+'('+currency+')', cols: ['平均真实波幅(N)','头寸单位','初始资产','当前资产','轮询时间','最新价','Highest','Lowest','加仓次数','【近似盈亏】'], rows: []}; + var table3 = {type: 'table', title: '交易历史-'+exname+'('+currency+')', cols: ['日期','类型', '成交数量','发单数量','成交价','发单价','备注'], rows: []}; + for (var i=0; i < positions.length; i++){ + table1.rows.push([positions[i].amount,positions[i].buy_price,positions[i].stoploss_price]); + } + table2.rows.push([N,position_unit,init_asset,cur_asset,passedtime+'ms',last,highest,Lowest,add_already,approximate_profit]); + for (i=0; i < trades.length; i++){ + table3.rows.push([trades[i].time,trades[i].type,trades[i].RealAmount,trades[i].WantAmount,trades[i].RealPrice,trades[i].WantPrice,trades[i].Memo]); + } + processor.logstatus=('`' + JSON.stringify([table1, table2, table3])+'`'+'\n'); + + //记录盈利 + processor.logprofit=approximate_profit; + + //rest + Sleep(wait_ms); + } + + return processor; + } +}; + + + +//主函数 +function main(){ + var exchange_num=exchanges.length; + var processors=[]; + for (var i=0; i 策略出处 + +https://www.fmz.com/strategy/157366 + +> 更新时间 + +2019-07-16 14:28:24 diff --git "a/RangeBreak\347\255\226\347\225\245\344\270\216\346\263\242\345\212\250\347\216\207\347\233\270\347\273\223\345\220\210\347\232\204\345\256\236\346\210\230\345\272\224\347\224\250.md" "b/RangeBreak\347\255\226\347\225\245\344\270\216\346\263\242\345\212\250\347\216\207\347\233\270\347\273\223\345\220\210\347\232\204\345\256\236\346\210\230\345\272\224\347\224\250.md" new file mode 100644 index 00000000..837de762 --- /dev/null +++ "b/RangeBreak\347\255\226\347\225\245\344\270\216\346\263\242\345\212\250\347\216\207\347\233\270\347\273\223\345\220\210\347\232\204\345\256\236\346\210\230\345\272\224\347\224\250.md" @@ -0,0 +1,54 @@ + +> 策略名称 + +RangeBreak策略与波动率相结合的实战应用 + +> 策略作者 + +Hukybo + +> 策略描述 + +**策略简介** +RangeBreak策略最初来源于期货和外汇交易,属于日内突破策略的一种。在《Futures Truth Magazine》(美国权威交易系统评选杂志)中曾经连续多年排名前十。无论是专业的投资机构还是个人交易者都在广泛使用。但是,如果一个交易策略被大众广为所知,那么这个交易策略在实战中的应用就会大打折扣。所以,这篇文章的目的,不是介绍RangeBreak策略让大家生搬硬套,而是通过对RangeBreak策略的学习,让大家从一个盈利的交易系统中融会贯通,提高交易的能力。 + +点击:[阅读更加详细的策略介绍](https://www.fmz.com/digest-topic/4038) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N|0.5|N| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2015-02-22 00:00:00 +end: 2019-07-13 00:00:00 +period: 5m +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["RunMode",1,126961],["SlideTick",0,126961],["ContractType","ZC888",126961]] +*) + +Q:=BARSLAST(DATE<>REF(DATE,1))+1; // 判断是不是新一天的K线 +DIFF:=REF(HHV(HIGH,Q),Q)-REF(LLV(LOW,Q),Q); // 昨日最高价与最低价的价格差 +OO:=VALUEWHEN(Q=1,OPEN); // 当天开盘价 +UP^^OO+DIFF*N1; // 上轨 +DOWN^^OO-DIFF*N2; // 下轨 +TIME>=0905&&TIME<1455&&CLOSE>UP,BK; // 多头开仓 +TIME>=0905&&TIME<1455&&CLOSE=1455,CLOSEOUT; // 收盘平仓 +AUTOFILTER; // 信号过滤 +``` + +> 策略出处 + +https://www.fmz.com/strategy/156836 + +> 更新时间 + +2019-07-16 16:49:03 diff --git "a/\343\200\220\346\265\267\351\276\237\346\261\244\347\255\226\347\225\245\343\200\221\345\217\215\350\266\213\345\212\277\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/\343\200\220\346\265\267\351\276\237\346\261\244\347\255\226\347\225\245\343\200\221\345\217\215\350\266\213\345\212\277\344\272\244\346\230\223\347\255\226\347\225\245.md" new file mode 100644 index 00000000..1c8befb9 --- /dev/null +++ "b/\343\200\220\346\265\267\351\276\237\346\261\244\347\255\226\347\225\245\343\200\221\345\217\215\350\266\213\345\212\277\344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -0,0 +1,286 @@ + +> 策略名称 + +【海龟汤策略】反趋势交易策略 + +> 策略作者 + +coin989 + +> 策略描述 + +海龟之汤,简称“龟汤”,是个与海龟交易法则相反的交易策略,它利用了跟势交易(特别是海龟方式)在很多假突破方面的缺陷来获利(把海龟做成汤吃掉)。 + +上世纪八十年代早期,有个非常著名的交易员团体——叫做“海龟”。缔造了交易传奇的市场大师理查德·丹尼斯在训练一组新交易员的时候起了这个有趣的名字。因为理查德相信,培训交易员,其实就像新加坡人养海龟一样。这个交易方法被称作海龟方法,这个简单的趋势跟随技巧方法曾令他们的导师理查德取得了巨大的成功。 + +二十多年过去了,海龟方法现在已不再是个秘密,很多人已经了解它。尽管如此,那为何仍没多少人用它交易取得成功呢?那是因为趋势跟随策略通常需要忍受大幅度和长时间的回撤。很多投资者或交易员没有足够的资本或者愿意坚持这些长期的亏损。通常大多数人在交易转向对他们有利之前就已经退出了。 + +琳达·华斯基和拉利·康诺在他们的书《华尔街精灵——屡试不爽的短期交易策略》(Street Smarts)中命名了这个与“海龟”交易法则相反的“龟汤”交易法则。大多数策略不能保持盈利的原因是,一旦很多市场参与者使用它们,这些策略的盈利能力就将退化。这是市场用来平衡那些不平衡现象的方法。华斯基通过与海龟方法相反的交易,发现更多成功和获利的结果。因为海龟法需要很多失败的交易和坐等坏的交易变得盈利。通常当它获利时,它会抵消那些所有的亏损才盈利,而且这个现象周而复始。很显然,华斯基创造这个策略“海龟之汤”的名字是种美式幽默,它利用海龟交易者的成本来获利(把海龟做成汤吃掉)。 + +原始的“海龟”交易规则至少是波段交易或更久的交易,时间跨度在一周到一个月之间。华斯基女士使用“龟汤”策略做更短期的日内或波段交易,集中地利用了假突破的高频发生现象。一般来说,“海龟”法使用的20天周期突破:突破20日高则买入,跌破20日低则抛售。而“龟汤”交易法则采用完全相反的方法。 + +策略特点: +支持任意级别的趋势跟踪(分钟K,小时K,日K,周K等) +支持任意交易对(ETH/BTC, BSV/BTC等) +支持任意交易所 +详细的策略报表(包括策略状态,交易历史记录等) +支持接近10个自定义个性化参数 + +依赖项botvs_tools模板库下载: +https://www.pcclean.io/9o7u + + + +> 源码 (javascript) + +``` javascript +var strategy_version="1.0.0.0(new release 仅供学习研究使用,实盘后果自负。实盘策略访问http://pcclean.io/quant )"; + +var price_n={Futures_OKCoin_BSV_USD:2}; +var num_n={Futures_OKCoin_BSV_USD:0}; +var minestbuy={Futures_OKCoin_BSV_USD:1}; +var price_step={Futures_OKCoin_BSV_USD:0.05}; +var contract_min={Futures_OKCoin_BSV_USD:10}; +var wait_ms=3000; +var max_wait_order=15000; +var max_positions=4; + +//gloabl variables +var positions_duo=[]; +var positions_kong=[]; +var total_loop=0; +var bet_duo=0; +var bet_kong=0; + +function main(){ + Log("strategy_version="+strategy_version); + $.set_params(price_n,num_n,minestbuy,price_step,wait_ms,max_wait_order); + while(true){ + var exname=exchange.GetName(); + var currency=exchange.GetCurrency(); + var account=_C(exchange.GetAccount); + var ticker=_C(exchange.GetTicker); + var depth=_C(exchange.GetDepth); + var sell1=depth.Asks[0].Price; + var buy1=depth.Bids[0].Price; + var records=_C(exchange.GetRecords); + if (records.length<=50){ + Log("records.length无效,跳过此次执行..."); + Sleep(wait_ms); + continue; + } + var atr = TA.ATR(records, 20); + if (atr.length<=1){ + Log("atr.length无效,跳过此次执行..."); + Sleep(wait_ms); + continue; + } + var N=atr[atr.length-1]; + var position_unit=account.Stocks/(max_positions*2); + var highest20=TA.Highest(records, 20, 'High'); + var lowest20=TA.Lowest(records, 20, 'Low'); + var highest10=TA.Highest(records, 10, 'High'); + var lowest10=TA.Lowest(records, 10, 'Low'); + + //建仓 + if (positions_duo.length===0){ + if (sell1<=lowest20){ + var heyuefenshu=_N(position_unit*sell1/contract_min[$.get_exchange_id(exchange)],0); + exchange.SetDirection("buy"); + var dealamount=$.perform_limited_order("buy",exchange,sell1,heyuefenshu,false,"futures","buy"); + if (dealamount>0){ + var postion = { + amount:dealamount, + price:sell1, + stoploss_price:sell1-2.5*N, + stopwin_price:sell1+2.5*N, + }; + positions_duo.push(postion); + bet_duo=1; + } + } + } + if (positions_kong.length===0){ + if (buy1>=highest20){ + var heyuefenshu=_N(position_unit*buy1/contract_min[$.get_exchange_id(exchange)],0); + exchange.SetDirection("sell"); + var dealamount=$.perform_limited_order("buy",exchange,buy1,heyuefenshu,false,"futures","sell"); + if (dealamount>0){ + var postion = { + amount:dealamount, + price:buy1, + stoploss_price:buy1+2.5*N, + stopwin_price:buy1-2.5*N, + }; + positions_kong.push(postion); + bet_kong=1; + } + } + } + //加仓 + if (positions_duo.length>0){ + var last_price=positions_duo[positions_duo.length-1].price; + if (bet_duo=0.5*N){ + var heyuefenshu=_N(position_unit*sell1/contract_min[$.get_exchange_id(exchange)],0); + exchange.SetDirection("buy"); + var dealamount=$.perform_limited_order("buy",exchange,sell1,heyuefenshu,false,"futures","buy"); + if (dealamount>0){ + var postion = { + amount:dealamount, + price:sell1, + stoploss_price:sell1-2.5*N, + stopwin_price:sell1+2.5*N, + }; + positions_duo.push(postion); + bet_duo+=1; + } + } + } + } + if (positions_kong.length>0){ + var last_price=positions_kong[positions_kong.length-1].price; + if (bet_kong=0.5*N){ + var heyuefenshu=_N(position_unit*buy1/contract_min[$.get_exchange_id(exchange)],0); + exchange.SetDirection("sell"); + var dealamount=$.perform_limited_order("buy",exchange,buy1,heyuefenshu,false,"futures","sell"); + if (dealamount>0){ + var postion = { + amount:dealamount, + price:buy1, + stoploss_price:buy1+2.5*N, + stopwin_price:buy1-2.5*N, + }; + positions_kong.push(postion); + bet_kong+=1; + } + } + } + } + //止损 + if (positions_duo.length>0){ + var positions_duo_new=[]; + for (var i=0; i < positions_duo.length; i++){ + if (buy1<=positions_duo[i].stoploss_price){ + exchange.SetDirection("closebuy"); + $.perform_limited_order("sell",exchange,buy1,positions_duo[i].amount,true,"futures","closebuy"); + }else{ + positions_duo_new.push(positions_duo[i]); + } + } + positions_duo=positions_duo_new; + } + if (positions_kong.length>0){ + var positions_kong_new=[]; + for (var i=0; i < positions_kong.length; i++){ + if (sell1>=positions_kong[i].stoploss_price){ + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,sell1,positions_kong[i].amount,true,"futures","closesell"); + }else{ + positions_kong_new.push(positions_kong[i]); + } + } + positions_kong=positions_kong_new; + } + //止盈 + if (positions_duo.length>0){ + var positions_duo_new=[]; + for (var i=0; i < positions_duo.length; i++){ + if (buy1>=positions_duo[i].stopwin_price){ + exchange.SetDirection("closebuy"); + $.perform_limited_order("sell",exchange,buy1,positions_duo[i].amount,true,"futures","closebuy"); + }else{ + positions_duo_new.push(positions_duo[i]); + } + } + positions_duo=positions_duo_new; + } + if (positions_kong.length>0){ + var positions_kong_new=[]; + for (var i=0; i < positions_kong.length; i++){ + if (sell1<=positions_kong[i].stopwin_price){ + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,sell1,positions_kong[i].amount,true,"futures","closesell"); + }else{ + positions_kong_new.push(positions_kong[i]); + } + } + positions_kong=positions_kong_new; + } + //清仓 + if (positions_duo.length>0){ + if (buy1>=highest10){ + for (var i=0; i < positions_duo.length; i++){ + exchange.SetDirection("closebuy"); + $.perform_limited_order("sell",exchange,buy1,positions_duo[i].amount,true,"futures","closebuy"); + } + positions_duo=[]; + } + } + if (positions_kong.length>0){ + if (sell1<=lowest10){ + for (var i=0; i < positions_kong.length; i++){ + exchange.SetDirection("closesell"); + $.perform_limited_order("sell",exchange,sell1,positions_kong[i].amount,true,"futures","closesell"); + } + positions_kong=[]; + } + } + //交易所强平 + var current_ok_position=_C(exchange.GetPosition);//must update here + if (current_ok_position.length===0){ + positions_duo=[]; + positions_kong=[]; + } + + //chart + var table1={type: 'table', title: '期货仓位', cols: ['交易所','持仓量','冻结量','持仓均价','实现盈余','类型','合约代码'], rows: []}; + var table2={type: 'table', title: '跟踪仓位', cols: ['交易所','类型','数量','价格','止损价','止盈价'], rows: []}; + for (var i=0; i < current_ok_position.length; i++){ + table1.rows.push([exname, + current_ok_position[i].Amount, + current_ok_position[i].FrozenAmount, + current_ok_position[i].Price, + current_ok_position[i].Profit, + current_ok_position[i].Type, + current_ok_position[i].ContractType]); + } + for (i=0; i 策略出处 + +https://www.fmz.com/strategy/157372 + +> 更新时间 + +2019-07-16 14:57:23 diff --git "a/\343\200\220\347\273\217\345\205\270\350\266\213\345\212\277\347\255\226\347\225\245\343\200\221\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/\343\200\220\347\273\217\345\205\270\350\266\213\345\212\277\347\255\226\347\225\245\343\200\221\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.md" new file mode 100644 index 00000000..2dc991ba --- /dev/null +++ "b/\343\200\220\347\273\217\345\205\270\350\266\213\345\212\277\347\255\226\347\225\245\343\200\221\346\265\267\351\276\237\344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -0,0 +1,405 @@ + +> 策略名称 + +【经典趋势策略】海龟交易策略 + +> 策略作者 + +zzx2019 + +> 策略描述 + +海龟交易策略是趋势策略中非常经典的交易策略,能在交易风险,仓位,资金利用率各方面做到很精细的控制。只要市场出现较大趋势(不管基于分钟K线,小时K线还是日K),海龟都会捕获到趋势并让利润最大化。此策略基于原版海龟交易法则实现,在2017年大牛市下取得了700%,远远高于大盘的收益。 + +策略特点: +支持任意级别的趋势跟踪(分钟K,小时K,日K,周K等) +支持任意交易对(ETH/BTC, BSV/BTC等) +详细的策略报表(包括策略状态,交易历史记录等) +支持10几个自定义个性化参数 + +参数说明: +请查看 https://www.pcclean.io/z6zl + + + +> 源码 (javascript) + +``` javascript +/* +海龟策略 +用途:分散风险,平抑波动 +17:34 2018/9/12 retrySell后加sleep,解决清仓余额不足的问题 +17:58 2018/9/12 fixed Sell(-1, 0.00033): Less than minimum requirement +8:58 2018/9/13 fixed 无限仓位问题 +11:12 2018/9/13 符合海龟交易法则 +20:23 2018/9/23 修改清仓时不更新account.stock的问题 +11:14 2018/10/18 retrysell函数支持 对最小数量的自动修正 +11:16 2018/10/19 支持utc+8时间和logprofit +15:13 2018/10/19 支持对象化和管理多个交易对 +23:28 2018/10/20 支持统计手续费损失 +9:05 2018/10/22 retryBuy支持自动修正买入量 +22:10 2018/12/22 支持统计市价单盈亏 +11:40 2019/04/25 支持收益曲线连续 +*/ + +var ExchangProcessor={ + createNew: function(exc_obj){ + //策略参数 + var manage_assets=1;//bch + var max_positions=4;//max=4N + var price_n={BTC_BCH:8,ETH_BCH:8,XRP_BCH:8,EOS_BCH:8,LTC_BCH:8,DASH_BCH:8,CET_BCH:8}; //价格精度 + var num_n={BTC_BCH:8,ETH_BCH:8,XRP_BCH:8,EOS_BCH:8,LTC_BCH:8,DASH_BCH:8,CET_BCH:8}; //数量精度 + var minest_buy={BTC_BCH:0.001,ETH_BCH:0.01,XRP_BCH:1,EOS_BCH:1,LTC_BCH:0.1,DASH_BCH:0.01,CET_BCH:1};//最小买入量 + var minest_sell={BTC_BCH:0.001,ETH_BCH:0.01,XRP_BCH:1,EOS_BCH:1,LTC_BCH:0.1,DASH_BCH:0.01,CET_BCH:1};//最小卖出量 + var order_wait_secs=120000; //订单的最长等待时间 毫秒 + var wait_ms=1000;//默认等待毫秒 + var sxf=0.0005;//用来计算手续费消耗 + + + //全局状态变量 + var positions=[];//记录仓位 + var init_asset=0; //初始资产 + var trades=[];//所有交易 + var trades_recorder=true;//记录所有交易 + var pre_time=null; //记录轮询间隔时间 + var approximate_profit=0;//盈亏近似值 + var add_already=0;//已经加仓次数 + + var processor={}; + //重试购买,直到成功返回 + processor.retryBuy=function(ex,price,num) + { + var currency=ex.GetCurrency(); + var r=ex.Buy(_N(price,price_n[currency]), _N(num,num_n[currency])); + while (!r){ + Log("Buy失败,正在retry。"); + Sleep(wait_ms); + var account=_C(ex.GetAccount); + var ticker=_C(ex.GetTicker); + var last=ticker.Last; + var fixedAmount=(price===-1?Math.min(account.Balance*0.95,num):Math.min(account.Balance/last*0.95,num)); + r=ex.Buy(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); + } + return r; + } + + //重试卖出,直到成功返回 + processor.retrySell=function(ex,price,num){ + var currency=ex.GetCurrency(); + var r=ex.Sell(_N(price,price_n[currency]), _N(num,num_n[currency])); + while (!r){ + Log("Sell失败,正在retry。"); + Sleep(wait_ms); + var account=_C(ex.GetAccount); + var fixedAmount=Math.min(account.Stocks,num); + r=ex.Sell(_N(price,price_n[currency]), _N(fixedAmount,num_n[currency])); + } + return r; + } + + + processor.get_ChinaTimeString=function(){ + var date = new Date(); + var now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), + date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); + var cdate=new Date(now_utc); + cdate.setHours(cdate.getHours()+8); + var localstring=cdate.getFullYear()+'/'+(cdate.getMonth()+1)+'/'+cdate.getDate()+' '+cdate.getHours()+':'+cdate.getMinutes()+':'+cdate.getSeconds(); + return localstring; + } + + processor.init_obj=function(){ + _CDelay(wait_ms); + pre_time = new Date(); + + //init + { + var account=_C(exc_obj.GetAccount); + var ticker=_C(exc_obj.GetTicker); + var last=ticker.Last; + init_asset=(account.Balance+account.FrozenBalance)+(account.Stocks+account.FrozenStocks)*last; + Sleep(wait_ms); + } + } + + + processor.work=function(){ + var cur_time = new Date(); + var passedtime=cur_time-pre_time; + pre_time=cur_time; + + //计算n,头寸 + var exname=exc_obj.GetName(); + var currency=exc_obj.GetCurrency(); + var account=_C(exc_obj.GetAccount); + var ticker=_C(exc_obj.GetTicker); + var depth = _C(exc_obj.GetDepth); + var last=ticker.Last; + var ask1=depth.Asks[0].Price; + var bid1=depth.Bids[0].Price; + var bestprice=bid1+(Math.abs(ask1-bid1)/2); + var records = _C(exc_obj.GetRecords); + if (records.length<=50){ + Log("records.length is not valid."); + Sleep(wait_ms); + return; + } + var atr = TA.ATR(records, 20); + if (atr.length<=1){ + Log("atr.length is not valid."); + Sleep(wait_ms); + return; + } + var N=atr[atr.length-1]; + var position_unit=Math.min(manage_assets*0.01/N,account.Balance/last*0.95);//cet + //Log("N="+N+", 头寸单位="+position_unit+"CET"); + var highest=TA.Highest(records, 20, 'High'); + var Lowest=TA.Lowest(records, 10, 'Low'); + var cur_asset=(account.Balance+account.FrozenBalance)+(account.Stocks+account.FrozenStocks)*last; + var rsi6 = TA.RSI(records, 6); + var rsi12 = TA.RSI(records, 12); + if (rsi6.length<=5 || rsi12.length<=5){ + Log("rsi is not valid."); + Sleep(wait_ms); + return; + } + var rsi_in=false; + if (rsi6[rsi6.length-1]-rsi6[rsi6.length-2]>5 && + rsi6[rsi6.length-3]-rsi6[rsi6.length-2]>5 && + rsi6[rsi6.length-2]<=55 && + rsi6[rsi6.length-1]>rsi12[rsi12.length-1]){ + //Log("rsi_in=true"); + rsi_in=true; + } + var rsi_out=false; + if (rsi6[rsi6.length-2]-rsi6[rsi6.length-1]>5 && + rsi6[rsi6.length-2]>=70){ + //Log("rsi_out=true"); + rsi_out=true; + } + + //建仓 + if (positions.length==0 && position_unit>minest_buy[currency]){ + if (last>=highest) + { + var buyID = processor.retryBuy(exc_obj,last,position_unit); + Sleep(order_wait_secs); + var buyOrder=_C(exc_obj.GetOrder,buyID); + if (buyOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(buyID); + } + if (buyOrder.DealAmount>0){ + var postion = { + amount:buyOrder.DealAmount, + buy_price:buyOrder.AvgPrice, + stoploss_price:buyOrder.AvgPrice-2*N}; + positions.push(postion); + + var details={ + type:"建仓", + time:processor.get_ChinaTimeString(), + RealAmount:buyOrder.DealAmount, + WantAmount:position_unit, + RealPrice:buyOrder.AvgPrice, + WantPrice:buyOrder.Price, + Memo:"" + }; + if (trades_recorder){ + trades.push(details); + } + + add_already=1; + } + } + } + + //加仓 + if (positions.length>0 && position_unit>minest_buy[currency]){ + var last_buy_price=positions[positions.length-1].buy_price; + if (add_already=0.5*N){ + var buyID = processor.retryBuy(exc_obj,last,position_unit); + Sleep(order_wait_secs); + var buyOrder=_C(exc_obj.GetOrder,buyID); + if (buyOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(buyID); + } + if (buyOrder.DealAmount>0){ + var postion = { + amount:buyOrder.DealAmount, + buy_price:buyOrder.AvgPrice, + stoploss_price:buyOrder.AvgPrice-2*N}; + positions.push(postion); + + var details={ + type:"加仓", + time:processor.get_ChinaTimeString(), + RealAmount:buyOrder.DealAmount, + WantAmount:position_unit, + RealPrice:buyOrder.AvgPrice, + WantPrice:last, + Memo:"" + }; + if (trades_recorder){ + trades.push(details); + } + + add_already=add_already+1; + } + } + } + } + + //止损 + if (positions.length>0){ + var positions_new=[]; + for (var i=0; i < positions.length; i++){ + if (last<=positions[i].stoploss_price){ + account=_C(exc_obj.GetAccount); + var fixedAmount=Math.min(account.Stocks,positions[i].amount); + if (fixedAmount>minest_sell[currency]){ + var sellID = processor.retrySell(exc_obj, last, fixedAmount); + Sleep(order_wait_secs); + var sellOrder=_C(exc_obj.GetOrder,sellID); + approximate_profit+=(sellOrder.AvgPrice*sellOrder.DealAmount*(1-sxf)-positions[i].buy_price*sellOrder.DealAmount*(1+sxf)); + Log("定价卖出: 数量-"+sellOrder.DealAmount+",approximate_profit="+approximate_profit); + if (sellOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(sellID); + if (Math.min(account.Stocks,fixedAmount-sellOrder.DealAmount)>minest_sell[currency]){ + var marketsellOrderID=processor.retrySell(exc_obj, -1, fixedAmount-sellOrder.DealAmount); + Sleep(order_wait_secs); + var marketsellOrderData=_C(exc_obj.GetOrder,marketsellOrderID); + approximate_profit+=(marketsellOrderData.AvgPrice*marketsellOrderData.DealAmount*(1-sxf)-positions[i].buy_price*marketsellOrderData.DealAmount*(1+sxf)); + Log("市价卖出: 数量-"+marketsellOrderData.DealAmount+",approximate_profit="+approximate_profit); + } + } + + var details={ + type:"止损", + time:processor.get_ChinaTimeString(), + RealAmount:-1, + WantAmount:fixedAmount, + RealPrice:-1, + WantPrice:last, + Memo:(last>positions[i].buy_price?"盈利":"亏损") + }; + if (trades_recorder){ + trades.push(details); + } + } + }else{ + positions_new.push(positions[i]); + } + } + positions=positions_new; + } + + //清仓 + if (positions.length>0){ + if (last<=Lowest){ + var positions_new=[]; + for (var i=0; i < positions.length; i++){ + account=_C(exc_obj.GetAccount); + var fixedAmount=Math.min(account.Stocks,positions[i].amount); + if (fixedAmount>minest_sell[currency]){ + var sellID = processor.retrySell(exc_obj, last, fixedAmount); + Sleep(order_wait_secs); + var sellOrder=_C(exc_obj.GetOrder,sellID); + approximate_profit+=(sellOrder.AvgPrice*sellOrder.DealAmount*(1-sxf)-positions[i].buy_price*sellOrder.DealAmount*(1+sxf)); + Log("定价卖出: 数量-"+sellOrder.DealAmount+",approximate_profit="+approximate_profit); + if (sellOrder.Status!=ORDER_STATE_CLOSED){ + exc_obj.CancelOrder(sellID); + if (Math.min(account.Stocks,fixedAmount-sellOrder.DealAmount)>minest_sell[currency]){ + var marketsellOrderID=processor.retrySell(exc_obj, -1, fixedAmount-sellOrder.DealAmount); + Sleep(order_wait_secs); + var marketsellOrderData=_C(exc_obj.GetOrder,marketsellOrderID); + approximate_profit+=(marketsellOrderData.AvgPrice*marketsellOrderData.DealAmount*(1-sxf)-positions[i].buy_price*marketsellOrderData.DealAmount*(1+sxf)); + Log("市价卖出: 数量-"+marketsellOrderData.DealAmount+",approximate_profit="+approximate_profit); + } + } + + var details={ + type:"清仓", + time:processor.get_ChinaTimeString(), + RealAmount:-1, + WantAmount:fixedAmount, + RealPrice:-1, + WantPrice:last, + Memo:(last>positions[i].buy_price?"盈利":"亏损") + }; + if (trades_recorder){ + trades.push(details); + } + } + } + positions=positions_new; + } + } + + + //显示状态 + var table1 = {type: 'table', title: '仓位-'+exname+'('+currency+')', cols: ['数量', '成交价','止损价'], rows: []}; + var table2 = {type: 'table', title: '状态-'+exname+'('+currency+')', cols: ['平均真实波幅(N)','头寸单位','初始资产','当前资产','轮询时间','最新价','Highest','Lowest','加仓次数','【近似盈亏】'], rows: []}; + var table3 = {type: 'table', title: '交易历史-'+exname+'('+currency+')', cols: ['日期','类型', '成交数量','发单数量','成交价','发单价','备注'], rows: []}; + for (var i=0; i < positions.length; i++){ + table1.rows.push([positions[i].amount,positions[i].buy_price,positions[i].stoploss_price]); + } + table2.rows.push([N,position_unit,init_asset,cur_asset,passedtime+'ms',last,highest,Lowest,add_already,approximate_profit]); + for (i=0; i < trades.length; i++){ + table3.rows.push([trades[i].time,trades[i].type,trades[i].RealAmount,trades[i].WantAmount,trades[i].RealPrice,trades[i].WantPrice,trades[i].Memo]); + } + processor.logstatus=('`' + JSON.stringify([table1, table2, table3])+'`'+'\n'); + + //记录盈利 + processor.logprofit=approximate_profit; + + //rest + Sleep(wait_ms); + } + + return processor; + } +}; + + + +//主函数 +function main(){ + var exchange_num=exchanges.length; + var processors=[]; + for (var i=0; i 策略出处 + +https://www.fmz.com/strategy/157270 + +> 更新时间 + +2019-07-16 14:07:22 diff --git "a/\345\201\232\345\270\202\347\255\226\347\225\245(basefex).md" "b/\345\201\232\345\270\202\347\255\226\347\225\245(basefex).md" new file mode 100644 index 00000000..01987c79 --- /dev/null +++ "b/\345\201\232\345\270\202\347\255\226\347\225\245(basefex).md" @@ -0,0 +1,449 @@ + +> 策略名称 + +做市策略(basefex) + +> 策略作者 + +daniaoren + +> 策略描述 + +自用做市策略备份 + +不能直接用,需配合自己的keygen模块生成私钥 + + + +> 源码 (python) + +``` python +import requests +import json +import time +import logging +from tenacity import * +from keygen import * + +TELEGRAM = False +if len(sys.argv) > 1: + if sys.argv[1] == 'telegram': + TELEGRAM = True +if TELEGRAM: + from telegram_bot import * +else: + def sendBotMessage(msg): + print ('telegram:', msg) + logger.debug('telegram: %s', msg) + def getNewMessage(): + return '' + +global LOGGING_LEVEL +#LOGGING_LEVEL = logging.DEBUG +LOGGING_LEVEL = logging.INFO + +baseurl = 'https://api.basefex.com' +slidePrice = 1 +minDiff = 10 #最小做市差价 +minAmount = 30 #最小下单量 +balancePosition = 200 #仓位为多少时考虑平衡减仓或市价减仓 +balanceDiff = 12 #差价为多少时考虑平衡减仓 +immediateBalanceDiff = 50 #差价为多少时市价减仓 +liquidatePriceAlertLow = 4000 #强平危险区下限 +liquidatePriceAlertHigh = 20000 #强平危险区上限 +lastBuyPrice = 0 +lastSellPrice = 0 +lastBuyAmount = 0 +lastSellAmount = 0 +currentBalance = 0 +currentPosition = [] +initBalance = 0 +tradeList = [] +totalBuyAmount = 0 +totalBuyPosition = 0 +totalSellAmount = 0 +totalSellPosition = 0 +totalBuyCount = 0 +totalSellCount = 0 + +@retry(stop=(stop_after_delay(10) | stop_after_attempt(5)) , wait=wait_fixed(2)) +def safeRequest(url, hed): + response = requests.get(url, headers=hed) + return response + +@retry(stop=(stop_after_delay(10) | stop_after_attempt(5)) , wait=wait_fixed(2)) +def safeRequestPost(url, hed, payload): + response = requests.post(url, headers=hed, json=payload) + return response + +@retry(stop=(stop_after_delay(10) | stop_after_attempt(5)) , wait=wait_fixed(2)) +def safeRequestDelete(url, hed): + response = requests.delete(url, headers=hed) + return response + +def getAccountInfo(): + uri = '/accounts' + auth_token = generate_token(key_id, private_key, "GET", 1584014794, uri) + hed = {'authorization': 'Bearer ' + auth_token} + response = safeRequest(baseurl+uri, hed) + return response.json() + +def updateAccount(): + global currentBalance + global currentPosition + accountInfo = getAccountInfo()[0] + currentBalance = accountInfo['cash']['balances'] + for position in accountInfo['positions']: + if position['symbol'] == 'BTCUSD': + currentPosition = position + break + print('CURRENT POSITION: ', currentPosition['entryPrice'], currentPosition['size']) + print('CURRENT BALANCE: ', currentBalance, 'PROFIT: ', currentBalance - initBalance) + logger.info('CURRENT BALANCE: %s | POSITION %s@%s', currentBalance, currentPosition['size'], currentPosition['entryPrice']) + logger.info('PROFIT: %s', currentBalance - initBalance) + return accountInfo + +def getTradeList(limit): + uri = '/trades' + query = '?limit=' + str(limit) + auth_token = generate_token(key_id, private_key, "GET", 1584014794, uri, query) + hed = {'authorization': 'Bearer ' + auth_token} + response = safeRequest(baseurl+uri+query, hed) + return response.json() + +def getCurrentBestPrices(): + uri = '/depth@BTCUSD/snapshot' + auth_token = generate_token(key_id, private_key, "GET", 1584014794, uri) + hed = {'authorization': 'Bearer ' + auth_token} + response = safeRequest(baseurl+uri, hed) + return response.json()['bestPrices'] + +def placeOrder(price, amount, side): + if amount == 0: + print ("amount is zero return") + return + payload = {'price': price, 'size': amount, 'type': 'LIMIT', 'side': side, 'symbol': 'BTCUSD'} + print (payload) + uri = '/orders' + auth_token = generate_token(key_id, private_key, "POST", 1584014794, "/orders", "", json.dumps(payload)) + hed = {'authorization': 'Bearer ' + auth_token, 'Content-Type': 'application/json'} + response = safeRequestPost(baseurl+uri, hed, payload) + # 如果下单失败,报错返回 + if (str(response) != ''): + print (str(response)) + logger.error('PLACE ORDER ERROR: %s', str(response)) + sendBotMessage('PLACE ORDER ERROR: ' + str(response)) + return + # 下单成功,记录相关信息 + if side == 'BUY': + global lastBuyPrice + global lastBuyAmount + lastBuyPrice = price + lastBuyAmount = amount + elif side == 'SELL': + global lastSellPrice + global lastSellAmount + lastSellPrice = price + lastSellAmount = amount + else: + logger.error('ERROR: unexpected side') + sendBotMessage('ERROR: unexpected side') + return response.json() + +def cancelOrder(id): + uri = '/orders/'+id + auth_token = generate_token(key_id, private_key, "DELETE", 1584014794, uri) + hed = {'authorization': 'Bearer ' + auth_token} + response = safeRequestDelete(baseurl+uri, hed) + return response + +def getOpeningOrderCount(): + uri = '/orders/opening/count' + query = '?symbol=BTCUSD' + auth_token = generate_token(key_id, private_key, "GET", 1584014794, uri, query) + hed = {'authorization': 'Bearer ' + auth_token} + response = safeRequest(baseurl+uri+query, hed) + return response.json() + +def getOpeningOrderList(): + uri = '/orders/opening' + query = '?symbol=BTCUSD' + auth_token = generate_token(key_id, private_key, "GET", 1584014794, uri, query) + hed = {'authorization': 'Bearer ' + auth_token} + response = safeRequest(baseurl+uri+query, hed) + return response.json() + +def getOrderList(): + uri = '/orders' + query = '?symbol=BTCUSD' + auth_token = generate_token(key_id, private_key, "GET", 1584014794, uri, query) + hed = {'authorization': 'Bearer ' + auth_token} + response = safeRequest(baseurl+uri+query, hed) + return response.json() + +def cancelPendingOrders(): + orderList = getOpeningOrderList() + if len(orderList) <= 0: + return + for order in orderList: + print('canceled:',order['id']) + cancelOrder(order['id']) + return + +def cancelPendingBuyOrders(): + orderList = getOpeningOrderList() + if len(orderList) <= 0: + return + for order in orderList: + if order['side'] == 'BUY': + cancelOrder(order['id']) + return + +def cancelPendingSellOrders(): + orderList = getOpeningOrderList() + if len(orderList) <= 0: + return + for order in orderList: + if order['side'] == 'SELL': + cancelOrder(order['id']) + return + +def setLogger(loggerName): + logger = logging.getLogger(loggerName) + global LOGGING_LEVEL + logger.setLevel(LOGGING_LEVEL) + + fileHandler = logging.FileHandler(loggerName+'.log', mode='a') + formatter = logging.Formatter('%(asctime)s - %(message)s') + fileHandler.setFormatter(formatter) + logger.addHandler(fileHandler) + return logger + +def onTick(): + #初始化状态及 确认价位 + global lastBuyPrice, lastSellPrice, lastBuyAmount, lastSellAmount + cancelBuyOrder = False + cancelSellOrder = False + result = getCurrentBestPrices() + bestAsk = result['ask'] + bestBid = result['bid'] + print('bestBid',bestBid,'bestAsk',bestAsk) + logger.info('bestBid: %s|bestAsk: %s',bestBid,bestAsk) + logger.info('LastBuy %s@%s | LastSell %s@%s', lastBuyAmount,lastBuyPrice,lastSellAmount,lastSellPrice) + buyPrice = bestBid + slidePrice + sellPrice = bestAsk - slidePrice + #确认仓位 + global currentPosition + buyAmountAdjust = 0 + sellAmountAdjust = 0 + + #####平衡模块#### + #是否满足市价平仓条件,满足直接尝试平仓并返回 + #平仓条件:仓位大于balancePosition, 价差大于immediateBalanceDiff + #买单方向 + if (currentPosition['size'] > balancePosition): + if bestBid - currentPosition['entryPrice'] > immediateBalanceDiff: + cancelPendingOrders() + placeOrder(bestBid, abs(currentPosition['size']), 'SELL') + print('immediateBalance', currentPosition) + sendBotMessage('IMMEDIATE BALANCE\n' + "Position: "+str(currentPosition['size'])+"@"+str(currentPosition['entryPrice'])+"\nBest Bid: " + str(bestBid)) + sleep(3) + cancelPendingOrders() + updateAccount() + return + #卖单方向 + elif ( currentPosition['size'] < -balancePosition): + if currentPosition['entryPrice'] - bestAsk > immediateBalanceDiff: + cancelPendingOrders() + placeOrder(bestAsk, abs(currentPosition['size']), 'BUY') + print('immediateBalance', currentPosition) + sendBotMessage('IMMEDIATE BALANCE\n' + "Position: "+str(currentPosition['size'])+"@"+str(currentPosition['entryPrice'])+"\nBest Ask: " + str(bestAsk)) + sleep(3) + cancelPendingOrders() + updateAccount() + return + + #不能市价平仓,调整买卖单数量偏向减仓 + #买单方向 + if (currentPosition['size'] > balancePosition): + if sellPrice - currentPosition['entryPrice'] > balanceDiff: + sellAmountAdjust = int(currentPosition['size']/10) + print('adjust buy/sell', buyAmountAdjust,sellAmountAdjust) + #卖单方向 + elif ( currentPosition['size'] < -balancePosition): + if currentPosition['entryPrice'] - buyPrice >balanceDiff: + buyAmountAdjust = int(currentPosition['size'] / -10) + print('adjust buy/sell', buyAmountAdjust,sellAmountAdjust) + + #确认是否进入强平危险区 + #强制平衡时只能单方面下单 + liquidatePrice = currentPosition['liquidatePrice'] + if liquidatePrice > liquidatePriceAlertLow and currentPosition['size'] > balancePosition: + logger.info('Liquidate risk ONLY CAN SELL') + buyAmountAdjust = -minAmount + elif liquidatePrice < liquidatePriceAlertHigh and currentPosition['size'] < -balancePosition: + logger.info('Liquidate risk ONLY CAN BUY') + sellAmountAdjust = -minAmount + ####平衡模块结束#### + + ####做市下单模块#### + #差价不满足条件,取消所有订单并返回 + if sellPrice - buyPrice < minDiff: + cancelPendingOrders() + return + + #确认上次的订单价格和现价差距,决定是否要调整买卖单 + if (lastBuyPrice > 0) and (abs(buyPrice - lastBuyPrice) > slidePrice): + cancelBuyOrder = True + if (lastSellPrice > 0) and (abs(lastSellPrice - sellPrice) > slidePrice): + cancelSellOrder = True + + #买单卖单均需调整,取消所有后调整 + if cancelBuyOrder & cancelSellOrder: + logger.debug('CANCEL ALL') + cancelPendingOrders() + placeOrder(buyPrice, minAmount + buyAmountAdjust, 'BUY') + placeOrder(sellPrice, minAmount + sellAmountAdjust, 'SELL') + return + + #按单数量分情况处理 + openingOrderCount = getOpeningOrderCount()['count'] + logger.debug('openingOrderCount %s', openingOrderCount) + #单数超过2不正常,退出 + if openingOrderCount > 2: + print('openingOrderCount:',openingOrderCount,'error') + logger.error('ERROR openingOrderCount: %s', str(openingOrderCount)) + sendBotMessage('ERROR openingOrderCount: ' + str(openingOrderCount)) + exit() + #单数为2,旧单都在,看需要更新买还是卖 + elif openingOrderCount == 2: + if cancelBuyOrder: + logger.debug('CANCEL BUY') + cancelPendingBuyOrders() + placeOrder(buyPrice, minAmount + buyAmountAdjust, 'BUY') + elif cancelSellOrder: + logger.debug('CANCEL SELL') + cancelPendingSellOrders() + placeOrder(sellPrice, minAmount + sellAmountAdjust, 'SELL') + else: + logger.debug('CANCEL NONE') + #单数为1,看具体生效的是买单还是卖单再更新 + elif openingOrderCount == 1: + #看是买单还是卖单 + orderList = getOpeningOrderList() + #更新的过程中有新单,跳过,重新check + if len(orderList) != 1: + logger.debug('openingOrderCount changed!! skip') + return + side = orderList[0]['side'] + logger.info('only 1 order remain: %s', side) + #现在有效的是买单 + if side == 'BUY': + #如果买单无效,那么更新买单 + if cancelBuyOrder: + cancelPendingBuyOrders() + placeOrder(buyPrice, minAmount + buyAmountAdjust, 'BUY') + #卖单无论如何都要更新 + placeOrder(sellPrice, minAmount + sellAmountAdjust, 'SELL') + #现在有效的是卖单 + elif side == 'SELL': + #如果卖单无效,那么更新卖单 + if cancelSellOrder: + cancelPendingSellOrders() + placeOrder(sellPrice, minAmount + sellAmountAdjust, 'SELL') + #买单无论如何都要更新 + placeOrder(buyPrice, minAmount + buyAmountAdjust, 'BUY') + else: + print('unexpected side, exit') + exit() + #单数为0,无论如何都需要补单 + elif openingOrderCount == 0: + placeOrder(buyPrice, minAmount + buyAmountAdjust, 'BUY') + placeOrder(sellPrice, minAmount + sellAmountAdjust, 'SELL') + ####做市下单模块结束#### + return + +###### TEST AREA +#exit() +###### INIT ###### +#SETUP LOGGER +logger = setLogger('merTradeLog') +#CANCEL ALL ORDER +cancelPendingOrders() +#GET ACCOUNT INFO +updateAccount() +accountInfo = getAccountInfo()[0] +initBalance = currentBalance +print('initBalance:', initBalance) +tradeList = getTradeList(1); +tickCount = 0 +startTime = time.time() +while True: + #Telegram控制模块 + message = getNewMessage() + if message == '!': + cancelPendingOrders() + updateAccount() + sendBotMessage('Balance: '+str(currentBalance)+"\nPosition: "+str(currentPosition['size'])+"@"+str(currentPosition['entryPrice'])+"\nLiquidatePrice: "+str(currentPosition['liquidatePrice']) +"\nProfit: " + str(currentBalance - initBalance)) + sendBotMessage('STOP STRATEGY') + exit() + elif message == '1': + updateAccount() + sendBotMessage('Balance: '+str(currentBalance)+"\nPosition: "+str(currentPosition['size'])+"@"+str(currentPosition['entryPrice'])+"\nLiquidatePrice: "+str(currentPosition['liquidatePrice']) +"\nProfit: " + str(currentBalance - initBalance)) + elif message == '2': + if totalBuyAmount != 0: + sendBotMessage('Buy position: ' + str(totalBuyAmount) + '@' + str(totalBuyPosition/totalBuyAmount)) + if totalSellAmount != 0: + sendBotMessage('Sell position: ' + str(totalSellAmount) + '@' + str(totalSellPosition/totalSellAmount)) + sendBotMessage('Buy/Sell Count: ' + str(totalBuyCount) +'/'+ str(totalSellCount)); + else: + pass + #策略逻辑 + onTick() + #检测账户信息 + if tickCount % 15 == 0: + updateAccount() + if tickCount > 0: + print ('Tick time: ', str((time.time() - startTime)/tickCount)) + #发送电报消息 + if tickCount % 100 == 0: + sendBotMessage('Balance: '+str(currentBalance)+"\nPosition: "+str(currentPosition['size'])+"@"+str(currentPosition['entryPrice'])+"\nLiquidatePrice: "+str(currentPosition['liquidatePrice']) +"\nProfit: " + str(currentBalance - initBalance)) + #检测交易信息 + if tickCount % 15 == 0: + lastTradeList = getTradeList(40) + for index in range(0,len(lastTradeList) - 1): + if tradeList[0]['id'] == lastTradeList[index]['id']: + break + if index == 0: + pass + else: + # 有新交易记录 + tradeList = lastTradeList[:index] + tradeList + for trade in lastTradeList[:index]: + logger.info('NEW TRADE: %s,%s,%s',trade['side'],trade['price'],trade['size']) + sendBotMessage('NEW TRADE - ' + str(trade['side']) + ' ' + str(trade['size']) + '@' + str(trade['price'])) + if trade['side'] == 'BUY': + totalBuyCount += 1 + totalBuyPosition += trade['price'] * trade['size'] + totalBuyAmount += trade['size'] + elif trade['side'] == 'SELL': + totalSellCount += 1 + totalSellPosition += trade['price'] * trade['size'] + totalSellAmount += trade['size'] + if totalBuyAmount != 0: + print ('Buy position at', totalBuyPosition/totalBuyAmount, ' | ',totalBuyAmount) + if totalSellAmount !=0: + print ('Sell position at', totalSellPosition/totalSellAmount, ' | ',totalSellAmount) + print ('Buy|Sell Count: ', totalBuyCount,'|',totalSellCount) + logger.info('Buy|Sell Count: %s|%s',totalBuyCount,totalSellCount); + tickCount += 1 + time.sleep(3) +``` + +> 策略出处 + +https://www.fmz.com/strategy/162413 + +> 更新时间 + +2019-08-16 15:53:47 diff --git "a/\345\235\207\347\272\277\347\255\226\347\225\245\350\214\203\344\276\21302.md" "b/\345\235\207\347\272\277\347\255\226\347\225\245\350\214\203\344\276\21302.md" new file mode 100644 index 00000000..0463189c --- /dev/null +++ "b/\345\235\207\347\272\277\347\255\226\347\225\245\350\214\203\344\276\21302.md" @@ -0,0 +1,32 @@ + +> 策略名称 + +均线策略范例02 + +> 策略作者 + +小小梦 + + + + + +> 源码 (麦语言) + +``` pascal +M5H^^MA(H,5); +M5L^^MA(L,5); +C>M5H,BPK; +C0,SP; +C>MA(C,5) AND SKVOL>0,BP; +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/156699 + +> 更新时间 + +2019-07-12 10:23:45 diff --git "a/\345\237\272\344\272\216\346\234\237\350\264\247\345\237\272\346\234\254\351\235\242\345\210\206\346\236\220\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/\345\237\272\344\272\216\346\234\237\350\264\247\345\237\272\346\234\254\351\235\242\345\210\206\346\236\220\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" new file mode 100644 index 00000000..5f5aa288 --- /dev/null +++ "b/\345\237\272\344\272\216\346\234\237\350\264\247\345\237\272\346\234\254\351\235\242\345\210\206\346\236\220\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -0,0 +1,256 @@ + +> 策略名称 + +基于期货基本面分析的交易策略 + +> 策略作者 + +Hukybo + + + + + +> 源码 (python) + +``` python +'''backtest +start: 2019-01-01 00:00:00 +end: 2019-08-09 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' + + +import requests +import re +from bs4 import BeautifulSoup +import time +import datetime +import random +import json +import threading + + +# 请求头文件 +request_headers = { + 'Connection': 'keep-alive', + 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3', + 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', + 'accept-encoding': 'gzip, deflate', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' +} + + +# ip代理 +proxies = { + 'http': 'http://182.35.82.128:9999', 'https': 'https://182.35.82.128:9999' +} + + +diff_data = 0 +reserve_data = 0 +receipt_data = 0 +profit_data = 0 + +# 日期转时间戳 +def to_timestamp(date_str): + times = date_str + " 00:00:00" + time_array = time.strptime(times, "%Y-%m-%d %H:%M:%S") + return int(round(time.mktime(time_array) * 1000)) + + +# 返回日期数组 +def date_arr(year, month, day): + begin = datetime.date(year, month, day) + end = datetime.date.today() + arr = [] + for i in range((end - begin).days + 1): + day = begin + datetime.timedelta(days=i) + arr.append([str(day).replace('-', ''), str(day), day.weekday() + 1, to_timestamp(str(day))]) + return arr + + +# 获取基差 +def spot_futures_diff_data(date, futures_name): + global diff_data + url = f"http://www.100ppi.com/sf2/day-{date}.html" + try: + url_text = requests.get(url, headers=request_headers).text # , proxies=proxies + except BaseException: + print('获取基差数据失败') + return int(diff_data) + soup = BeautifulSoup(url_text, "html5lib") + results = soup.select("#fdata")[0] + for i in results.find_all('tr'): + if len(i.find_all('td', text=futures_name)) > 0: + data = i.find_all('font')[0].text + if data is not None: + diff_data = data + return int(diff_data) + + +# 获取库存 +def spot_reserve_data(date, futures_name): + global reserve_data + url = f'http://www.shfe.com.cn/data/dailydata/{date}weeklystock.dat' + try: + url_text = requests.get(url, headers=request_headers).text + except BaseException: + print('获取库存数据失败') + return reserve_data + total = 0 + count = 0 + if url_text[0] == '{': + for i in json.loads(url_text)['o_cursor']: + if futures_name in i['VARNAME']: + if '合计' not in i['WHABBRNAME'] and '总计' not in i['WHABBRNAME']: + try: + inventory = int(i['WHSTOCKS']) + except BaseException: + return reserve_data + if inventory > 0: + total = total + inventory + count = count + 1 + if count > 0: + reserve_data = int(total / count) + return reserve_data + + +# 获取仓单 +def spot_receipt_data(date, futures_name): + global receipt_data + url = f'http://www.shfe.com.cn/data/dailydata/{date}dailystock.dat' + try: + url_text = requests.get(url, headers=request_headers).text + except BaseException: + print('获取库存数据失败') + return receipt_data + total = 0 + count = 0 + if url_text[0] == '{': + for i in json.loads(url_text)['o_cursor']: + if futures_name in i['VARNAME']: + if '合计' not in i['WHABBRNAME'] and '总计' not in i['WHABBRNAME']: + try: + inventory = int(i['WRTWGHTS']) + except BaseException: + return receipt_data + if inventory > 0: + total = total + inventory + count = count + 1 + if count > 0: + receipt_data = int(total / count) + return receipt_data + + +# 虚拟利润 +def get_profit_data(): + global profit_data + profit_data = profit_data + random.randint(-100, 150) + return profit_data + + +def main(): + # threading.Thread(target=spot_futures_diff_arr, args=('天然橡胶',)).start() + # threading.Thread(target=commodity_inventory_arr, args=('天然橡胶',)).start() + # threading.Thread(target=commodity_warehouse_receipt_arr, args=('天然橡胶',)).start() + + cfgA = { + "extension": { + "layout": 'single', + "col": 6, + "height": "500px", + }, + "title" : { + "text" : "基差图表" + }, + "xAxis" : { + "type" : "datetime" + }, + "series" : [{ + "name" : "基差", + "data" : [], + }] + } + cfgB = { + "extension": { + "layout": 'single', + "col": 6, + "height": "500px", + }, + "title" : { + "text" : "库存图表" + }, + "xAxis" : { + "type" : "datetime" + }, + "series" : [{ + "name" : "库存", + "data" : [], + }] + } + cfgC = { + "extension": { + "layout": 'single', + "col": 6, + "height": "500px", + }, + "title" : { + "text" : "仓单图表" + }, + "xAxis" : { + "type" : "datetime" + }, + "series" : [{ + "name" : "仓单", + "data" : [], + }] + } + cfgD = { + "extension": { + "layout": 'single', + "col": 6, + "height": "500px", + }, + "title" : { + "text" : "利润图表" + }, + "xAxis" : { + "type" : "datetime" + }, + "series" : [{ + "name" : "利润", + "data" : [], + }] + } + LogReset() + chart = Chart([cfgA, cfgB, cfgC, cfgD]) + chart.reset() + for i in date_arr(2018, 1, 1): + diff = spot_futures_diff_data(i[1], '天然橡胶') + reserve = spot_reserve_data(i[0], '天然橡胶') + receipt = spot_receipt_data(i[0], '天然橡胶') + profit = get_profit_data() + if diff != 0 and reserve != 0 and receipt != 0: + chart.add(0, [i[3], diff]) + chart.add(1, [i[3], reserve]) + chart.add(2, [i[3], receipt]) + chart.add(3, [i[3], profit]) + chart.update([cfgA, cfgB, cfgC, cfgD]) + time.sleep(1) + + Log(f'基差:{diff} 库存:{reserve} 仓单:{receipt} 日期:{i[1]}') + + + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/161412 + +> 更新时间 + +2019-08-17 11:40:22 diff --git "a/\345\237\272\344\272\216\347\256\261\344\275\223\347\220\206\350\256\272\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245\357\274\214\346\224\257\346\214\201\345\225\206\345\223\201\346\234\237\350\264\247\345\222\214\346\225\260\345\255\227\350\264\247\345\270\201.md" "b/\345\237\272\344\272\216\347\256\261\344\275\223\347\220\206\350\256\272\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245\357\274\214\346\224\257\346\214\201\345\225\206\345\223\201\346\234\237\350\264\247\345\222\214\346\225\260\345\255\227\350\264\247\345\270\201.md" new file mode 100644 index 00000000..5aa9b62f --- /dev/null +++ "b/\345\237\272\344\272\216\347\256\261\344\275\223\347\220\206\350\256\272\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245\357\274\214\346\224\257\346\214\201\345\225\206\345\223\201\346\234\237\350\264\247\345\222\214\346\225\260\345\255\227\350\264\247\345\270\201.md" @@ -0,0 +1,54 @@ + +> 策略名称 + +基于箱体理论的交易策略,支持商品期货和数字货币 + +> 策略作者 + +Hukybo + +> 策略描述 + +**策略简介** +所谓的箱体,也可以称为一种形态,它的理论根基借鉴了支撑线和阻力线。通常情况下,当价格上涨到前期高点时,会遇到卖压使价格回落,当价格下跌到前期低点时,会遇到买压使价格上升。如果价格多次这样来来回回上下运动,就可以根据一段时间的历史价格的高点与低点,形成一个箱体(Box theory)。 + +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4068) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|N|25|N| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2015-02-22 00:00:00 +end: 2019-07-20 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["SlideTick",0,126961],["ContractType","i888",126961]] +*) + +PRICE:=(OPEN+HIGH+LOW+CLOSE*2)/5; +UPPERBAND^^REF(HHV(PRICE,N),1); +LOWERBAND^^REF(LLV(PRICE,N),1); +C>=UPPERBAND,BPK; +C<=LOWERBAND,SPK; +MID^^(UPPERBAND+LOWERBAND)/2; +CMID||C>HHV(PRICE,N/2),BP; +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/158088 + +> 更新时间 + +2019-07-20 16:26:14 diff --git "a/\345\244\232\347\272\277\347\250\213\346\211\271\351\207\217\344\273\273\345\212\241.md" "b/\345\244\232\347\272\277\347\250\213\346\211\271\351\207\217\344\273\273\345\212\241.md" new file mode 100644 index 00000000..0bcdf72f --- /dev/null +++ "b/\345\244\232\347\272\277\347\250\213\346\211\271\351\207\217\344\273\273\345\212\241.md" @@ -0,0 +1,114 @@ + +> 策略名称 + +多线程批量任务 + +> 策略作者 + +jason47 + +> 策略描述 + +``` + var tasks = $.go([ + [exchange, 'GetDepth'], + [exchange, 'GetTicker'], + ]) + var retList = $.wait(tasks) + Log(retList[0]) + Log(retList[1]) +``` + +- **$.go()** +> 批量执行Go +> 参数类型 二维数组 +``` + [ + [exchange, 'GetDepth'], + [exchange, 'GetTicker'], + ] +``` +> 返回值 cmdList 数组 + +- **$.wait(cmdList)** +> 获取结果 + +- **$.gowait()** +> 执行Go并且获取结果 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|RETRY_INTERVAL|true|重试间隔(秒)| + + +> 源码 (javascript) + +``` javascript +$.go = function(tasks) { + return _.map(tasks, function(args) { + return { + result: null, + args: args, + defer: args[0].Go.apply(args[0], args.slice(1)) + } + }) +} + +$.gowait = function(tasks, maxConcurrent, retry) { + return $.wait($.go(tasks), maxConcurrent, retry) +} + +$.wait = function(cmdList, maxConcurrent, retry) { + retry = retry || true + maxConcurrent = Math.min(cmdList.length, maxConcurrent || 5) + var total = Math.ceil(cmdList.length / maxConcurrent) + return _.reduce(_.range(total), function(beforeResultList, currentPage) { + var lastCmdList = cmdList.slice(currentPage * maxConcurrent, currentPage * maxConcurrent + maxConcurrent) + while (1) { + lastCmdList = _.map(lastCmdList, function(cmd) { + var args = cmd.args + if (cmd.result == null) { + var ret = cmd.defer.wait() + if (ret != null) { + return _.extend(cmd, { + result: ret + }) + } else if (retry === true) { + return _.extend(cmd, { + defer: args[0].Go.apply(args[0], args.slice(1)), + result: null + }) + } + } + return cmd + }) + var isFinished = _.every(lastCmdList, function(cmd) { + return cmd.result + }) + if (isFinished) { + break + } + Sleep(RETRY_INTERVAL * 1000) + } + var newResultList = lastCmdList.map(function(cmd) { + return cmd.result + }) + if (currentPage + 1 < total) { + Sleep(500) + } + return beforeResultList.concat(newResultList) + }, []) +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/159978 + +> 更新时间 + +2019-08-24 04:51:11 diff --git "a/\346\227\266\351\227\264\346\240\274\345\274\217\345\267\245\345\205\267.md" "b/\346\227\266\351\227\264\346\240\274\345\274\217\345\267\245\345\205\267.md" new file mode 100644 index 00000000..770e6939 --- /dev/null +++ "b/\346\227\266\351\227\264\346\240\274\345\274\217\345\267\245\345\205\267.md" @@ -0,0 +1,164 @@ + +> 策略名称 + +时间格式工具 + +> 策略作者 + +huangsibo + + + + + +> 源码 (javascript) + +``` javascript +/* + * @Author: sibohuang + * @Date: 2019-08-10 09:36:03 + * @LastEditors: sibohuang + * @LastEditTime: 2019-08-10 09:45:11 + * @Description: + * @Email: 3570411064@qq.com + * @Company: igola + */ + +/** + * 将日期格式化成指定格式的字符串 + * @param date 要格式化的日期,不传时默认当前时间,也可以是一个时间戳 + * @param fmt 目标字符串格式,支持的字符有:y,M,d,q,w,H,h,m,S,默认:yyyy-MM-dd HH:mm:ss + * @returns 返回格式化后的日期字符串 + */ +$.formatDate = function (date, fmt) { + date = !date ? new Date() : date; + date = typeof date === 'number' ? new Date(date) : date; + fmt = fmt || 'yyyy-MM-dd HH:mm:ss'; + var obj = + { + 'y': date.getFullYear(), // 年份,注意必须用getFullYear + 'M': date.getMonth() + 1, // 月份,注意是从0-11 + 'd': date.getDate(), // 日期 + 'q': Math.floor((date.getMonth() + 3) / 3), // 季度 + 'w': date.getDay(), // 星期,注意是0-6 + 'H': date.getHours(), // 24小时制 + 'h': date.getHours() % 12 == 0 ? 12 : date.getHours() % 12, // 12小时制 + 'm': date.getMinutes(), // 分钟 + 's': date.getSeconds(), // 秒 + 'S': date.getMilliseconds() // 毫秒 + }; + var week = ['天', '一', '二', '三', '四', '五', '六']; + for (var i in obj) { + fmt = fmt.replace(new RegExp(i + '+', 'g'), function (m) { + var val = obj[i] + ''; + if (i == 'w') return (m.length > 2 ? '星期' : '周') + week[val]; + for (var j = 0, len = val.length; j < m.length - len; j++) val = '0' + val; + return m.length == 1 ? val : val.substring(val.length - m.length); + }); + } + return fmt; +} +/** + * 将字符串解析成日期 + * @param str 输入的日期字符串,如'2014-09-13' + * @param fmt 字符串格式,默认'yyyy-MM-dd',支持如下:y、M、d、H、m、s、S,不支持w和q + * @returns 解析后的Date类型日期 + */ + +$.parseDate = function(str, fmt) { + fmt = fmt || 'yyyy-MM-dd'; + var obj = {y: 0, M: 1, d: 0, H: 0, h: 0, m: 0, s: 0, S: 0}; + fmt.replace(/([^yMdHmsS]*?)(([yMdHmsS])\3*)([^yMdHmsS]*?)/g, function (m, $1, $2, $3, $4, idx, old) { + str = str.replace(new RegExp($1 + '(\\d{' + $2.length + '})' + $4), function (_m, _$1) { + obj[$3] = parseInt(_$1); + return ''; + }); + return ''; + }); + obj.M--; // 月份是从0开始的,所以要减去1 + var date = new Date(obj.y, obj.M, obj.d, obj.H, obj.m, obj.s); + if (obj.S !== 0) date.setMilliseconds(obj.S); // 如果设置了毫秒 + return date; +} +/** + * 将一个日期格式化成友好格式,比如,1分钟以内的返回“刚刚”, + * 当天的返回时分,当年的返回月日,否则,返回年月日 + * @param {Object} date + */ +$.formatDateToFriendly = function(date) { + date = date || new Date(); + date = typeof date === 'number' ? new Date(date) : date; + invariant(date instanceof Date, 'date is not date type'); + var now = new Date(); + if ((now.getTime() - date.getTime()) < 60 * 1000) return '刚刚'; // 1分钟以内视作“刚刚” + var temp = this.formatDate(date, 'yyyy年M月d'); + if (temp == this.formatDate(now, 'yyyy年M月d')) return this.formatDate(date, 'HH:mm'); + if (date.getFullYear() == now.getFullYear()) return this.formatDate(date, 'M月d日'); + return temp; +} + +/** + * 将一段时长转换成友好格式,如: + * 147->“2分27秒” + * 1581->“26分21秒” + * 15818->“4小时24分” + * @param {Object} second + */ + +$.formatDurationToFriendly = function(second) { + if (second < 60) return second + '秒'; + else if (second < 60 * 60) return (second - second % 60) / 60 + '分' + second % 60 + '秒'; + else if (second < 60 * 60 * 24) return (second - second % 3600) / 60 / 60 + '小时' + Math.round(second % 3600 / 60) + '分'; + return (second / 60 / 60 / 24).toFixed(1) + '天'; +} +/** + * 将时间转换成MM:SS形式 + */ + +$.formatTimeToFriendly = function(second) { + var m = Math.floor(second / 60); + m = m < 10 ? ( '0' + m ) : m; + var s = second % 60; + s = s < 10 ? ( '0' + s ) : s; + return m + ':' + s; +} +/** + * 计算2日期之间的天数,用的是比较毫秒数的方法 + * 传进来的日期要么是Date类型,要么是yyyy-MM-dd格式的字符串日期 + * @param date1 日期一 + * @param date2 日期二 + */ +$.countDays = function(date1, date2) { + var fmt = 'yyyy-MM-dd'; + // 将日期转换成字符串,转换的目的是去除“时、分、秒” + if (date1 instanceof Date && date2 instanceof Date) { + date1 = this.formatDate(date1, fmt); + date2 = this.formatDate(date2, fmt); + } + if (typeof date1 === 'string' && typeof date2 === 'string') { + date1 = this.parseDate(date1, fmt); + date2 = this.parseDate(date2, fmt); + return (date1.getTime() - date2.getTime()) / (1000 * 60 * 60 * 24); + } + else { + console.error('参数格式无效!'); + return 0; + } +} +function main() { + Log($.formatDate(new Date())) + // Log($.parseDate(new Date())) + // Log($.formatDateToFriendly(new Date())) + // Log($.formatTimeToFriendly(new Date())) + // Log($.formatDurationToFriendly(new Date())) + // Log($.countDays(new Date())) +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/161505 + +> 更新时间 + +2019-08-10 09:45:12 diff --git "a/\346\234\237\350\264\247\347\234\213\347\251\277\345\274\217\346\265\213\350\257\225.md" "b/\346\234\237\350\264\247\347\234\213\347\251\277\345\274\217\346\265\213\350\257\225.md" new file mode 100644 index 00000000..a4c5a9d6 --- /dev/null +++ "b/\346\234\237\350\264\247\347\234\213\347\251\277\345\274\217\346\265\213\350\257\225.md" @@ -0,0 +1,76 @@ + +> 策略名称 + +期货看穿式测试 + +> 策略作者 + +Hukybo + + + + + +> 源码 (javascript) + +``` javascript +num = 0 + +function onTick() { + if (num < 1) { + _C(exchange.SetContractType, "rb1910") + account = _C(exchange.GetAccount).Info.AccountID + Log("账号:", account); + Log("AppID:", "client_fmz_1.0"); + records = _C(exchange.GetRecords) + k = records[records.length - 1].Close + exchange.SetDirection("buy"); + id = exchange.Buy(k + 2, 1) + Log("sessionid:", id); + Log("登陆时间:", Date()); + + Log("账号:", account); + records = _C(exchange.GetRecords) + k = records[records.length - 1].Close + for (x = 0; x < 5; x++) { + exchange.SetDirection("buy"); + id = exchange.Buy(k + 2, 1) + Log("sessionid:", id); + Sleep(1000) + } + + Log("账号:", account); + for (y = 0; y < 5; y++) { + exchange.SetDirection("buy"); + id = exchange.Buy(k - 2, 1) + Log("sessionid:", id); + Sleep(1000) + } + orders = _C(exchange.GetOrders) + for (z = 0; z < 5; z++) { + Log("账号:", account); + Log("合约:", "rb1910"); + var ordersid = orders[z].Id + if (exchange.CancelOrder(ordersid)) { + Log("订单:" + ordersid + " 已撤单") + } + } + num++ + } +} + +function main() { + while (true) { + onTick(); + Sleep(1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/152670 + +> 更新时间 + +2019-07-29 10:30:46 diff --git "a/\346\265\213\350\257\225\345\233\276\350\241\250.md" "b/\346\265\213\350\257\225\345\233\276\350\241\250.md" new file mode 100644 index 00000000..ef9d86e1 --- /dev/null +++ "b/\346\265\213\350\257\225\345\233\276\350\241\250.md" @@ -0,0 +1,183 @@ + +> 策略名称 + +测试图表 + +> 策略作者 + +Hukybo + + + + + +> 源码 (python) + +``` python +'''backtest +start: 2019-01-01 00:00:00 +end: 2019-08-09 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' + + +import requests +import re +from bs4 import BeautifulSoup +import time +import datetime +import random +import json +import threading + + +# 请求头文件 +request_headers = { + 'Connection': 'keep-alive', + 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3', + 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', + 'accept-encoding': 'gzip, deflate', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' +} + + +# ip代理 +proxies = { + 'http': 'http://182.35.82.128:9999', 'https': 'https://182.35.82.128:9999' +} + + +diff_old_data = 0 + + +# 日期转时间戳 +def to_timestamp(date_str): + times = date_str + " 00:00:00" + time_array = time.strptime(times, "%Y-%m-%d %H:%M:%S") + return int(round(time.mktime(time_array))) + + +# 返回日期数组 +def date_arr(year, month, day): + begin = datetime.date(year, month, day) + end = datetime.date.today() + arr = [] + for i in range((end - begin).days + 1): + day = begin + datetime.timedelta(days=i) + arr.append([str(day).replace('-', ''), str(day), day.weekday() + 1, to_timestamp(str(day))]) + return arr + + +def spot_futures_diff_data(date, futures_name): + global diff_old_data + url = f"http://www.100ppi.com/sf2/day-{date}.html" + try: + url_text = requests.get(url, headers=request_headers).text # , proxies=proxies + except BaseException: + print('由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。') + return int(diff_old_data) + soup = BeautifulSoup(url_text, "html5lib") + results = soup.select("#fdata")[0] + for i in results.find_all('tr'): + if len(i.find_all('td', text=futures_name)) > 0: + data = i.find_all('font')[0].text + if data is not None: + diff_old_data = data + return int(data) + return int(diff_old_data) + + +def main(): + # threading.Thread(target=spot_futures_diff_arr, args=('天然橡胶',)).start() + # threading.Thread(target=commodity_inventory_arr, args=('天然橡胶',)).start() + # threading.Thread(target=commodity_warehouse_receipt_arr, args=('天然橡胶',)).start() + + cfgA = { + "extension": { + "layout": 'single', + "col": 6, + "height": "500px", + }, + "title" : { + "text" : "基差图表" + }, + "xAxis" : { + "type" : "datetime" + }, + "series" : [{ + "name" : "基差", + "data" : [], + }] + } + cfgB = { + "extension": { + "layout": 'single', + "col": 6, + "height": "500px", + }, + "title" : { + "text" : "库存图表" + }, + "xAxis" : { + "type" : "datetime" + }, + "series" : [{ + "name" : "库存", + "data" : [], + }] + } + cfgC = { + "extension": { + "layout": 'single', + "col": 6, + "height": "500px", + }, + "title" : { + "text" : "仓单图表" + }, + "xAxis" : { + "type" : "datetime" + }, + "series" : [{ + "name" : "仓单", + "data" : [], + }] + } + cfgD = { + "extension": { + "layout": 'single', + "col": 6, + "height": "500px", + }, + "title" : { + "text" : "利润图表" + }, + "xAxis" : { + "type" : "datetime" + }, + "series" : [{ + "name" : "利润", + "data" : [], + }] + } + chart = Chart([cfgA, cfgB, cfgC, cfgD]) + for i in date_arr(2018, 1, 1): + diff = spot_futures_diff_data(i[1], '天然橡胶') + chart.add(0, [i[3], diff]) + chart.add(1, [i[3], diff]) + chart.add(2, [i[3], diff]) + chart.add(3, [i[3], diff]) + Log('时间戳', i[3], type(i[3])) + Log('数据', diff, type(diff)) + #chart.update([cfgA, cfgB, cfgC, cfgD]) + time.sleep(1) +``` + +> 策略出处 + +https://www.fmz.com/strategy/162093 + +> 更新时间 + +2019-08-15 16:55:35 diff --git "a/\347\201\253\345\270\201\347\202\271\345\215\241.md" "b/\347\201\253\345\270\201\347\202\271\345\215\241.md" new file mode 100644 index 00000000..b43d04b6 --- /dev/null +++ "b/\347\201\253\345\270\201\347\202\271\345\215\241.md" @@ -0,0 +1,49 @@ + +> 策略名称 + +火币点卡 + +> 策略作者 + +jason47 + +> 策略描述 + +- getHBPoints(exchange) +> 获取火币点卡 +> 返回值,number类型 + + + +> 源码 (javascript) + +``` javascript +$.getHBPoints = function(ex) { + try { + var accountRet = ex.IO("api", "GET", "/v1/account/accounts") + if (accountRet && accountRet.data) { + var account = _.findWhere(accountRet.data, { + type: 'point' + }) + if (account && account.id) { + var balanceRet = ex.IO("api", "GET", "/v1/account/accounts/" + account.id + "/balance") + if (balanceRet && balanceRet.data && balanceRet.data.list) { + var balance = _.reduce(balanceRet.data.list, function(p, n) { + return new Decimal(p).plus(n.balance).toNumber() + }, 0) + return balance + } + } + } + } catch (e) {} + return null +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/162055 + +> 更新时间 + +2019-08-13 22:05:07 diff --git "a/\347\201\253\345\270\201\347\262\276\345\272\246.md" "b/\347\201\253\345\270\201\347\262\276\345\272\246.md" new file mode 100644 index 00000000..3391b096 --- /dev/null +++ "b/\347\201\253\345\270\201\347\262\276\345\272\246.md" @@ -0,0 +1,160 @@ + +> 策略名称 + +火币精度 + +> 策略作者 + +jason47 + +> 策略描述 + +- **$.getAmountPrecision(Currency)** +> 交易对基础币种计数精度(小数点后位数) +> 返回值 number类型 + +- **$.getPricePrecision(Currency)** +> 交易对报价的精度(小数点后位数) +> 返回值 number类型 + +- **$.getMinOrderAmount(Currency)** +> 交易对最小下单量 +> 返回值 number类型 + +- **$.getMaxOrderAmount(Currency)** +> 交易对最大下单量 +> 返回值 number类型 + +- **$.getValuePrecision(Currency)** +> 交易对交易金额的精度(小数点后位数) +> 返回值 number类型 + +- **$.getMinValue(Currency)** +> 最小下单金额 (下单金额指当订单类型为限价单时,下单接口传入的(amount * price)。当订单类型为buy-market时,下单接口传的'amount') +> 返回值 number类型 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|TICKER_EXPIRE_TIME|600|行情缓存时间(秒)| + + +> 源码 (javascript) + +``` javascript +var _symbols = _C(getSymbols) +var _cacheTicker = {} + +function parseJson(str) { + try { + return JSON.parse(str) + } catch(e) { + Log(str + e.message + '#FF0000') + return null + } +} + +function getSymbols() { + var ret = parseJson(HttpQuery('https://api.huobi.pro/v1/common/symbols')) + if (ret && ret.status === 'ok') { + return ret.data + } else { + return null + } +} + +function getTicker(ex) { + var currency = getCurreny(ex) + if (_cacheTicker[currency] && Unix() - _cacheTicker[currency].UpdatedAt < TICKER_EXPIRE_TIME) { + return _cacheTicker[currency] + } + var sym = currency.replace('_', '').toLocaleLowerCase() + var ret = parseJson(HttpQuery('https://api.huobi.pro/market/detail/merged?symbol=' + sym)) + if (ret && ret.status === 'ok') { + _cacheTicker[currency] = _.extend({ UpdatedAt: Unix() }, ret.tick) + return ret.data + } else { + return null + } +} + +function getCurreny(ex) { + var currency = null + if (typeof(ex) === 'object') { + return ex.GetCurrency() + } else { + return ex + } +} + +function getCoin(ex) { + var currency = getCurreny(ex) + var currencyAry = _.map(currency.split('_'), function(sym) { return sym.toLocaleLowerCase() }) + return _.find(_symbols, function(coin) { + return currencyAry[0] === coin['base-currency'] && currencyAry[1] === coin['quote-currency'] + }) +} + +$.getSymbols = getSymbols + +$.getAmountPrecision = function (ex) { + var coin = getCoin(ex) + if (coin) { + return coin['amount-precision'] + } + return 0 +} + +$.getPricePrecision = function(ex) { + var coin = getCoin(ex) + if (coin) { + return coin['price-precision'] + } + return 0 +} + +$.getMinOrderAmount = function(ex, price) { + var coin = getCoin(ex) + if (coin) { + price = price || _C(getTicker, ex).close + return +(new Decimal(coin['min-order-value']).mul(1.1).div(price).toFixed($.getAmountPrecision(ex), Decimal.ROUND_CEIL)) + } + return 0 +} + +$.getMaxOrderAmount = function(ex) { + var coin = getCoin(ex) + if (coin) { + return coin['max-order-amt'] + } + return 0 +} + +$.getValuePrecision = function(ex) { + var coin = getCoin(ex) + if (coin) { + return coin['value-precision'] + } + return 0 +} + +$.getMinValue = function(ex) { + var coin = getCoin(ex) + if (coin) { + return coin['min-order-value'] + } + return 0 +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/159104 + +> 更新时间 + +2019-07-31 18:15:19 diff --git "a/\347\216\260\347\216\260\345\257\271\345\206\262(\345\244\232\344\272\244\346\230\223\346\211\200\346\220\254\347\240\226).md" "b/\347\216\260\347\216\260\345\257\271\345\206\262(\345\244\232\344\272\244\346\230\223\346\211\200\346\220\254\347\240\226).md" new file mode 100644 index 00000000..e4c83850 --- /dev/null +++ "b/\347\216\260\347\216\260\345\257\271\345\206\262(\345\244\232\344\272\244\346\230\223\346\211\200\346\220\254\347\240\226).md" @@ -0,0 +1,400 @@ + +> 策略名称 + +现现对冲(多交易所搬砖) + +> 策略作者 + +vipjohn + +> 策略描述 + +策略功能: +实现跨交易所的现现对冲 +支持无限个交易所同时搬砖 +支持任意交易对搬砖 +详细报表支持(完整的状态信息, 可实时看到策略观察到的各个交易所的差价信息, 持仓信息,资金净值,策略运行状况) +24小时无人值守, 全自动运行 + +策略参数设置: +请访问 https://www.pcclean.io/9wbl + + + +> 源码 (javascript) + +``` javascript +/* +现现对冲(搬砖) + +注意: +1.确保设置了交易所的手续费和最小买入量 + +版本历史: +21:33 2018/10/25 处理挂单不成交的情况,不再使用市价单 +7:28 2018/10/26 支持永久记录收益 +8:00 2018/10/27 支持显示币数变化,搬砖函数每次更新getaccount +10:14 2018/10/27 修复不显示profit chart的问题 +*/ + +//搬砖参数设置 +var handfee= {FCoin:0.0 , CoinEx:0.0004,Huobi:0.002,OKEX:0.002,Binance:0.001,ZB:0.002 };//手续费 +var minestbuy={FCoin:0.01, CoinEx:0.01, Huobi:0.01, OKEX:0.01, Binance:0.04, ZB:0.01 }; //最小买入量 +var want_profit=0.0001;//期望收益 +var price_step=0.00001;//定价单调整价格的单位 +var maxbuy=5; //最大买入 +var warning_stocks=10;//余额预警 +var price_n=6; //价格精度 +var num_n=3; //数量精度 +var max_wait_order=15000;//订单等待时间 +var buypercent=1.0; //买入百分比 +var wait_ms=3000;//重试等待间隔时间 +var enable_traders_recorder=true;//记录所有交易 + + +//全局变量 +var limit_orders=[];//限价单 +var total_banzhuan=0;//搬砖次数 +var total_op=0;//总搬砖机会 +var exchange_banzhuan={};//记录交易所搬砖次数 +var total_passed=0;//因为余额不足错过了多少次搬砖机会 +var trades=[];//所有交易 +var approximate_profit=0;//盈亏近似值 +var dealamount_change=0;//币数变化 + +function get_exchange_banzhuan(exname){ + var name = exname.replace(" ", "_"); + if (isNaN(exchange_banzhuan[name])){ + return 0; + }else{ + return exchange_banzhuan[name]; + } +} +function put_exchange_banzhuan(exname,value){ + var name = exname.replace(" ", "_"); + exchange_banzhuan[name]=value; +} + +//在交易所ex1和ex2之间搬砖 +function banzhuan(exchange1,exchange2) +{ + //read price from exchange 1 + var account1=_C(exchange1.GetAccount); + var exname1=exchange1.GetName(); + var depth1 = _C(exchange1.GetDepth); + var askprice1=depth1.Asks[0].Price; + var askamount1=depth1.Asks[0].Amount; + + //read price from exchange 2 + var account2=_C(exchange2.GetAccount); + var exname2=exchange2.GetName(); + var depth2 = _C(exchange2.GetDepth); + var bidprice2=depth2.Bids[0].Price; + var bidamount2=depth2.Bids[0].Amount; + + var threshold=handfee[exname1]+handfee[exname2]+want_profit; //交易阀值 + var minbuy=Math.max(minestbuy[exname1],minestbuy[exname2]); //最小购买数量 + + //buy and sell if its prifitable + var diff=(bidprice2-askprice1)/askprice1; + var canbuy=Math.min(askamount1,bidamount2); + canbuy=canbuy*buypercent; + var min=Math.min(canbuy,maxbuy); //the minimum number for buy/sell + + if (Math.abs(diff)>=threshold && min>=minbuy) //for bch + { + if (diff>0)//exchange 1 is cheap + { + total_op=total_op+2; + put_exchange_banzhuan(exname1+"_op",get_exchange_banzhuan(exname1+"_op")+1); + put_exchange_banzhuan(exname2+"_op",get_exchange_banzhuan(exname2+"_op")+1); + put_exchange_banzhuan(exname1+"_canbuy",get_exchange_banzhuan(exname1+"_canbuy")+min); + put_exchange_banzhuan(exname2+"_cansell",get_exchange_banzhuan(exname2+"_cansell")+min); + + var needmoney=min*askprice1; + if (account2.Stocks>min && account1.Balance>needmoney ){ + + //buy from exchange 1 + var price_1=askprice1; + var buyID=retryBuy(exchange1,price_1,min); + //sell from exchange 2 + var price_2=bidprice2; + var sellID=retrySell(exchange2,price_2,min); + + //add orders to pre-processing list + var order1={ + exchange:exchange1, + ID:buyID, + create_time:new Date(), + utcdate:get_ChinaTimeString() + }; + limit_orders.push(order1); + var order2={ + exchange:exchange2, + ID:sellID, + create_time:new Date(), + utcdate:get_ChinaTimeString() + }; + limit_orders.push(order2); + + total_banzhuan=total_banzhuan+2; + put_exchange_banzhuan(exname1,get_exchange_banzhuan(exname1)+1); + put_exchange_banzhuan(exname2,get_exchange_banzhuan(exname2)+1); + }else{ + if (account2.Stocks<=min){ + Log(exchange2.GetName()+"没币了,无法搬砖。请及时充值。"+"#ff0000"); + } + if (account1.Balance<=needmoney){ + Log(exchange1.GetName()+"没钱了,无法搬砖。请及时充值。"+"#ff0000"); + } + total_passed=total_passed+2; + } + } + } +} + + +//检查订单是否执行成功,如果未完成,执行市价下单 +function process_limiteorders(){ + var cur_time=new Date(); + var limit_orders_new=[]; + for (var i=0; imax_wait_order){ + var exchange_c=limit_orders[i].exchange; + var order_ID=limit_orders[i].ID; + var exname=exchange_c.GetName(); + var account=_C(exchange_c.GetAccount); + var ticker=_C(exchange_c.GetTicker); + var last=ticker.Last; + var orderdata=_C(exchange_c.GetOrder,order_ID); + var type=orderdata.Type; + + if (orderdata.Status!=ORDER_STATE_CLOSED){ + var notcompleted=orderdata.Amount-orderdata.DealAmount; + exchange_c.CancelOrder(order_ID); + if (type===ORDER_TYPE_BUY){ + var allowbuy=Math.min(account.Balance/last,notcompleted); + if (allowbuy>minestbuy[exname]){ + var limited_order_ID=retryBuy(exchange_c,orderdata.Price+price_step,allowbuy); + Log("加价买入。"+orderdata.Price+"|"+(orderdata.Price+price_step)); + var limited_order_data={ + exchange:exchange_c, + ID:limited_order_ID, + create_time:new Date(), + utcdate:get_ChinaTimeString() + }; + limit_orders_new.push(limited_order_data); + } + approximate_profit-=(orderdata.Price*orderdata.DealAmount*(1+handfee[exname])); + dealamount_change+=(orderdata.DealAmount); + }else if (type===ORDER_TYPE_SELL){ + var allowsell=Math.min(account.Stocks,notcompleted); + if (allowsell>minestbuy[exname]){ + var limited_order_ID=retrySell(exchange_c,orderdata.Price-price_step,allowsell); + Log("降价卖出。"+orderdata.Price+"|"+(orderdata.Price-price_step)); + var limited_order_data={ + exchange:exchange_c, + ID:limited_order_ID, + create_time:new Date(), + utcdate:get_ChinaTimeString() + }; + limit_orders_new.push(limited_order_data); + } + approximate_profit+=(orderdata.Price*orderdata.DealAmount*(1-handfee[exname])); + dealamount_change-=(orderdata.DealAmount); + } + + //保存交易信息 + if (type===ORDER_TYPE_BUY){ + var details={ + type:"限价买", + time:limit_orders[i].utcdate, + RealAmount:orderdata.DealAmount, + WantAmount:orderdata.Amount, + RealPrice:orderdata.Price, + WantPrice:orderdata.Price, + Memo:"部分完成", + exname:exname + }; + if (enable_traders_recorder){ + trades.push(details); + } + }else if (type===ORDER_TYPE_SELL){ + var details={ + type:"限价卖", + time:limit_orders[i].utcdate, + RealAmount:orderdata.DealAmount, + WantAmount:orderdata.Amount, + RealPrice:orderdata.Price, + WantPrice:orderdata.Price, + Memo:"部分完成", + exname:exname + }; + if (enable_traders_recorder){ + trades.push(details); + } + } + }else{ + //保存交易信息 + if (type===ORDER_TYPE_BUY){ + approximate_profit-=(orderdata.Price*orderdata.DealAmount*(1+handfee[exname])); + dealamount_change+=(orderdata.DealAmount); + var details={ + type:"限价买", + time:limit_orders[i].utcdate, + RealAmount:orderdata.DealAmount, + WantAmount:orderdata.Amount, + RealPrice:orderdata.Price, + WantPrice:orderdata.Price, + Memo:"已完成", + exname:exname + }; + if (enable_traders_recorder){ + trades.push(details); + } + }else if (type===ORDER_TYPE_SELL){ + approximate_profit+=(orderdata.Price*orderdata.DealAmount*(1-handfee[exname])); + dealamount_change-=(orderdata.DealAmount); + var details={ + type:"限价卖", + time:limit_orders[i].utcdate, + RealAmount:orderdata.DealAmount, + WantAmount:orderdata.Amount, + RealPrice:orderdata.Price, + WantPrice:orderdata.Price, + Memo:"已完成", + exname:exname + }; + if (enable_traders_recorder){ + trades.push(details); + } + } + } + }else{ + limit_orders_new.push(limit_orders[i]); + } + } + limit_orders=limit_orders_new; +} + +//重试购买,直到成功返回 +function retryBuy(ex,price,num) +{ + var r=ex.Buy(_N(price,price_n), _N(num,num_n)); + while (!r){ + Log("Buy失败,正在retry。"); + Sleep(wait_ms); + r=ex.Buy(_N(price,price_n), _N(num,num_n)); + } + return r; +} + +//重试卖出,直到成功返回 +function retrySell(ex,price,num) +{ + var r=ex.Sell(_N(price,price_n), _N(num,num_n)); + while (!r){ + Log("Sell失败,正在retry。"); + Sleep(wait_ms); + r=ex.Sell(_N(price,price_n), _N(num,num_n)); + } + return r; +} + +//get utc+8 date string +function get_ChinaTimeString() +{ + var date = new Date(); + var now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); + var cdate=new Date(now_utc); + cdate.setHours(cdate.getHours()+8); + var localstring=cdate.getFullYear()+'/'+(cdate.getMonth()+1)+'/'+cdate.getDate()+' '+cdate.getHours()+':'+cdate.getMinutes()+':'+cdate.getSeconds(); + return localstring; +} + + +//主逻辑 +function main(){ + + _CDelay(wait_ms); + var exchange_num=exchanges.length; + var pre_time = new Date(); + var start_time=new Date(); + var last_profit=0; + var pre_profit=Number(_G("pre_profit")); + Log('之前收入累计:'+pre_profit); + + while(true){ + var cur_time = new Date(); + var passedtime=cur_time-pre_time; + pre_time=cur_time; + + for (var i=0; i 策略出处 + +https://www.fmz.com/strategy/157267 + +> 更新时间 + +2019-07-16 14:06:06 diff --git "a/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245 (Copy).md" "b/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245 (Copy).md" new file mode 100644 index 00000000..37f1a978 --- /dev/null +++ "b/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245 (Copy).md" @@ -0,0 +1,72 @@ + +> 策略名称 + +简单多品种商品期货均线策略 (Copy) + +> 策略作者 + +ktz + +> 策略描述 + +商品期货类库实现了$.CTA函数的策略框架,借助该策略框架, 可以短短几十行实现一个并发稳定可实盘的多品种策略 + + https://dn-filebox.qbox.me/21384f4e53937bc1dd252ff478ff08e5b4d52e71.png + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Symbols|rb000,MA000|操作品种| +|FastPeriod|5|快线周期| +|SlowPeriod|20|慢线周期| +|ConfirmPeriod|2|确认周期| +|Lots|true|开仓手数| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2017-06-01 00:00:00 +end: 2017-10-01 00:00:00 +period: 1d +*/ +function main() { + // 使用了商品期货类库的CTA策略框架 + $.CTA(Symbols, function(st) { + var r = st.records + var mp = st.position.amount + var symbol = st.symbol + /* + r为K线, mp为当前品种持仓数量, 正数指多仓, 负数指空仓, 0则不持仓, symbol指品种名称 + 返回值如为n: + n = 0 : 指全部平仓(不管当前持多持空) + n > 0 : 如果当前持多仓,则加n个多仓, 如果当前为空仓则平n个空仓,如果n大于当前持仓, 则反手开多仓 + n < 0 : 如果当前持空仓,则加n个空仓, 如果当前为多仓则平n个多仓,如果-n大于当前持仓, 则反手开空仓 + 无返回值表示什么也不做 + */ + if (r.length < SlowPeriod) { + return + } + var cross = _Cross(TA.EMA(r, FastPeriod), TA.EMA(r, SlowPeriod)); + if (mp <= 0 && cross > ConfirmPeriod) { + Log(symbol, "金叉周期", cross, "当前持仓", mp); + return Lots * (mp < 0 ? 2 : 1) + } else if (mp >= 0 && cross < -ConfirmPeriod) { + Log(symbol, "死叉周期", cross, "当前持仓", mp); + return -Lots * (mp > 0 ? 2 : 1) + } + }); +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/159506 + +> 更新时间 + +2019-07-30 22:26:44 diff --git "a/\347\275\221\346\240\274\347\255\226\347\225\245.md" "b/\347\275\221\346\240\274\347\255\226\347\225\245.md" new file mode 100644 index 00000000..c7337344 --- /dev/null +++ "b/\347\275\221\346\240\274\347\255\226\347\225\245.md" @@ -0,0 +1,250 @@ + +> 策略名称 + +网格策略 + +> 策略作者 + +alinwo + +> 策略描述 + +什么是网格交易策略? +这是一种仓位策略,用于动态调仓。 + +所谓网格交易法(grid trading method),也称鱼网交易网,指以某点为基点,每上涨或下跌一定点数挂一定数量空单或多单,设定盈利目标,但不设止损,当价格朝期望方向进展时获利平仓,并在原点位挂同样的买单或卖单。 + +基本概念 +1、底仓价:价格的标准线,建仓和调仓的重要依据。 +2、低吸高抛:仓位控制贯彻低吸高抛,绝不追涨杀跌。 + +下面举个例子: +操作:在底仓价的附近,我们根据网格的大小,比如每跌3%按仓位买入(第一档:买40%,第二档:买30%,第三档:买20%,第四档:买10%)。 + +要注意的是,这里买卖不是绝对的定量,而是调仓到对应仓位。如果第一次跌破3%,而后上涨到5%时,是不操作的,因为下跌时只建了40%的仓,而上涨5%的仓位是60%,不够抛出。 + +数字货币中应用网格策略 +借助发明者平台,我们可以通过JS代码完整实现网格交易策略,策略实现选中币种价格上涨时分批次建仓以及币价下跌时分批次减仓。 + +策略参数详情 +https://www.pcclean.io/%e6%95%b0%e5%ad%97%e8%b4%a7%e5%b8%81%e9%87%8f%e5%8c%96%e7%ad%96%e7%95%a5%e4%b9%8b%e7%bd%91%e6%a0%bc%e7%ad%96%e7%95%a5/ + + + +> 源码 (javascript) + +``` javascript +var KaiCangPercent=0.5; //开仓百分比 +var PriceChangeStep=0.005; //网格交易中的价格改变量(百分比) +var StocksChangeStep=0.2; //网格交易中的股票改变量(百分比) + +var minBalance=80; +var minStocks=0.001; +var IsJianCang=false; //是否建仓 +var LastOperationPrice=null; //网格交易中最近处理的股票价格 +var PriceChangeStep_Real=null; //网格交易中的价格改变量(实际值) +var StocksChangeStep_Real=null;//网格交易中的股票改变量(实际值) + +function getAccount(){ + var curAccount = exchange.GetAccount(); + while(!curAccount){ + Log("GetAccount() Retrying..."); + Sleep(2000); + nowAccount = exchange.GetAccount(); + } + return curAccount; +} + +function getTicker(){ + var curTicker=exchange.GetTicker(); + while(!curTicker){ + Log("GetTicker() Retrying..."); + Sleep(2000); + curTicker=exchange.GetTicker(); + } + return curTicker; +} + +//type: PERIOD_M5 etc... +function getRecords(type){ + var records = exchange.GetRecords(type); + while(!records || records.length < 100) + { + Log("GetRecords() retrying..."); + Sleep(2000); + records = exchange.GetRecords(type); + } + return records; +} + +function printProfit(){ + try { + var curAccount = getAccount(); + var currrentPrice = getTicker().Last; //当前价格 + LogProfit(curAccount.Balance + curAccount.FrozenBalance + (curAccount.Stocks + curAccount.FrozenStocks) * currrentPrice); + } catch (e) { + Log("LogProfit error:" + e); + } +} + +function EMAChecker(){ + //获得records + var records = getRecords(PERIOD_H1); + var len = records.length; + //获得ema + var ret1=TA.EMA(records,5); + var ret2=TA.EMA(records,15); + var emaFast=ret1[len - 1]; + var emaSlow=ret2[len - 1]; + if (emaFast-emaSlow>=5){ + return 1;//牛市 + } + else if(emaFast-emaSlow<=-5){ + return -1;//熊市 + } + return 0; +} + +function MACDChecker(){ + //获得records + var records = getRecords(PERIOD_H1); + var len = records.length; + + //获得当前MACD指标 + var ret = TA.MACD(records, 12, 26, 9); + var dif = ret[0]; + var dea = ret[1]; + var macd = ret[2]; + + //获得KDJ + var ret2 = TA.KDJ(records, 9, 3, 3); + var vark = ret2[0]; + var vard = ret2[1]; + var varj = ret2[2]; + + if (macd[len - 1]>=0.2){ + return 1;//牛市 + } + else if (macd[len - 1]<=-0.2){ + return -1;//熊市 + } + return 0; +} + +//amount: CNY amount +function BuyAndPrintProfit(amount){ + var nowAccount = getAccount(); + if (nowAccount.Balance > minBalance) { + exchange.Buy(amount); + printProfit(); + } +} + +function SellAndPrintProfit(stocksAmount){ + var nowAccount = getAccount(); + if (nowAccount.Stocks > minStocks) { + exchange.Sell(stocksAmount); + printProfit(); + } +} + +function BuyPercent(percent){ + var nowAccount = getAccount(); + var nowPrice = getTicker().Last; + var totalAssets=nowAccount.Balance + nowAccount.FrozenBalance + (nowAccount.Stocks + nowAccount.FrozenStocks) * nowPrice; + var canOperateAssets=parseFloat((totalAssets*percent).toFixed(2)); + var realBuyAmount=(canOperateAssets0){//涨 + var n=Math.floor((nowPrice-LastOperationPrice)/PriceChangeStep_Real); + if (n>0){ + LastOperationPrice=LastOperationPrice+n*PriceChangeStep_Real; + SellAndPrintProfit(n*StocksChangeStep_Real); + + //如果没有库存了 + var nowAccount = getAccount(); + if ((nowAccount.Stocks + nowAccount.FrozenStocks) <= minStocks){ + Log("涨幅过大?已经没有库存了。"); + startTable(); + } + } + }else if (nowPrice-LastOperationPrice<0){//跌 + var n=Math.floor((LastOperationPrice-nowPrice)/PriceChangeStep_Real); + if (n>0){ + LastOperationPrice=LastOperationPrice-n*PriceChangeStep_Real; + BuyAndPrintProfit(n*StocksChangeStep_Real*nowPrice); + } + } + } +} + +function XiongShi_Do(){ + //清仓 + var nowAccount = getAccount(); + SellAndPrintProfit(nowAccount.Stocks); + IsJianCang=false; +} + +function main() { + Log(exchange.GetAccount()); + + while (true) { + + //确定是否在MACD牛市范围 + var result1=MACDChecker(); + var result2=EMAChecker(); + if (result1===1 && result2===1){ + NiuShi_Do(); + }else if (result1===-1 || result2===-1){ + XiongShi_Do(); + } + + //等待下次查询交易所 + Sleep(15*1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/156663 + +> 更新时间 + +2019-07-11 21:52:57 diff --git "a/\350\202\257\347\211\271\347\272\263\351\200\232\351\201\223\345\215\207\347\272\247\347\211\210\351\207\221\350\202\257\347\211\271\347\272\263kingkeltner\347\255\226\347\225\245.md" "b/\350\202\257\347\211\271\347\272\263\351\200\232\351\201\223\345\215\207\347\272\247\347\211\210\351\207\221\350\202\257\347\211\271\347\272\263kingkeltner\347\255\226\347\225\245.md" new file mode 100644 index 00000000..98474d57 --- /dev/null +++ "b/\350\202\257\347\211\271\347\272\263\351\200\232\351\201\223\345\215\207\347\272\247\347\211\210\351\207\221\350\202\257\347\211\271\347\272\263kingkeltner\347\255\226\347\225\245.md" @@ -0,0 +1,54 @@ + +> 策略名称 + +肯特纳通道升级版金肯特纳kingkeltner策略 + +> 策略作者 + +Hukybo + +> 策略描述 + +**策略简介** +肯特纳通道是由Chester W. Keltner在上个世纪60年代发明的一个交易系统,其核心思想是均线理论。并且当时该系统在非常长的一段时间内,得到了令人瞩目的成绩。虽然原版的肯特纳通道系统没有刚出现时那么有效,但它的核心思想,至今都对交易界产生很深远的影响。 +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4104) + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2019-01-01 00:00:00 +end: 2019-07-27 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_BitMEX","currency":"XBT_USD"}] +args: [["MAN",20],["TradeAmount",10000,126961],["SlideTick",2,126961],["ContractType","XBTUSD",126961]] +*) + +// 参数 +MAN:=20; +ATRN:=50; + +JG:=(HIGH+LOW+CLOSE)/3; // 基础价格 +ZG^^MA(JG,MAN); // 中轨 +TRUEHIGH1:=IF(HIGH>REF(C,1),HIGH,REF(C,1)); +TRUELOW1:=IF(LOW<=REF(C,1),LOW,REF(C,1)); +TRUERANGE1:=IF(ISLASTBAR,H-L,TRUEHIGH1-TRUELOW1); // 计算真实波动幅度 +SG^^ZG+MA(TRUERANGE1,ATRN); // 上轨 +XG^^ZG-MA(TRUERANGE1,ATRN); // 下轨 + +ZG>REF(ZG,1)&&C>SG,BK; // 中轨向上,并且价格升破上轨,开多单 +CZG,BP; // 持有空单时,价格升破中轨,平空单 +AUTOFILTER; // 设置信号过滤方式 +``` + +> 策略出处 + +https://www.fmz.com/strategy/159285 + +> 更新时间 + +2019-07-27 16:28:56 diff --git "a/\350\203\275\351\207\217\346\275\256OBV\345\234\250\351\207\217\345\214\226\344\272\244\346\230\223\344\270\255\347\232\204\350\257\246\347\273\206\347\224\250\346\263\225\345\222\214\345\256\236\346\210\230\346\212\200\345\267\247.md" "b/\350\203\275\351\207\217\346\275\256OBV\345\234\250\351\207\217\345\214\226\344\272\244\346\230\223\344\270\255\347\232\204\350\257\246\347\273\206\347\224\250\346\263\225\345\222\214\345\256\236\346\210\230\346\212\200\345\267\247.md" new file mode 100644 index 00000000..513af460 --- /dev/null +++ "b/\350\203\275\351\207\217\346\275\256OBV\345\234\250\351\207\217\345\214\226\344\272\244\346\230\223\344\270\255\347\232\204\350\257\246\347\273\206\347\224\250\346\263\225\345\222\214\345\256\236\346\210\230\346\212\200\345\267\247.md" @@ -0,0 +1,43 @@ + +> 策略名称 + +能量潮OBV在量化交易中的详细用法和实战技巧 + +> 策略作者 + +Hukybo + +> 策略描述 + +**策略简介** +古代打仗有一句这样的成语:“兵马未动,粮草先行”。在交易中也有一句类似的话:“量在价先”。意思是说:价格的上涨和下跌,背后都是成交量在推动,一切风吹草动,最先反应在成交量上。于是呢,就有人发明了衡量成交量的能量潮指标(On Balance Volume,OBV)。 + +能量潮(OBV)是上个世纪60年代由格兰维尔(Joe Granville)发明,虽然其中的算法很简单,但是在交易的“价、量、时、空”四个要素中,以“量”为切入点,得到了很多交易者的青睐。作为交易市场中的人气指标,能量潮可以很直观的反应出价格与成交量的相互关系,从而帮助交易者从更多的角度观察市场。 + +[点击查看更多内容](https://www.fmz.com/bbs-topic/4118) + + + +> 源码 (麦语言) + +``` pascal +N:=10; +OBV:=SUM(IFELSE(CLOSE>REF(CLOSE,1),VOL,IFELSE(CLOSEREF(B,1) && D>REF(D,1) && B>D,BK; +BREF(B,1) || D>REF(D,1) || B>D,BP; +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/159997 + +> 更新时间 + +2019-07-31 19:44:46 diff --git "a/\350\216\267\345\217\226USDT\345\222\214USD\347\232\204\345\256\236\346\227\266\346\261\207\347\216\207.md" "b/\350\216\267\345\217\226USDT\345\222\214USD\347\232\204\345\256\236\346\227\266\346\261\207\347\216\207.md" new file mode 100644 index 00000000..8fcd55a3 --- /dev/null +++ "b/\350\216\267\345\217\226USDT\345\222\214USD\347\232\204\345\256\236\346\227\266\346\261\207\347\216\207.md" @@ -0,0 +1,35 @@ + +> 策略名称 + +获取USDT和USD的实时汇率 + +> 策略作者 + +affroad + +> 策略描述 + +通过Http请求读取coinmarketcap上的实时USDT汇率 + +我的博客:https://www.pcclean.io/yax2 + + + +> 源码 (javascript) + +``` javascript +//获得美元汇率 +function getUSDTratio(){ +var r = _C(HttpQuery,"https://api.coinmarketcap.com/v2/ticker/825/"); +var o = JSON.parse(r); +return o.data.quotes.USD.price; +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/157364 + +> 更新时间 + +2019-07-16 14:21:58 diff --git "a/\351\222\211\351\222\211\346\216\250\351\200\201.md" "b/\351\222\211\351\222\211\346\216\250\351\200\201.md" new file mode 100644 index 00000000..2822465f --- /dev/null +++ "b/\351\222\211\351\222\211\346\216\250\351\200\201.md" @@ -0,0 +1,50 @@ + +> 策略名称 + +钉钉推送 + +> 策略作者 + +jason47 + +> 策略描述 + +- $.ddNotice(title, content) +> title: 字符串类型,推送的标题 +> content: 数组类型,markdown格式 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|DING_URI|钉钉URI|钉钉URI| + + +> 源码 (javascript) + +``` javascript +$.ddNotice = function(title, content) { + content = content == null ? title : content instanceof Array ? content.join('\n') : content + HttpQuery(DING_URI, { + method: 'POST', + timeout: 3000, + data: JSON.stringify({ + msgtype: 'markdown', + markdown: { + title: title, + text: content + } + }) + }, null, 'Content-Type: application/json') +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/159668 + +> 更新时间 + +2019-08-13 22:38:39 From 276639d2f093ece1c8d933c9368b87985cbf2fdb Mon Sep 17 00:00:00 2001 From: Zero Date: Thu, 2 Jan 2020 17:51:10 +0800 Subject: [PATCH 16/19] update --- ...45\346\234\272\345\231\250\344\272\272.md" | 2 +- ...51\345\231\250\347\255\226\347\225\245.md" | 137 ++++ ...33\344\273\267\347\255\226\347\225\245.md" | 121 ++++ ...\255\226\347\225\245Python\347\211\210.md" | 126 ++++ ...44\346\230\223\347\255\226\347\225\245.md" | 106 +++ ...01\347\240\264\347\255\226\347\225\245.md" | 104 +++ ...07\346\240\207\347\255\226\347\225\245.md" | 105 +++ ...45\212\251MACD\347\255\226\347\225\245.md" | 126 ++++ ...01\347\240\264\347\255\226\347\225\245.md" | 113 +++ ...32\351\201\223\347\255\226\347\225\245.md" | 101 +++ ...55\226\347\225\245 Python \347\211\210.md" | 105 +++ ...60\345\215\226\347\273\237\350\256\241.md" | 2 +- ...Bitmex position-change push(websocket).md" | 2 +- ...\226\347\225\245\344\271\213Penny Jump.md" | 346 --------- ...\347\225\245OKEX Websocket\347\211\210.md" | 670 +++++++++++++++++ ...344\272\206SSL\351\252\214\350\257\201.md" | 2 +- ...13\350\257\225\347\255\226\347\225\245.md" | 119 +++ Dual Thrust OKEX Feature.md | 2 +- ...44\346\230\223\346\250\241\346\235\277.md" | 78 -- ...74\346\216\222\345\272\217\357\274\211.md" | 329 +++++++++ ...07\350\215\241\347\211\210\343\200\221.md" | 359 ++++++++++ ...77\346\234\272\345\231\250\344\272\272.md" | 187 +++++ ...77\346\234\272\345\231\250\344\272\272.md" | 241 +++++++ ...77\346\234\272\345\231\250\344\272\272.md" | 215 ++++++ ...15\344\276\233\345\272\224\351\207\217.md" | 2 +- Iceberg Buy Order.md | 2 +- ...350\257\225for\346\226\260\346\211\213.md" | 149 ++++ ...56\347\273\203\344\271\240\357\274\211.md" | 2 +- "Python API \346\265\213\350\257\225.md" | 19 +- ...71\345\206\262\347\255\226\347\225\245.md" | 192 ----- ...04\346\265\213\344\271\260\345\215\226.md" | 9 +- README.md | 77 +- SeamlessConnWS.md | 260 +++++++ "annotation\345\261\236\346\200\247.md" | 249 ------- ...33\351\207\217\346\216\222\345\272\217.md" | 253 +++++++ ...26\347\237\277\346\274\224\347\244\272.md" | 2 +- ...1-\345\237\272\347\241\200\347\211\210.md" | 2 +- ...32\351\222\261\350\265\232\347\237\277.md" | 332 +++++++++ ...47\211\210|Simple Iceberg order to buy.md" | 2 +- ...7\211\210|Simple Iceberg order to sell.md" | 2 +- ...32\204\346\216\222\345\210\227 - btcdw.md" | 39 - ...15\350\275\254\347\255\226\347\225\245.md" | 107 +++ ...50\346\234\237\345\245\227\345\210\251.md" | 48 +- ...63\350\241\241\347\255\226\347\225\245.md" | 6 +- ...5\245V2.0_\345\271\264\345\214\226130%.md" | 145 ++++ ...43\345\245\227\347\256\227\346\263\225.md" | 476 ++++++++++++ ...7\240\201\346\235\245\350\207\252zero).md" | 2 +- ...0_\345\214\272\347\217\255\344\270\273.md" | 95 +++ ...76\271\347\275\221\346\240\274 (Copy).md" | 190 ----- ...6\240\274 (OK\346\234\237\350\264\247).md" | 499 +++++++++++++ ...1\346\240\274x\347\216\260\350\264\247.md" | 675 ++++++++++++++++++ ...10\346\225\231\345\255\246\357\274\211.md" | 97 +++ ...10\346\225\231\345\255\246\357\274\211.md" | 202 ++++++ ...345\210\260\346\234\254\345\234\260CSV.md" | 2 +- ...44\346\230\223\347\255\226\347\225\245.md" | 101 --- ...44\346\230\223\347\255\226\347\225\245.md" | 2 +- ...74\357\274\211|Multiple charts example.md" | 2 +- ...42\347\233\210\347\255\226\347\225\245.md" | 91 +++ ...71\351\207\217\344\273\273\345\212\241.md" | 6 +- ...45\237\272\347\202\2711000\357\274\211.md" | 2 +- ...\357\274\211|Cancel ALL Binance Orders.md" | 2 +- ...26\347\225\245\347\240\224\347\251\266.md" | 6 +- ...16\347\202\271\347\255\226\347\225\245.md" | 53 ++ ...\255\226\347\225\245|Index Balance Bot.md" | 2 +- ...00\347\247\273\346\244\215\357\274\211.md" | 381 ++++++++++ ...56\344\273\267\347\233\221\346\216\247.md" | 79 ++ ...23\346\234\272\345\231\250\344\272\272.md" | 190 +++++ ...77\345\274\217\346\265\213\350\257\225.md" | 4 +- ...10\346\225\231\345\255\246\357\274\211.md" | 235 ++++++ ...57\345\220\246\346\255\243\345\270\270.md" | 2 +- ...13\350\257\225\345\233\276\350\241\250.md" | 183 ----- ...32\345\270\202\345\267\245\345\205\267.md" | 17 +- ...53\345\270\201\347\202\271\345\215\241.md" | 2 +- ...53\345\270\201\347\262\276\345\272\246.md" | 2 +- ...ce announcements and sell Delist coin.md" | 2 +- ...5\245V1.0_OKex\345\220\210\347\272\246.md" | 266 +++++++ ...0_\345\214\272\347\217\255\344\270\273.md" | 111 +++ ...34\346\224\266\345\211\262\346\234\272.md" | 12 +- ...44\272\272|Stop Loss Below Fixed Price.md" | 2 +- ...47\225\245|Moving Average Bot 30 lines.md" | 2 +- ...72\277\347\255\226\347\225\245 (Copy).md" | 72 -- ...07\347\272\277\347\255\226\347\225\245.md" | 3 +- ...71\345\206\262\345\212\237\350\203\275.md" | 135 ++++ ...272|Buy then Sell (ping-pong strategy).md" | 11 +- ...07\347\272\277\347\255\226\347\225\245.md" | 9 +- ...50\351\207\212\347\256\200\345\214\226.md" | 108 +++ ...30\345\234\250\350\266\213\345\212\277.md" | 2 +- ...My\350\257\255\350\250\200\347\211\210.md" | 54 ++ ...55\347\232\204\345\272\224\347\224\250.md" | 53 ++ ...Push the price information to telegram.md" | 2 +- ...11\351\222\211\346\216\250\351\200\201.md" | 2 +- ...1\345\206\234\347\275\221\346\240\274).md" | 210 ++++++ ...345\260\224\347\275\221\346\240\274btc.md" | 462 ++++++++++++ 93 files changed, 9152 insertions(+), 1563 deletions(-) create mode 100644 "8.10 \347\273\217\345\205\270\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" create mode 100644 "8.11 \350\217\262\351\230\277\351\207\214\345\233\233\344\273\267\347\255\226\347\225\245.md" create mode 100644 "8.2 \350\207\252\351\200\202\345\272\224\345\212\250\346\200\201\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245Python\347\211\210.md" create mode 100644 "8.3 \347\273\217\345\205\270MACD\344\272\244\346\230\223\347\255\226\347\225\245.md" create mode 100644 "8.4 \345\212\250\346\200\201\351\230\266\346\242\257\347\252\201\347\240\264\347\255\226\347\225\245.md" create mode 100644 "8.5 AROON\351\230\277\351\232\206\346\214\207\346\240\207\347\255\226\347\225\245.md" create mode 100644 "8.6 \344\275\277\347\224\250DMI\350\276\205\345\212\251MACD\347\255\226\347\225\245.md" create mode 100644 "8.7 \346\227\245\345\206\205\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\347\255\226\347\225\245.md" create mode 100644 "8.8 \345\242\236\345\274\272\347\211\210\345\224\220\345\245\207\345\256\211\351\200\232\351\201\223\347\255\226\347\225\245.md" create mode 100644 "8.9 Dual Thrust \345\214\272\351\227\264\347\252\201\347\240\264\347\255\226\347\225\245 Python \347\211\210.md" delete mode 100644 "C++\345\225\206\345\223\201\346\234\237\350\264\247\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213Penny Jump.md" create mode 100644 "C++\346\234\237\350\264\247\351\253\230\351\242\221\345\245\227\345\270\201\347\255\226\347\225\245OKEX Websocket\347\211\210.md" create mode 100644 "Deribit\346\234\237\346\235\203\346\265\213\350\257\225\347\255\226\347\225\245.md" delete mode 100644 "FCoin\346\235\240\346\235\206\344\272\244\346\230\223\346\250\241\346\235\277.md" create mode 100644 "FMEX[\347\251\272\345\244\264]\350\266\213\345\212\277\346\214\226\347\237\277\347\255\226\347\225\245\357\274\210\351\232\217\346\234\272\347\275\221\346\240\274\346\216\222\345\272\217\357\274\211.md" create mode 100644 "FMEX\346\214\226\347\237\277\347\255\226\347\225\245\357\274\210\346\216\222\345\272\217\357\274\211btc\345\235\207\350\241\241\346\210\226\343\200\220\351\234\207\350\215\241\347\211\210\343\200\221.md" create mode 100644 "FMEX\347\256\200\345\215\225\344\272\244\346\230\223\346\214\226\347\237\277\346\234\272\345\231\250\344\272\272.md" create mode 100644 "FMEX\347\256\200\345\215\225\346\214\202\345\215\225\346\214\226\347\237\277\346\234\272\345\231\250\344\272\272.md" create mode 100644 "FMEX\347\256\200\345\215\225\346\216\222\345\272\217\346\214\226\347\237\277\346\234\272\345\231\250\344\272\272.md" create mode 100644 "OKex\346\234\237\350\264\247\346\265\213\350\257\225for\346\226\260\346\211\213.md" delete mode 100644 "Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.md" create mode 100644 SeamlessConnWS.md delete mode 100644 "annotation\345\261\236\346\200\247.md" create mode 100644 "fcoin-\345\244\232\347\251\272\345\212\233\351\207\217\346\216\222\345\272\217.md" create mode 100644 "\344\274\230\345\205\210\347\211\210-FMEX[\345\244\232\345\244\264]\350\266\213\345\212\277mining\347\255\226\347\225\245\357\274\214\351\231\204\345\233\276\357\274\214\350\265\232\345\270\201\350\265\232\351\222\261\350\265\232\347\237\277.md" delete mode 100644 "\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.md" create mode 100644 "\345\210\251\347\224\250\345\233\236\345\275\222\345\271\205\345\272\246\346\236\204\345\273\272\345\244\232\345\223\201\347\247\215\345\217\215\350\275\254\347\255\226\347\225\245.md" create mode 100644 "\345\215\225\345\225\206\345\223\201\345\260\217\345\215\226\351\203\250\347\255\226\347\225\245V2.0_\345\271\264\345\214\226130%.md" create mode 100644 "\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225.md" create mode 100644 "\345\215\225\350\264\247\345\270\201\345\212\250\346\200\201\345\235\207\350\241\241V1.0_\345\214\272\347\217\255\344\270\273.md" delete mode 100644 "\345\215\225\350\276\271\347\275\221\346\240\274 (Copy).md" create mode 100644 "\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).md" create mode 100644 "\345\215\225\350\276\271\347\275\221\346\240\274x\347\216\260\350\264\247.md" create mode 100644 "\345\225\206\345\223\201\346\234\237\350\264\247\345\270\203\346\236\227\346\214\207\346\240\207\347\252\201\347\240\264\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" create mode 100644 "\345\225\206\345\223\201\346\234\237\350\264\247\350\256\241\345\210\222\345\247\224\346\211\230\345\267\245\345\205\267\357\274\210\346\225\231\345\255\246\357\274\211.md" delete mode 100644 "\345\237\272\344\272\216\345\233\236\345\275\222\345\271\205\345\272\246\347\232\204\345\217\215\350\275\254\344\272\244\346\230\223\347\255\226\347\225\245.md" create mode 100644 "\345\244\232\347\272\247\347\231\276\345\210\206\346\257\224\346\255\242\347\233\210\347\255\226\347\225\245.md" create mode 100644 "\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" create mode 100644 "\346\225\231\345\255\246\347\255\226\347\225\245TCI\347\255\226\347\225\245\357\274\210\351\272\246\350\257\255\350\250\200\347\247\273\346\244\215\357\274\211.md" create mode 100644 "\346\225\260\345\255\227\350\264\247\345\270\201\346\234\237\350\264\247\347\216\260\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247.md" create mode 100644 "\346\232\264\351\233\252\347\275\221\346\240\274-7*24\345\260\217\346\227\266\344\272\244\346\230\223\346\234\272\345\231\250\344\272\272.md" create mode 100644 "\346\240\271\346\215\256\345\225\206\345\223\201\346\234\237\350\264\247\350\256\241\345\210\222\345\247\224\346\211\230\345\267\245\345\205\267\345\256\236\347\216\260\344\270\200\344\270\252\347\237\255\347\272\277\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" delete mode 100644 "\346\265\213\350\257\225\345\233\276\350\241\250.md" rename "\346\267\261\345\272\246\345\201\232\345\270\202.md" => "\346\267\261\345\272\246\345\201\232\345\270\202 \347\233\230\345\217\243\346\216\247\345\210\266 \346\223\215\347\233\230\346\234\272\345\231\250\344\272\272 \345\201\232\345\270\202\345\267\245\345\205\267.md" (95%) create mode 100644 "\347\211\233\347\206\212\345\260\217\345\215\226\351\203\250\347\255\226\347\225\245V1.0_OKex\345\220\210\347\272\246.md" create mode 100644 "\347\211\233\347\206\212\347\214\264\345\270\202\345\210\244\346\226\255V1.0_\345\214\272\347\217\255\344\270\273.md" delete mode 100644 "\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245 (Copy).md" create mode 100644 "\347\256\200\345\215\225\347\232\204\345\201\232\345\270\202\345\257\271\345\206\262\345\212\237\350\203\275.md" create mode 100644 "\347\273\217\345\205\270\345\235\207\347\272\277\347\255\226\347\225\245V1.0_\345\214\272\347\217\255\344\270\273\346\263\250\351\207\212\347\256\200\345\214\226.md" create mode 100644 "\350\207\252\351\200\202\345\272\224\345\212\250\346\200\201\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245My\350\257\255\350\250\200\347\211\210.md" create mode 100644 "\350\243\270K\344\270\212\344\270\213\345\275\261\347\272\277\345\234\250\344\272\244\346\230\223\347\255\226\347\225\245\344\270\255\347\232\204\345\272\224\347\224\250.md" create mode 100644 "\351\246\231\345\206\234\347\275\221\346\240\274).md" create mode 100644 "\351\251\254\344\270\201\346\240\274\345\260\224\347\275\221\346\240\274btc.md" diff --git "a/2014\345\271\264\347\232\204\347\256\200\346\230\223\346\257\224\347\211\271\345\270\201\351\253\230\351\242\221\347\255\226\347\225\245\346\234\272\345\231\250\344\272\272.md" "b/2014\345\271\264\347\232\204\347\256\200\346\230\223\346\257\224\347\211\271\345\270\201\351\253\230\351\242\221\347\255\226\347\225\245\346\234\272\345\231\250\344\272\272.md" index 0efb7256..dca94bfc 100644 --- "a/2014\345\271\264\347\232\204\347\256\200\346\230\223\346\257\224\347\211\271\345\270\201\351\253\230\351\242\221\347\255\226\347\225\245\346\234\272\345\231\250\344\272\272.md" +++ "b/2014\345\271\264\347\232\204\347\256\200\346\230\223\346\257\224\347\211\271\345\270\201\351\253\230\351\242\221\347\255\226\347\225\245\346\234\272\345\231\250\344\272\272.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/8.10 \347\273\217\345\205\270\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" "b/8.10 \347\273\217\345\205\270\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" new file mode 100644 index 00000000..c3a0d73f --- /dev/null +++ "b/8.10 \347\273\217\345\205\270\346\201\222\346\270\251\345\231\250\347\255\226\347\225\245.md" @@ -0,0 +1,137 @@ + +> 策略名称 + +8.10 经典恒温器策略 + +> 策略作者 + +Hukybo + +> 策略描述 + +#### 摘要 +趋势行情不会永远持续下去,事实上市场大部分时间都处于震荡行情,所以才会有人希望能得到一种交易策略,既可以用在趋势行情,也可以用在震荡行情。那么今天我们就用发明者量化交易平台,构建一个趋势和震荡行情通用的经典恒温器策略。 +[点击阅读更多](https://www.fmz.com/bbs-topic/4827) + + + +> 源码 (python) + +``` python +'''backtest +start: 2015-02-22 00:00:00 +end: 2019-12-20 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' + +mp = 0 # 定义一个全局变量,用于控制虚拟持仓 + +# 策略主函数 +def onTick(): + exchange.SetContractType("rb000") # 订阅期货品种 + bar_arr = exchange.GetRecords() # 获取K线数组 + if len(bar_arr) < 100: # 如果K线少于100根 + return # 直接返回 + close0 = bar_arr[-1]['Close'] # 获取最新价格(卖价),用于开平仓 + bar_arr.pop() # 删除K线数组最后一个元素,策略采用开平仓条件成立,下根K线交易模式 + + # 计算CMI指标用以区分震荡市与趋势市 + close1 = bar_arr[-1]['Close'] # 最新收盘价 + close30 = bar_arr[-30]['Close'] # 前30根K线的收盘价 + hh30 = TA.Highest(bar_arr, 30, 'High') # 最近30根K线的最高价 + ll30 = TA.Lowest(bar_arr, 30, 'Low') # 最近30根K线的最低价 + cmi = abs((close1 - close30) / (hh30 - ll30)) * 100 # 计算市场波动指数 + + # 震荡市中收盘价大于关键价格为宜卖市,否则为宜买市 + high1 = bar_arr[-1]['High'] # 最新最高价 + low1 = bar_arr[-1]['Low'] # 最新最低价 + kod = (close1 + high1 + low1) / 3 # 计算关键价格 + if close1 > kod: + be = 1 + se = 0 + else: + be = 0 + se = 1 + + # 计算10根K线ATR指标 + atr10 = TA.ATR(bar_arr, 10)[-1] + + # 定义最高价与最低价3日均线 + high2 = bar_arr[-2]['High'] # 上根K线最高价 + high3 = bar_arr[-3]['High'] # 前根K线最高价 + low2 = bar_arr[-2]['Low'] # 上根K线最低价 + low3 = bar_arr[-3]['Low'] # 前根K线最低价 + avg3high = (high1 + high2 + high3) / 3 # 最近3根K线最高价的均值 + avg3low = (low1 + low2 + low3) / 3 # 最近3根K线最低价的均值 + + # 计算震荡行情的进场价格 + open1 = bar_arr[-1]['Open'] # 最新开盘价 + if close1 > kod: # 如果收盘价大于关键价格 + lep = open1 + atr10 * 3 + sep = open1 - atr10 * 2 + else: + lep = open1 + atr10 * 2 + sep = open1 - atr10 * 3 + lep1 = max(lep, avg3high) # 计算震荡市多头进场价格 + sep1 = min(sep, avg3low) # 计算震荡市空头进场价格 + + # 计算趋势行情的进场价格 + boll = TA.BOLL(bar_arr, 50, 2) + up_line = boll[0][-1] + mid_line = boll[1][-1] + down_line = boll[2][-1] + + global mp # 引入全局变量 + if cmi < 20: # 如果是震荡行情 + if mp == 0 and close1 >= lep1 and se: + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(close0, 1) # 开多单 + mp = 1 # 设置虚拟持仓的值,即有多单 + if mp == 0 and close1 <= sep1 and be: + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(close0 - 1, 1) # 开空单 + mp = -1 # 设置虚拟持仓的值,即有空单 + if mp == 1 and (close1 >= avg3high or be): + exchange.SetDirection("closebuy") # 设置交易方向和类型 + exchange.Sell(close0 - 1, 1) # 平多单 + mp = 0 # 设置虚拟持仓的值,即空仓 + if mp == -1 and (close1 <= avg3low or se): + exchange.SetDirection("closesell") # 设置交易方向和类型 + exchange.Buy(close0, 1) # 平空单 + mp = 0 # 设置虚拟持仓的值,即空仓 + else: # 如果是趋势行情 + if mp == 0 and close1 >= up_line: + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(close0, 1) # 开多单 + mp = 1 # 设置虚拟持仓的值,即有多单 + if mp == 0 and close1 <= down_line: + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(close0 - 1, 1) # 开空单 + mp = -1 # 设置虚拟持仓的值,即有空单 + if mp == 1 and close1 <= mid_line: + exchange.SetDirection("closebuy") # 设置交易方向和类型 + exchange.Sell(close0 - 1, 1) # 平多单 + mp = 0 # 设置虚拟持仓的值,即空仓 + if mp == -1 and close1 >= mid_line: + exchange.SetDirection("closesell") # 设置交易方向和类型 + exchange.Buy(close0, 1) # 平空单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + +# 程序入口 +def main(): + while True: # 进入无限循环模式 + onTick() # 执行策略主函数 + Sleep(1000) # 休眠1秒 + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/179014 + +> 更新时间 + +2019-12-21 17:59:05 diff --git "a/8.11 \350\217\262\351\230\277\351\207\214\345\233\233\344\273\267\347\255\226\347\225\245.md" "b/8.11 \350\217\262\351\230\277\351\207\214\345\233\233\344\273\267\347\255\226\347\225\245.md" new file mode 100644 index 00000000..311c574c --- /dev/null +++ "b/8.11 \350\217\262\351\230\277\351\207\214\345\233\233\344\273\267\347\255\226\347\225\245.md" @@ -0,0 +1,121 @@ + +> 策略名称 + +8.11 菲阿里四价策略 + +> 策略作者 + +Hukybo + +> 策略描述 + +#### 摘要 +在期货市场,价格呈现一切。几乎所有的技术分析,如均线、布林线、MACD、KDJ等等,这些都是以价格为基础,通过特定的方法计算。包括基本面分析也是如此,通过分析近期和远期价差、期货和现货升贴水、上下游库存等等数据,计算当前价格是否合理,并预估未来的价格。既然如此,为什么不直接研究价格呢?今天我们讲的菲阿里四价策略就是完全根据价格来做出卖决定。 + +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4857) + + + +> 源码 (python) + +``` python +# 回测配置 +'''backtest +start: 2015-02-22 00:00:00 +end: 2019-12-26 00:00:00 +period: 5m +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' + + +# 导入库 +import time # 用于转换时间格式 + + +# 策略主函数 +def onTick(): + exchange.SetContractType("rb888") # 订阅期货品种 + bar_arr = _C(exchange.GetRecords, PERIOD_D1) # 获取日线数组 + if len(bar_arr) < 2: # 如果小于2根K线 + return # 返回继续等待数据 + yesterday_high = bar_arr[-2]['High'] # 昨日最高价 + yesterday_low = bar_arr[-2]['Low'] # 昨日最低价 + yesterday_close = bar_arr[-2]['Close'] # 昨日收盘价 + today_open = bar_arr[-1]['Open'] # 当日开盘价 + + bar_arr = _C(exchange.GetRecords) # 获取当前设置周期K线数组 + current_time = bar_arr[-1]['Time'] # 获取当前K线时间戳 + time_local = time.localtime(current_time / 1000) # 处理时间戳 + hour = int(time.strftime("%H", time_local)) # 格式化时间戳,并获取小时 + minute = int(time.strftime("%M", time_local)) # 格式化时间戳,并获取分钟 + current_close = bar_arr[-1]['Close'] # 获取最新价格 + + # 处理时间函数 + def trade_time(hour, minute): + hour = str(hour) + minute = str(minute) + if len(minute) == 1: + minute = "0" + minute + return int(hour + minute) + + # 获取持仓 + real_position = _C(exchange.GetPosition) # 获取持仓数组 + if len(real_position) > 0: # 如果持仓数组长度大于0 + real_position = real_position[0] + if real_position['ContractType'] == 'rb888': # 如果持仓品种等于订阅品种 + if real_position['Type'] == 0 or real_position['Type'] == 2: # 如果是多单 + mp = real_position['Amount'] # 赋值持仓为正数 + elif real_position['Type'] == 1 or real_position['Type'] == 3: + mp = -real_position['Amount'] # 赋值持仓为负数 + else: + mp = 0 # 赋值持仓为0 + + # 设置多头止损 + if today_open / yesterday_high > 1.005: # 如果当天开盘价大于昨天最高价 + long_stop_loss = yesterday_high # 设置多头止损价为昨天最高价 + elif today_open / yesterday_high < 0.995: # 如果当天开盘价小于昨天最高价 + long_stop_loss = today_open # 设置多头止损价为当天开盘价 + else: # 如果当天开盘价接近于昨天最高价 + long_stop_loss = (yesterday_high + yesterday_low) / 2 # 设置多头止损为昨天中间价 + + # 设置空头止损 + if today_open / yesterday_low < 0.995: # 如果当天开盘价小于昨天最低价 + short_stop_loss = yesterday_low # 设置空头止损价为昨天最低价 + elif today_open / yesterday_low > 1.005: # 如果当天开盘价大于昨天最低价 + short_stop_loss = today_open # 设置空头止损价为当天开盘价 + else: # 如果当天开盘价接近于昨天最低价 + short_stop_loss = (yesterday_high + yesterday_low) / 2 # 设置多头止损为昨天中间价 + + # 下单交易 + if mp > 0: # 如果当前持有多单 + if current_close < long_stop_loss or trade_time(hour, minute) > 1450: # 如果当前价格小于多头止损线,或者超过规定的交易时间 + exchange.SetDirection("closebuy") # 设置交易方向和类型 + exchange.Sell(current_close - 1, 1) # 平多单 + if mp < 0: # 如果当前持有空单 + if current_close > short_stop_loss or trade_time(hour, minute) > 1450: # 如果当前价格大于空头止损线,或者超过规定的交易时间 + exchange.SetDirection("closesell") # 设置交易方向和类型 + exchange.Buy(current_close + 1, 1) # 平空单 + if mp == 0 and 930 < trade_time(hour, minute) < 1450: # 如果当前无持仓,并且在规定的交易时间内 + if current_close > yesterday_high: # 如果当前价格大于昨天最高价 + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(current_close + 1, 1) # 开多单 + elif current_close < yesterday_low: # 如果价格小于昨天最低价 + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(current_close - 1, 1) # 开空单 + + +# 程序入口 +def main(): + while True: # 无限循环 + onTick() # 执行策略主函数 + Sleep(1000) #休眠1秒 + +``` + +> 策略出处 + +https://www.fmz.com/strategy/179505 + +> 更新时间 + +2019-12-28 15:08:11 diff --git "a/8.2 \350\207\252\351\200\202\345\272\224\345\212\250\346\200\201\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245Python\347\211\210.md" "b/8.2 \350\207\252\351\200\202\345\272\224\345\212\250\346\200\201\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245Python\347\211\210.md" new file mode 100644 index 00000000..b0a88cef --- /dev/null +++ "b/8.2 \350\207\252\351\200\202\345\272\224\345\212\250\346\200\201\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245Python\347\211\210.md" @@ -0,0 +1,126 @@ + +> 策略名称 + +8.2 自适应动态双均线策略Python版 + +> 策略作者 + +Hukybo + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|ama_short|50|ama_short| +|ama_long|100|ama_long| + + +> 源码 (python) + +``` python +# 回测配置 +'''backtest +start: 2015-02-22 00:00:00 +end: 2019-10-17 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' + + +# 导入库 +import talib +import numpy as np + + +mp = 0 # 定义一个全局变量,用于控制虚拟持仓 + + +# 把K线数组转换成收盘价数组,用于计算AMA的值 +def get_close(r): + arr = [] + for i in r: + arr.append(i['Close']) + return arr + + +# 判断AMA是否上升 +def is_up(arr): + arr_len = len(arr) + if arr[arr_len - 1] > arr[arr_len - 2] and arr[arr_len - 2] > arr[arr_len - 3]: + return True + + +# 判断AMA是否下降 +def is_down(arr): + arr_len = len(arr) + if arr[arr_len - 1] < arr[arr_len - 2] and arr[arr_len - 2] < arr[arr_len - 3]: + return True + + +# 判断两根AMA是否金叉 +def is_up_cross(arr1, arr2): + if arr1[len(arr1) - 2] < arr2[len(arr2) - 2] and arr1[len(arr1) - 1] > arr2[len(arr2) - 1]: + return True + +# 判断两根AMA是否死叉 +def is_down_cross(arr1, arr2): + if arr1[len(arr1) - 2] > arr2[len(arr2) - 2] and arr1[len(arr1) - 1] < arr2[len(arr2) - 1]: + return True + + +# 程序主函数 +def onTick(): + exchange.SetContractType("rb000") # 订阅期货品种 + bar_arr = exchange.GetRecords() # 获取K线数组 + if len(bar_arr) < ama_long: # 判断K线数组的长度,如果小于参数ama_long就不能计算AMA,所以直接返回跳过 + return + close_arr = get_close(bar_arr) # 把K线数组转换成收盘价数组,用于计算AMA的值 + np_close_arr = np.array(close_arr) # 把列表转换为numpy.array,用于计算AMA的值 + ama1 = talib.KAMA(np_close_arr, ama_short).tolist() # 计算短期AMA + ama2 = talib.KAMA(np_close_arr, ama_long).tolist() # 计算长期AMA + last_close = close_arr[len(close_arr) - 1] # 获取最新价格(卖价),用于开平仓 + global mp # 全局变量,用于控制虚拟持仓 + + # 开多单 + if mp == 0 and is_up_cross(ama1, ama2) and is_up(ama1): + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(last_close, 1) # 开多单 + mp = 1 # 设置虚拟持仓的值,即有多单 + + # 开空单 + if mp == 0 and is_down_cross(ama1, ama2) and is_down(ama1): + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(last_close - 1, 1) # 开空单 + mp = -1 # 设置虚拟持仓的值,即有空单 + + # 平多单 + if mp == 1 and (is_down_cross(ama1, ama2) or is_down(ama1)): + exchange.SetDirection("closebuy") # 设置交易方向和类型 + exchange.Sell(last_close - 1, 1) # 平多单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + # 平空单 + if mp == -1 and (is_up_cross(ama1, ama2) or is_up(ama1)): + exchange.SetDirection("closesell") # 设置交易方向和类型 + exchange.Buy(last_close, 1) # 平空单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + +def main(): + while True: + onTick() + Sleep(1000) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/170551 + +> 更新时间 + +2019-12-28 17:11:31 diff --git "a/8.3 \347\273\217\345\205\270MACD\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/8.3 \347\273\217\345\205\270MACD\344\272\244\346\230\223\347\255\226\347\225\245.md" new file mode 100644 index 00000000..9d1024f4 --- /dev/null +++ "b/8.3 \347\273\217\345\205\270MACD\344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -0,0 +1,106 @@ + +> 策略名称 + +8.3 经典MACD交易策略 + +> 策略作者 + +Hukybo + +> 策略描述 + +# 摘要 +相信做过交易的人对MACD都不陌生,这是一个非常古老的技术指标,它是由查拉尔·阿佩尔(Geral Appel)在上个世纪70年代发明的,全称指数平滑异同移动平均线。本节我们将继续重温经典技术分析工具MACD,深度解析每一个计算步骤,以及如何用Python和talib库去实现它,并根据MACD比较常用的使用方法来构建策略。 + +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4503) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|short|5|short| +|long|50|long| +|m|15|m| + + +> 源码 (python) + +``` python +# 回测配置 +'''backtest +start: 2015-02-22 00:00:00 +end: 2019-10-17 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' + + +mp = 0 # 定义一个全局变量,用于控制虚拟持仓 + + +# 判断两根两个数组是否金叉 +def is_up_cross(arr1, arr2): + if arr1[len(arr1) - 2] < arr2[len(arr2) - 2] and arr1[len(arr1) - 1] > arr2[len(arr2) - 1]: + return True + +# 判断两根两个数组是否死叉 +def is_down_cross(arr1, arr2): + if arr1[len(arr1) - 2] > arr2[len(arr2) - 2] and arr1[len(arr1) - 1] < arr2[len(arr2) - 1]: + return True + + +# 程序主函数 +def onTick(): + exchange.SetContractType("rb000") # 订阅期货品种 + bar_arr = exchange.GetRecords() # 获取K线数组 + if len(bar_arr) < long + m + 1: # 如果K线数组长度太小,就不能计算MACD,所以直接返回跳过 + return + all_macd = TA.MACD(bar_arr, short, long, m) # 计算MACD值,返回的是一个二维数组 + dif = all_macd[0] # 获取DIF的值,返回一个数组 + dif.pop() # 删除DIF数组最后一个元素 + dea = all_macd[1] # 获取DEA的值,返回一个数组 + dea.pop() # 删除DEA数组最后一个元素 + last_close = bar_arr[len(bar_arr) - 1]['Close'] # 获取最新价格(卖价),用于开平仓 + global mp # 全局变量,用于控制虚拟持仓 + + # 开多单 + if mp == 0 and dif[len(dif) - 1] > 0: + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(last_close, 1) # 开多单 + mp = 1 # 设置虚拟持仓的值,即有多单 + + # 开空单 + if mp == 0 and dif[len(dif) - 1] < 0: + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(last_close - 1, 1) # 开空单 + mp = -1 # 设置虚拟持仓的值,即有空单 + + # 平多单 + if mp == 1 and is_down_cross(dif, dea): + exchange.SetDirection("closebuy") # 设置交易方向和类型 + exchange.Sell(last_close - 1, 1) # 平多单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + # 平空单 + if mp == -1 and is_up_cross(dif, dea): + exchange.SetDirection("closesell") # 设置交易方向和类型 + exchange.Buy(last_close, 1) # 平空单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + +def main(): + while True: + onTick() + Sleep(1000) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/171604 + +> 更新时间 + +2019-12-28 17:11:46 diff --git "a/8.4 \345\212\250\346\200\201\351\230\266\346\242\257\347\252\201\347\240\264\347\255\226\347\225\245.md" "b/8.4 \345\212\250\346\200\201\351\230\266\346\242\257\347\252\201\347\240\264\347\255\226\347\225\245.md" new file mode 100644 index 00000000..6d4818b3 --- /dev/null +++ "b/8.4 \345\212\250\346\200\201\351\230\266\346\242\257\347\252\201\347\240\264\347\255\226\347\225\245.md" @@ -0,0 +1,104 @@ + +> 策略名称 + +8.4 动态阶梯突破策略 + +> 策略作者 + +Hukybo + +> 策略描述 + +# 摘要 +在量化投资领域,突破策略是技术分析中很重要的一部份,它的观念在于市场价格穿透了之前的价格压力或支撑,继而形成一股新的趋势,我们的目标就是在突破发生时能够确认并建立部位以获取趋势的利润。 + +通道策略有他的弹性,可顺可逆。把通道缩窄一点,就可以做顺势;或是把通道拉宽一点,就可以做逆势,或是再搭配其他指标写成其他的交易策略等。可以发现其实通道无所不在,只是通道的取法各有不同罢了。 + +换个角度来看,我们都只是在寻找两条线,支撑跟压力线来决定进场作多或作空,通道的上限与下限即是这种概念。总之,对量化交易而言,不管是什么策略,可以赚钱就是好策略! + +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4549) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|cycle_length|50|cycle_length| + + +> 源码 (python) + +``` python +'''backtest +start: 2015-02-22 00:00:00 +end: 2019-10-29 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' + + +# 外部参数 +cycle_length = 100 + + +# 定义全局变量 +up_line = 0 # 上轨 +under_line = 0 # 下轨 +mp = 0 # 用于控制虚拟持仓 + + +def onTick(): + exchange.SetContractType("rb000") # 订阅期货品种 + bars = exchange.GetRecords() # 获取K线数组 + if len(bars) < cycle_length + 1: # 如果K线数组的长度太小,所以直接返回 + return + close0 = bars[len(bars) - 1].Close; # 获取当根K线收盘价 + high0 = bars[len(bars) - 1].High; # 获取当根K线最高价 + high1 = bars[len(bars) - 2].High; # 获取上根K线最高价 + low0 = bars[len(bars) - 1].Low; # 获取当根K线最低价 + low1 = bars[len(bars) - 2].Low; # 获取上根K线最低价 + highs = TA.Highest(bars, cycle_length, 'High'); # 获取前cycle_length根K线最高价的最高价 + lows = TA.Lowest(bars, cycle_length, 'Low'); # 获取前cycle_length根K线最低价的最低价 + global up_line, under_line, mp # 使用全局变量 + if high0 > high1: # 如果当根K线最高价大于上根K线最高价 + under_line = lows # 把下轨重新赋值为:前cycle_length根K线最低价的最低价 + if low0 < low1: # 如果当根K线最低价小于上根K线最低价 + up_line = highs # 把上轨重新赋值为:前cycle_length根K线最高价的最高价 + middle_line = (lows + highs) / 2; # 计算中轨的值 + + if mp == 0 and close0 > up_line: # 如果当前空仓,并且最新价大于上轨 + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(close0, 1) # 开多单 + mp = 1 # 设置虚拟持仓的值,即有多单 + + if mp == 0 and close0 < under_line: # 如果当前空仓,并且最新价小于下轨 + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(close0 - 1, 1) # 开空单 + mp = -1 # 设置虚拟持仓的值,即有空单 + + if mp > 0 and close0 < middle_line: # 如果当前持有多单,并且最新价小于中轨 + exchange.SetDirection("closebuy") # 设置交易方向和类型 + exchange.Sell(close0 - 1, 1) # 平多单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + if mp < 0 and close0 > middle_line: # 如果当前持有空单,并且最新价大于中轨 + exchange.SetDirection("closesell") # 设置交易方向和类型 + exchange.Buy(close0, 1) # 平空单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + +def main(): + while True: + onTick() + Sleep(1000) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/172610 + +> 更新时间 + +2019-12-28 17:12:07 diff --git "a/8.5 AROON\351\230\277\351\232\206\346\214\207\346\240\207\347\255\226\347\225\245.md" "b/8.5 AROON\351\230\277\351\232\206\346\214\207\346\240\207\347\255\226\347\225\245.md" new file mode 100644 index 00000000..3cf5670b --- /dev/null +++ "b/8.5 AROON\351\230\277\351\232\206\346\214\207\346\240\207\347\255\226\347\225\245.md" @@ -0,0 +1,105 @@ + +> 策略名称 + +8.5 AROON阿隆指标策略 + +> 策略作者 + +Hukybo + +> 策略描述 + +# 摘要 +在技术分析中阿隆(Aroon)是一个很独特的技术指标,“Aroon”一词来自梵文,寓意为“黎明曙光”。它不像MA、MACD、KDJ那样广为人所熟悉,它推出的时间更晚,直到1995年才被图莎尔·钱德(Tushar Chande)发明出来,作者还发明了钱德动量摆动指标(CMO)和日内动量指数(IMI)。如果说一个技术指标知道的人越多,使用的人也越多,那么其赚钱能力也越低,那么相对新颖的阿隆指标则恰恰相反,站在这个角度看这是一个不错的选择。 + +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4601) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|cycle_length|20|cycle_length| + + +> 源码 (python) + +``` python +'''backtest +start: 2015-02-22 00:00:00 +end: 2019-10-29 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' + + +import talib +import numpy as np + + +# 外部参数 +# cycle_length = 100 + + +# 定义全局变量 +mp = 0 # 用于控制虚拟持仓 + + +# 把K线数组转换成最高价和最低价数组,用于转换为numpy.array类型数据 +def get_data(bars): + arr = [[], []] + for i in bars: + arr[0].append(i['High']) + arr[1].append(i['Low']) + return arr + + +# 策略主函数 +def onTick(): + exchange.SetContractType("ZC000") # 订阅期货品种 + bars = exchange.GetRecords() # 获取K线数组 + if len(bars) < cycle_length + 1: # 如果K线数组的长度太小,所以直接返回 + return + np_arr = np.array(get_data(bars)) # 把列表转换为numpy.array类型数据,用于计算AROON的值 + aroon = talib.AROON(np_arr[0], np_arr[1], 20); # 计算阿隆指标 + aroon_up = aroon[1][len(aroon[1]) - 2]; # 阿隆指标上线倒数第2根数据 + aroon_down = aroon[0][len(aroon[0]) - 2]; # 阿隆指标下线倒数第2根数据 + close0 = bars[len(bars) - 1].Close; # 获取当根K线收盘价 + global mp # 全局变量,用于控制虚拟仓位 + if mp == 0 and aroon_up > aroon_down and aroon_up > 50: # 如果当前空仓,并且阿隆上线大于下线,并且阿隆上线大于50 + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(close0, 1) # 开多单 + mp = 1 # 设置虚拟持仓的值,即有多单 + + if mp == 0 and aroon_down > aroon_up and aroon_down > 50: # 如果当前空仓,并且阿隆下线大于上线,并且阿隆下线小于50 + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(close0 - 1, 1) # 开空单 + mp = -1 # 设置虚拟持仓的值,即有空单 + + if mp > 0 and (aroon_up < aroon_down or aroon_up < 50): # 如果当前持有多单,并且阿隆上线小于下线或者阿隆上线小于50 + exchange.SetDirection("closebuy") # 设置交易方向和类型 + exchange.Sell(close0 - 1, 1) # 平多单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + if mp < 0 and (aroon_down < aroon_up or aroon_down < 50): # 如果当前持有空单,并且阿隆下线小于上线或者阿隆下线小于50 + exchange.SetDirection("closesell") # 设置交易方向和类型 + exchange.Buy(close0, 1) # 平空单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + +# 程序入口 +def main(): + while True: # 进入无限循环模式 + onTick() # 执行策略主函数 + Sleep(1000) # 休眠1秒 + +``` + +> 策略出处 + +https://www.fmz.com/strategy/173417 + +> 更新时间 + +2019-12-28 17:12:17 diff --git "a/8.6 \344\275\277\347\224\250DMI\350\276\205\345\212\251MACD\347\255\226\347\225\245.md" "b/8.6 \344\275\277\347\224\250DMI\350\276\205\345\212\251MACD\347\255\226\347\225\245.md" new file mode 100644 index 00000000..72c5b961 --- /dev/null +++ "b/8.6 \344\275\277\347\224\250DMI\350\276\205\345\212\251MACD\347\255\226\347\225\245.md" @@ -0,0 +1,126 @@ + +> 策略名称 + +8.6 使用DMI辅助MACD策略 + +> 策略作者 + +Hukybo + +> 策略描述 + +# 摘要 +“趋势是你的朋友”这是每一个交易者都耳熟能详的箴言。但做过交易的朋友可能会有体会,趋势总是在毫无预警地开始并突然结束。那么在CTA策略中,如何抓住趋势并过滤震荡行情,是许多主观和量化交易者孜孜不倦的追求。在本节课程中,我们将以平均趋向指数(ADX)为滤网,分析在它量化交易中的应用。 + +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4645) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|short|5|short| +|long|50|long| +|m|15|m| + + +> 源码 (python) + +``` python +# 回测配置 +'''backtest +start: 2015-02-22 00:00:00 +end: 2019-10-17 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' + +# 导入库 +import talib +import numpy as np + + +mp = 0 # 定义一个全局变量,用于控制虚拟持仓 + + +# 把K线数组转换成最高价、最低价、收盘价数组,用于转换为numpy.array类型数据 +def get_data(bars): + arr = [[], [], []] + for i in bars: + arr[0].append(i['High']) + arr[1].append(i['Low']) + arr[2].append(i['Close']) + return arr + + +# 判断两根两个数组是否金叉 +def is_up_cross(arr1, arr2): + if arr1[len(arr1) - 2] < arr2[len(arr2) - 2] and arr1[len(arr1) - 1] > arr2[len(arr2) - 1]: + return True + +# 判断两根两个数组是否死叉 +def is_down_cross(arr1, arr2): + if arr1[len(arr1) - 2] > arr2[len(arr2) - 2] and arr1[len(arr1) - 1] < arr2[len(arr2) - 1]: + return True + + +# 程序主函数 +def onTick(): + exchange.SetContractType("rb000") # 订阅期货品种 + bar_arr = exchange.GetRecords() # 获取K线数组 + if len(bar_arr) < long + m + 1: # 如果K线数组长度太小,就不能计算MACD,所以直接返回跳过 + return + all_macd = TA.MACD(bar_arr, short, long, m) # 计算MACD值,返回的是一个二维数组 + dif = all_macd[0] # 获取DIF的值,返回一个数组 + dif.pop() # 删除DIF数组最后一个元素 + dea = all_macd[1] # 获取DEA的值,返回一个数组 + dea.pop() # 删除DEA数组最后一个元素 + + np_arr = np.array(get_data(bar_arr)) # 把列表转换为numpy.array类型数据,用于计算ADX的值 + adx_arr = talib.ADX(np_arr[0], np_arr[1], np_arr[2], 14); # 计算ADX的值 + adx1 = adx_arr[len(adx_arr) - 2] # 倒数第二根K线的ADX值 + adx2 = adx_arr[len(adx_arr) - 3] # 倒数第三根K线的ADX值 + + last_close = bar_arr[len(bar_arr) - 1]['Close'] # 获取最新价格(卖价),用于开平仓 + global mp # 全局变量,用于控制虚拟持仓 + + # 开多单 + if mp == 0 and dif[len(dif) - 1] > 0 and adx1 > 45: + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(last_close, 1) # 开多单 + mp = 1 # 设置虚拟持仓的值,即有多单 + + # 开空单 + if mp == 0 and dif[len(dif) - 1] < 0 and adx1 > 45: + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(last_close - 1, 1) # 开空单 + mp = -1 # 设置虚拟持仓的值,即有空单 + + # 平多单 + if mp == 1 and (is_down_cross(dif, dea) or adx1 < adx2): + exchange.SetDirection("closebuy") # 设置交易方向和类型 + exchange.Sell(last_close - 1, 1) # 平多单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + # 平空单 + if mp == -1 and (is_up_cross(dif, dea) or adx1 < adx2): + exchange.SetDirection("closesell") # 设置交易方向和类型 + exchange.Buy(last_close, 1) # 平空单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + +def main(): + while True: + onTick() + Sleep(1000) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/174672 + +> 更新时间 + +2019-12-28 17:12:33 diff --git "a/8.7 \346\227\245\345\206\205\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\347\255\226\347\225\245.md" "b/8.7 \346\227\245\345\206\205\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\347\255\226\347\225\245.md" new file mode 100644 index 00000000..bea3e7c1 --- /dev/null +++ "b/8.7 \346\227\245\345\206\205\351\253\230\344\275\216\347\202\271\347\252\201\347\240\264\347\255\226\347\225\245.md" @@ -0,0 +1,113 @@ + +> 策略名称 + +8.7 日内高低点突破策略 + +> 策略作者 + +Hukybo + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|up|true|up| +|down|true|down| + + +> 源码 (python) + +``` python +# 回测配置 +'''backtest +start: 2015-02-22 00:00:00 +end: 2019-10-17 00:00:00 +period: 5m +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' + +# 导入库 +import time + + +# 定义全局变量 +mp = 0 # 用于控制虚拟持仓 +on_line = 0 # 上轨 +under_line = 0 # 下轨 + + +def onTick(): + # 处理时间函数 + def can_time(hour, minute): + hour = str(hour) + minute = str(minute) + if len(minute) == 1: + minute = "0" + minute + return int(hour + minute) + + exchange.SetContractType("MA888") # 订阅期货品种 + bar_arr = exchange.GetRecords() # 获取K线数组 + time_new = bar_arr[len(bar_arr) - 1]['Time'] # 获取当根K线的时间戳 + time_local_new = time.localtime(time_new / 1000) # 处理时间戳 + hour_new = int(time.strftime("%H", time_local_new)) # 格式化时间戳,并获取小时 + minute_new = int(time.strftime("%M", time_local_new)) # 格式化时间戳,并获取分钟 + day_new = int(time.strftime("%d", time_local_new)) # 格式化时间戳,并获取日期 + time_previous = bar_arr[len(bar_arr) - 2]['Time'] # 获取上根K线的时间戳 + time_local_previous = time.localtime(time_previous / 1000) # 处理时间戳 + day_previous = int(time.strftime("%d", time_local_previous)) # 格式化时间戳,并获取日期 + + global mp, on_line, under_line # 引入全局变量 + high = bar_arr[len(bar_arr) - 2]['High'] # 获取上根K线的最高价 + low = bar_arr[len(bar_arr) - 2]['Low'] # 获取上根K线的最低价 + if day_new != day_previous or len(bar_arr) == 1: # 如果当前是第一个K线,或者是最新一根K线 + on_line = high * up # 重置上轨 + under_line = low * down # 重置下轨 + if can_time(hour_new, minute_new) < 930: # 如果不是在规定交易的时间内 + if high > on_line: # 如果上根K线最高价大于上轨 + on_line = high * up # 重置上轨 + elif low < under_line: # 如果上根K线最低价小于下轨 + under_line = low * down # 重置上轨 + + close_new = bar_arr[len(bar_arr) - 1]['Close'] # 获取最新价格(卖价),用于开平仓 + if mp == 0 and 930 < can_time(hour_new, minute_new) < 1450: # 如果当前无持仓,并且在规定的交易时间内 + if close_new > on_line: # 如果价格大于上轨 + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(close_new, 1) # 开多单 + mp = 1 # 设置虚拟持仓的值,即有多单 + elif close_new < under_line: # 如果价格小于下轨 + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(close_new - 1, 1) # 开空单 + mp = -1 # 设置虚拟持仓的值,即有空单 + + # 如果持多单,并且价格小于下轨或者非规定的交易时间 + if mp > 0 and (close_new < under_line or can_time(hour_new, minute_new) > 1450): + exchange.SetDirection("closebuy") # 设置交易方向和类型 + exchange.Sell(close_new - 1, 1) # 平多单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + # 如果持空单,并且价格大于上轨或者非规定的交易时间 + if mp < 0 and (high > on_line or can_time(hour_new, minute_new) > 1450): + exchange.SetDirection("closesell") # 设置交易方向和类型 + exchange.Buy(close_new, 1) # 平空单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + +# 程序入口 +def main(): + while True: + onTick() + Sleep(1000) #休眠1秒 + +``` + +> 策略出处 + +https://www.fmz.com/strategy/175316 + +> 更新时间 + +2019-12-28 17:12:49 diff --git "a/8.8 \345\242\236\345\274\272\347\211\210\345\224\220\345\245\207\345\256\211\351\200\232\351\201\223\347\255\226\347\225\245.md" "b/8.8 \345\242\236\345\274\272\347\211\210\345\224\220\345\245\207\345\256\211\351\200\232\351\201\223\347\255\226\347\225\245.md" new file mode 100644 index 00000000..66ac6c7a --- /dev/null +++ "b/8.8 \345\242\236\345\274\272\347\211\210\345\224\220\345\245\207\345\256\211\351\200\232\351\201\223\347\255\226\347\225\245.md" @@ -0,0 +1,101 @@ + +> 策略名称 + +8.8 增强版唐奇安通道策略 + +> 策略作者 + +Hukybo + +> 策略描述 + +# 前言 +提起唐奇安通道,很多人都会联想到海龟交易法则,这也许是有史以来最成功的交易员培训课程。海龟们用神奇的交易系统赚了成百上千万美元,直到1983年海龟交易法则解密,人们才发现这个神奇的交易系统用的是修正版的唐奇安通道。但时过境迁,现在的市场环境已经发生了很大的变化,这导致唐奇安通道策略变得低效,那么今天我们试着改进,看看增强版的唐奇安通道策略效果如何。 +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4723) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|long_coefficient|0.999|多头系数| +|short_coefficient|1.001|空头系数| +|cycle_length|55|周期长度| + + +> 源码 (python) + +``` python +# 回测配置 +'''backtest +start: 2015-02-22 00:00:00 +end: 2019-11-27 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' + + +# 定义全局变量 +mp = 0 # 用于控制虚拟持仓 + + +# 外部参数 +long_coefficient = 0.999 +short_coefficient = 1.001 +cycle_length = 55 + + +def onTick(): + exchange.SetContractType("rb000") # 订阅期货品种 + bar_arr = exchange.GetRecords() # 获取K线数组 + if len(bar_arr) < cycle_length + 1: + return + close_new = bar_arr[len(bar_arr) - 1]['Close'] # 获取最新价格(卖价),用于开平仓 + close_last = bar_arr[len(bar_arr) - 2]['Close'] # 上根K线收盘价 + bar_arr.pop() + on_line = TA.Highest(bar_arr, cycle_length, 'High') * long_coefficient + under_line = TA.Lowest(bar_arr, cycle_length, 'Low') * short_coefficient + middle_line = (on_line + under_line) / 2 + + global mp # 引入全局变量 + + if mp == 0: # 如果当前无持仓 + if close_last > on_line: # 如果价格大于上轨 + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(close_new, 1) # 开多单 + mp = 1 # 设置虚拟持仓的值,即有多单 + elif close_last < under_line: # 如果价格小于下轨 + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(close_new - 1, 1) # 开空单 + mp = -1 # 设置虚拟持仓的值,即有空单 + + # 如果持多单,并且价格小于下轨 + if mp > 0 and close_last < middle_line: + exchange.SetDirection("closebuy") # 设置交易方向和类型 + exchange.Sell(close_new - 1, 1) # 平多单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + # 如果持空单,并且价格大于上轨 + if mp < 0 and close_last > middle_line: + exchange.SetDirection("closesell") # 设置交易方向和类型 + exchange.Buy(close_new, 1) # 平空单 + mp = 0 # 设置虚拟持仓的值,即空仓 + LogStatus(mp) + + +# 程序入口 +def main(): + while True: + onTick() + Sleep(1000) #休眠1秒 + +``` + +> 策略出处 + +https://www.fmz.com/strategy/176458 + +> 更新时间 + +2019-12-28 17:13:03 diff --git "a/8.9 Dual Thrust \345\214\272\351\227\264\347\252\201\347\240\264\347\255\226\347\225\245 Python \347\211\210.md" "b/8.9 Dual Thrust \345\214\272\351\227\264\347\252\201\347\240\264\347\255\226\347\225\245 Python \347\211\210.md" new file mode 100644 index 00000000..2feb5c63 --- /dev/null +++ "b/8.9 Dual Thrust \345\214\272\351\227\264\347\252\201\347\240\264\347\255\226\347\225\245 Python \347\211\210.md" @@ -0,0 +1,105 @@ + +> 策略名称 + +8.9 Dual Thrust 区间突破策略 Python 版 + +> 策略作者 + +Hukybo + +> 策略描述 + +# 前言 +Dual Thrust直译为“双重推力”,是上个世纪80年代由Michael Chalek开发的一个交易策略,曾经在期货市场风靡一时。由于策略本身思路简单,参数很少,因此可以适应于很多金融市场,正是因为简单易用和普适性高的特点,得到了广大交易者的认可流传至今。 +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4757) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Cycle|5|周期| +|Ks|true|Ks| +|Kx|2|Kx| +|FuturesCode|rb000|期货代码| + + +> 源码 (python) + +``` python +# 回测配置 +'''backtest +start: 2015-02-22 00:00:00 +end: 2019-12-06 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' + + +# 定义全局变量 +mp = 0 # 用于控制虚拟持仓 +last_bar_time = 0 # 用于判断K线时间 +up_line = 0 # 上轨 +down_line = 0 # 下轨 + + +''' +# 外部参数 +Cycle = 5 # 周期 +Ks = 1 # 多头系数 +Kx = 2 # 空头系数 +''' + + +# 策略主函数 +def onTick(): + global mp, last_bar_time, up_line, down_line # 引入全局变量 + exchange.SetContractType(FuturesCode) # 订阅期货品种 + bar_arr = exchange.GetRecords() # 获取K线数组 + if not bar_arr or len(bar_arr) < Cycle: + return # 如果没有获取到K线数据或者K线数据太短就返回 + last_bar = bar_arr[len(bar_arr) - 1] # 最新的K线 + last_bar_close = last_bar['Close'] # 最新K线的收盘价 + if last_bar_time != last_bar['Time']: # 如果产生了新的K线 + hh = TA.Highest(bar_arr, Cycle, 'High') # 最高价 + hc = TA.Highest(bar_arr, Cycle, 'Close') # 最高的收盘价 + ll = TA.Lowest(bar_arr, Cycle, 'Low') # 最低价 + lc = TA.Lowest(bar_arr, Cycle, 'Close') # 最低的收盘价 + Range = max(hh - lc, hc - ll) # 计算范围 + up_line = _N(last_bar['Open'] + Ks * Range) # 计算上轨 + down_line = _N(last_bar['Open'] - Kx * Range) # 计算下轨 + last_bar_time = last_bar['Time'] # 更新最后时间戳 + if mp == 0 and last_bar_close >= up_line: + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(last_bar_close, 1) # 开多单 + mp = 1 # 设置虚拟持仓的值,即有多单 + if mp == 0 and last_bar_close <= down_line: + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(last_bar_close - 1, 1) # 开空单 + mp = -1 # 设置虚拟持仓的值,即有空单 + if mp == 1 and last_bar_close <= down_line: + exchange.SetDirection("closebuy") # 设置交易方向和类型 + exchange.Sell(last_bar_close - 1, 1) # 平多单 + mp = 0 # 设置虚拟持仓的值,即空仓 + if mp == -1 and last_bar_close >= up_line: + exchange.SetDirection("closesell") # 设置交易方向和类型 + exchange.Buy(last_bar_close, 1) # 平空单 + mp = 0 # 设置虚拟持仓的值,即空仓 + + +# 程序入口 +def main(): + while True: # 进入循环模式 + onTick() # 执行策略主函数 + Sleep(1000) # 休眠1秒 + +``` + +> 策略出处 + +https://www.fmz.com/strategy/177504 + +> 更新时间 + +2019-12-28 17:13:23 diff --git "a/Binance buy and sell statistics|\345\270\201\345\256\211\344\271\260\345\215\226\347\273\237\350\256\241.md" "b/Binance buy and sell statistics|\345\270\201\345\256\211\344\271\260\345\215\226\347\273\237\350\256\241.md" index e4a98338..76033de3 100644 --- "a/Binance buy and sell statistics|\345\270\201\345\256\211\344\271\260\345\215\226\347\273\237\350\256\241.md" +++ "b/Binance buy and sell statistics|\345\270\201\345\256\211\344\271\260\345\215\226\347\273\237\350\256\241.md" @@ -5,7 +5,7 @@ Binance buy and sell statistics|币安买卖统计 > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/Bitmex\344\273\223\344\275\215\345\217\230\345\214\226\346\216\250\351\200\201\345\276\256\344\277\241\357\274\210wss\345\215\217\350\256\256,\351\234\200\350\246\201bitmex api ID\357\274\211|Bitmex position-change push(websocket).md" "b/Bitmex\344\273\223\344\275\215\345\217\230\345\214\226\346\216\250\351\200\201\345\276\256\344\277\241\357\274\210wss\345\215\217\350\256\256,\351\234\200\350\246\201bitmex api ID\357\274\211|Bitmex position-change push(websocket).md" index 7f88f9ea..fc29df57 100644 --- "a/Bitmex\344\273\223\344\275\215\345\217\230\345\214\226\346\216\250\351\200\201\345\276\256\344\277\241\357\274\210wss\345\215\217\350\256\256,\351\234\200\350\246\201bitmex api ID\357\274\211|Bitmex position-change push(websocket).md" +++ "b/Bitmex\344\273\223\344\275\215\345\217\230\345\214\226\346\216\250\351\200\201\345\276\256\344\277\241\357\274\210wss\345\215\217\350\256\256,\351\234\200\350\246\201bitmex api ID\357\274\211|Bitmex position-change push(websocket).md" @@ -5,7 +5,7 @@ Bitmex仓位变化推送微信(wss协议,需要bitmex api ID)|Bitmex positio > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/C++\345\225\206\345\223\201\346\234\237\350\264\247\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213Penny Jump.md" "b/C++\345\225\206\345\223\201\346\234\237\350\264\247\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213Penny Jump.md" deleted file mode 100644 index f4eba767..00000000 --- "a/C++\345\225\206\345\223\201\346\234\237\350\264\247\351\253\230\351\242\221\344\272\244\346\230\223\347\255\226\347\225\245\344\271\213Penny Jump.md" +++ /dev/null @@ -1,346 +0,0 @@ - -> 策略名称 - -C++商品期货高频交易策略之Penny Jump - -> 策略作者 - -Zero - -> 策略描述 - -> 高频交易分类 - -* 以最快的速度抹平市场的一切不合理现象, 常见于炒单与高频套利, 主动出击, 拼速度 -* 提前在不合理的价位埋伏并跟随市场快速移动, 常见于市商策略, 守株待兔, 拼知识面 -* 其它各种作者只学习了理论没有实盘, 先不讲 - -> 动手实现 - -* 观察盘口的概率极低的不合理现像并做出相应策略进行测试更改 -* 如果逻辑复杂, 就需要利用现有的数学知识尽可能的用模型描述不合理现象的本质, 尽量减少拟合 -* 必须用可以见量成交又可以见价成交的回测模型去验证, 发明者量化目前是唯一支持这两种回测模式的平台 -* 平台的C++例子很少, 这里就用C++写本策略, 方便大家学习 - -> 策略原理 - - 正常情况下商品期货的盘口买一卖一差价只有一跳, 偶尔会有两跳,三跳基本很少见, 主力合约交易比较频繁, 这种现像发生后瞬间消失, 难以有下手机会, 我们就把精力放到次主力合约上面,比如MA001为主力, MA909为次主力时, MA909盘口下面这种情况 - - ![IMG](https://www.fmz.com/upload/asset/10c6ef53263999aec8e.png) - - 卖一为2225量551, 买一2223量565, 向下看几秒, 出现这种情况后, 几个tick推送后消失, 这种情况,我们视为市场的自我纠正, 我们要做的就是赶在市场主动纠正前, 杀进去, 这种逻辑看人工去盯盘是天方夜谈, 因为商品期货盘口差价两跳的情况级少出现, 三跳最安全, 但三跳极少出现, 导致交易频率太低, 意义不大, 接下来, 我们观察盘口之前卖一买一与现在两跳时买一卖一的区别, 去填补盘口差价空隙, 如果速度够快, 就可以排在委托单的最前位置, 做为Maker以最快的速度成交后反手卖出, 持仓时间很短, 有了这个交易逻辑, 实现为策略以后, 以MA909为例, 实盘测试推荐易盛而非CTP接口, 易盛仓位与资金变化是推送机制, 非常适合高频 - -> 回测结果 - - ![IMG](https://www.fmz.com/upload/asset/1209a7f1c3125148a76.png) - -> 交易逻辑 - - ![IMG](https://www.fmz.com/upload/asset/e2afad523b119c9a23.png) - -> 必看声明 - -为满足对高频交易的好奇心, 为了更明显的看到结果, 此策略回测手续费设定为0, 实现了一个简单的拼速度逻辑, 想要覆盖手续费实现盈利, 实盘需做更多优化, 仅凭这个简单的逻辑很难致胜, 要考虑更多操作, 比如锁仓(降低平今手续费), 利用定单薄流进行短期预测提高胜率, 再加上交易所手续费返还, 从而实现一个可持久盈利的策略, 关于高频交易的书籍很多, 希望大家多去思考,多去实盘,而不是只停留在原理上. - -> 关于我们 - - 发明者量化是一个纯技术驱动的团队, 为量化交易爱好者提供了一个高可用的回测机制, 我们的回测机制是真实的模拟了一个交易所的存在, 而不是简单的见价撮合, 希望用户能够利用到平台的优点更好的去发挥自己的能力 - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|Symbol|MA909|品种| -|RetryMax|true|重试最多| -|ProfitTick|true|利润跳数| -|TolerateTick|5|容忍跳数| - - -> 源码 (cpp) - -``` cpp -/*backtest -start: 2019-08-19 09:00:00 -end: 2019-08-23 15:00:00 -period: 1d -exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","balance":10000,"minfee":0,"fee":[0,0]}] -mode: 1 -*/ - -enum State { - STATE_NA, - STATE_IDLE, - STATE_HOLD_LONG, - STATE_HOLD_SHORT, -}; - -typedef struct { - double bidPrice; - double bidAmount; - double askPrice; - double askAmount; -} Book; - -class HFT { - public: - HFT() { - _tradingDay = getTradingWeekDay(); - Log("current trading weekday", _tradingDay); - } - int getTradingWeekDay() { - int seconds = Unix() + 28800; - int hour = (seconds/3600)%24; - int weekDay = (seconds/(60*60*24))%7+4; - if (hour > 20) { - weekDay += 1; - } - return weekDay; - } - State getState() { - auto orders = exchange.GetOrders(); - if (!orders.Valid || orders.size() == 2) { - return STATE_NA; - } - - bool foundCover = false; - for (auto &order : orders) { - if (order.Id == _coverId) { - if ((order.Type == ORDER_TYPE_BUY && order.Price < _book.bidPrice - _toleratePrice) || - (order.Type == ORDER_TYPE_SELL && order.Price > _book.askPrice + _toleratePrice)) { - exchange.CancelOrder(order.Id, "Cancel Cover Order"); - _countCancel++; - _countRetry++; - } else { - foundCover = true; - } - } else { - exchange.CancelOrder(order.Id); - _countCancel++; - } - } - - if (foundCover) { - return STATE_NA; - } - - auto positions = exchange.GetPosition(); - if (!positions.Valid) { - return STATE_NA; - } - - for (auto &pos : positions) { - if (pos.ContractType == Symbol) { - _holdPrice = pos.Price; - _holdAmount = pos.Amount; - _holdType = pos.Type; - return pos.Type == PD_LONG || pos.Type == PD_LONG_YD ? STATE_HOLD_LONG : STATE_HOLD_SHORT; - } - } - return STATE_IDLE; - } - - void stop() { - Log(exchange.GetOrders()); - Log(exchange.GetPosition()); - Log("Stop"); - } - - bool Loop() { - if (exchange.IO("status") == 0) { - LogStatus(_D(), "Server not connect ...."); - Sleep(1000); - return true; - } - if (_initBalance == 0) { - _initBalance = _C(exchange.GetAccount).Balance; - } - auto day = getTradingWeekDay(); - if (day != _tradingDay) { - _tradingDay = day; - _countCancel = 0; - } - - if (_ct.is_null()) { - Log(_D(), "subscribe", Symbol); - _ct = exchange.SetContractType(Symbol); - if (!_ct.is_null()) { - auto obj = _ct["Commodity"]["CommodityTickSize"]; - int volumeMultiple = 1; - if (obj.is_null()) { // CTP - obj = _ct["PriceTick"]; - volumeMultiple = _ct["VolumeMultiple"]; - _exchangeId = _ct["ExchangeID"]; - } else { // Esunny - volumeMultiple = _ct["Commodity"]["ContractSize"]; - _exchangeId = _ct["Commodity"]["ExchangeNo"]; - } - if (obj.is_null() || obj <= 0) { - Panic("PriceTick not found"); - } - if (_priceTick < 1) { - exchange.SetPrecision(1, 0); - } - _priceTick = double(obj); - _toleratePrice = _priceTick * TolerateTick; - _ins = _ct["InstrumentID"]; - - Log(_ins, _exchangeId, "PriceTick:", _priceTick, "VolumeMultiple:", volumeMultiple); - } - Sleep(1000); - return true; - } - // Check orders and positions to set state - auto depth = exchange.GetDepth(); - if (!depth.Valid) { - LogStatus(_D(), "Market not ready"); - Sleep(1000); - return true; - } - _countTick++; - _preBook = _book; - _book.bidPrice = depth.Bids[0].Price; - _book.bidAmount = depth.Bids[0].Amount; - _book.askPrice = depth.Asks[0].Price; - _book.askAmount = depth.Asks[0].Amount; - // _book not init - if (_preBook.bidAmount == 0) { - return true; - } - auto st = getState(); - - LogStatus(_D(), _ins, "State:", st, - "Ask:", depth.Asks[0].Price, depth.Asks[0].Amount, - "Bid:", depth.Bids[0].Price, depth.Bids[0].Amount, - "Cancel:", _countCancel, - "Tick:", _countTick); - - bool forceCover = _countRetry >= _retryMax; - if (st == STATE_IDLE) { - if (_holdAmount > 0) { - if (_countRetry > 0) { - _countLoss++; - } else { - _countWin++; - } - auto account = exchange.GetAccount(); - if (account.Valid) { - LogProfit(_N(account.Balance+account.FrozenBalance-_initBalance, 2), "Win:", _countWin, "Loss:", _countLoss); - } - } - _countRetry = 0; - _holdAmount = 0; - - if (_countCancel > _cancelMax) { - Log("Cancel Exceed", _countCancel); - return false; - } - - bool canDo = false; - if (abs(_book.bidPrice - _book.askPrice) > _priceTick * 1) { - canDo = true; - } - if (!canDo) { - return true; - } - - - auto bidPrice = depth.Bids[0].Price; - auto askPrice = depth.Asks[0].Price; - auto bidAmount = 1.0; - auto askAmount = 1.0; - - if (_preBook.bidPrice > _book.bidPrice && _book.askAmount < _book.bidAmount) { - bidPrice += _priceTick; - bidAmount = 2; - } else if (_preBook.askPrice < _book.askPrice && _book.bidAmount < _book.askAmount) { - askPrice -= _priceTick; - askAmount = 2; - } else { - return true; - } - Log(_book.bidPrice, _book.bidAmount, _book.askPrice, _book.askAmount); - exchange.SetDirection("buy"); - exchange.Buy(bidPrice, bidAmount); - exchange.SetDirection("sell"); - exchange.Sell(askPrice, askAmount); - } else if (st == STATE_HOLD_LONG) { - exchange.SetDirection((_holdType == PD_LONG && _exchangeId == "SHFE") ? "closebuy_today" : "closebuy"); - auto sellPrice = depth.Asks[0].Price; - if (sellPrice > _holdPrice) { - Log(_holdPrice, "Hit #ff0000"); - sellPrice = _holdPrice + ProfitTick; - } else if (sellPrice < _holdPrice) { - forceCover = true; - } - if (forceCover) { - Log("StopLoss"); - } - _coverId = exchange.Sell(forceCover ? depth.Bids[0].Price : sellPrice, _holdAmount); - if (!_coverId.Valid) { - return false; - } - } else if (st == STATE_HOLD_SHORT) { - exchange.SetDirection((_holdType == PD_SHORT && _exchangeId == "SHFE") ? "closesell_today" : "closesell"); - auto buyPrice = depth.Bids[0].Price; - if (buyPrice < _holdPrice) { - Log(_holdPrice, "Hit #ff0000"); - buyPrice = _holdPrice - ProfitTick; - } else if (buyPrice > _holdPrice) { - forceCover = true; - } - if (forceCover) { - Log("StopLoss"); - } - _coverId = exchange.Buy(forceCover ? depth.Asks[0].Price : buyPrice, _holdAmount); - if (!_coverId.Valid) { - return false; - } - } - return true; - } - private: - double _holdPrice = 0; - double _holdAmount = 0; - int _holdType; - int _countTick = 0; - int _countRetry = 0; - int _countCancel = 0; - int _period = 20; - int _tradingDay = 0; - double _initBalance; - const int _retryMax = RetryMax; - const int _cancelMax = 300; - - int _countLoss = 0; - int _countWin = 0; - - json _ct; - string _ins; - string _exchangeId; - double _priceTick; - double _toleratePrice; - Book _book; - Book _preBook; - TId _coverId; -}; - - -void main() { - LogReset(); - SetErrorFilter("ready|timeout"); - Log("Init OK"); - HFT hft; - while (hft.Loop()); - Log("Exit"); -} -``` - -> 策略出处 - -https://www.fmz.com/strategy/163427 - -> 更新时间 - -2019-08-24 12:23:42 diff --git "a/C++\346\234\237\350\264\247\351\253\230\351\242\221\345\245\227\345\270\201\347\255\226\347\225\245OKEX Websocket\347\211\210.md" "b/C++\346\234\237\350\264\247\351\253\230\351\242\221\345\245\227\345\270\201\347\255\226\347\225\245OKEX Websocket\347\211\210.md" new file mode 100644 index 00000000..583d13c1 --- /dev/null +++ "b/C++\346\234\237\350\264\247\351\253\230\351\242\221\345\245\227\345\270\201\347\255\226\347\225\245OKEX Websocket\347\211\210.md" @@ -0,0 +1,670 @@ + +> 策略名称 + +C++期货高频套币策略OKEX Websocket版 + +> 策略作者 + +小小梦 + +> 策略描述 + +## C++期货高频套币策略OKEX Websocket版 + +策略原理 + + 策略原理为非常简单的,OKEX合约跨期对冲,仓位控制设计方面,设计为差价网格对冲。 + 策略定义两个合约,A合约,B合约。可以合约设置不同的合约代码,进行对冲。 + 例如,设置 A 合约为季度合约,B合约为当周合约(也可以设置 A 为近期合约,B为远期合约,其它定义就是相反的)。 + 对冲操作即分为 做空A合约(季度),做多B合约(类似 商品期货中跨期套利的做空远期合约,做多近期合约,进行正套) + 做多A合约,做空B合约(类似商品期货中的做空近期,做多远期,进行反套) + +- ### 设计特点 + + - 代码语言 + 策略编写代码使用C++语言,具有速度快的性能优势。 + + - 行情驱动: + 行情驱动采用OKEX websocket 接口接受交易所推送行情,最新行情获取较为及时,行情数据使用数据量不大的实时tick数据, + 对于行情响应速度有不小提升。对于tick 数据,策略专门构造了一个K线生成器,用来对获取到的tick数据计算后的合约差价,进行K线合成。 + 策略对冲操作的开仓、平仓 均由该K线生成器类对象生成的数据驱动。 + + - 仓位控制 + 仓位控制采用类似 「波菲纳契」数列的对冲仓位比例,进行控制。 + 实现差价越大,套利对冲数量相对增加,对仓位进行分散,从而把握住小差价波动小仓位,大差价波动仓位适当增大。 + + - 平仓:止损止盈 + 固定的止盈差价,止损差价。 + 持仓差价到达止盈位置、止损位置即进行止盈、止损。 + + - 入市、离市 周期设计 + 参数 NPeriod 控制的周期对策略的开仓平仓进行一定的动态控制。 + + - 仓位平衡系统、订单检测系统 + 策略有专门的定期检测 平衡系统。 + 订单检测系统。 + + - 策略扩展 + 策略代码设计耦合度较低,可扩展为商品期货对冲,或者进行进一步优化,修改。 + + - 策略图表 + 策略自动生成差价 K线图表,标记相关交易信息。 + +- ### 回测 + + ![IMG](https://www.fmz.com/upload/asset/165549c612d8ba5ae550.png) + + ![IMG](https://www.fmz.com/upload/asset/168d0e671a56094b28c3.png) + + ![IMG](https://www.fmz.com/upload/asset/170dcc772a1925d46885.png) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|InstrumentA|this_week|近期合约| +|InstrumentB|next_week|远期合约| +|DPeriod|30|差价周期(秒)| +|NPeriod|20|周期| +|LeavePeriod|5|出场周期| +|AddMax|5|加仓次数| +|StopLoss|10|止损差价| +|StopWin|30|止盈差价| +|OpenAmount|10|手数| +|SlidePrice|true|滑价| +|MaxDelay|500|最大行情延迟(毫秒)| +|IsSetProxy|false|(?代理)是否代理设置| +|Proxy||代理设置| + + +> 源码 (cpp) + +``` cpp +/*backtest +start: 2019-07-22 00:00:00 +end: 2019-08-21 00:00:00 +period: 1m +exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD","stocks":0.1,"fee":[0.02,0.05]}] +args: [["InstrumentB","quarter"],["NPeriod",200],["LeavePeriod",100],["AddMax",3],["StopLoss",20],["StopWin",50],["OpenAmount",2]] +*/ + +enum State { + STATE_NA, + STATE_IDLE, + STATE_HOLD_LONG, + STATE_HOLD_SHORT, +}; + +string replace(string s, const string from, const string& to) { + if(!from.empty()) + for(size_t pos = 0; (pos = s.find(from, pos)) != std::string::npos; pos += to.size()) + s.replace(pos, from.size(), to); + return s; +} + +class BarFeeder { + public: + BarFeeder(int period) : _period(period) { + _rs.Valid = true; + } + + void feed(double price, Chart *c=nullptr, int chartIdx=0) { + uint64_t epoch = uint64_t(Unix() / _period) * _period * 1000; + bool newBar = false; + if (_rs.size() == 0 || _rs[_rs.size()-1].Time < epoch) { + Record r; + r.Time = epoch; + r.Open = r.High = r.Low = r.Close = price; + _rs.push_back(r); + if (_rs.size() > 2000) { + _rs.erase(_rs.begin()); + } + newBar = true; + } else { + Record &r = _rs[_rs.size() - 1]; + r.High = max(r.High, price); + r.Low = min(r.Low, price); + r.Close = price; + } + + auto bar = _rs[_rs.size()-1]; + json point = {bar.Time, bar.Open, bar.High, bar.Low, bar.Close}; + if (c != nullptr) { + if (newBar) { + c->add(chartIdx, point); + c->reset(1000); + } else { + c->add(chartIdx, point, -1); + } + } + } + Records & get() { + return _rs; + } + private: + int _period; + Records _rs; +}; + +class Hedge { + public: + Hedge() { + _isCover = true; + _needCheckOrder = true; + _st = STATE_NA; + for (int i = 0; i < AddMax + 1; i++) { + if (_addArr.size() < 2) { + _addArr.push_back((i+1)*OpenAmount); + } + _addArr.push_back(_addArr[_addArr.size()-1] + _addArr[_addArr.size()-2]); + } + _cfgStr = R"EOF( + [{ + "extension": { "layout": "single", "col": 6, "height": "500px"}, + "rangeSelector": {"enabled": false}, + "tooltip": {"xDateFormat": "%Y-%m-%d %H:%M:%S, %A"}, + "plotOptions": {"candlestick": {"color": "#d75442", "upColor": "#6ba583"}}, + "chart":{"type":"line"}, + "title":{"text":"Spread Long"}, + "xAxis":{"title":{"text":"Date"}}, + "series":[ + {"type":"candlestick", "name":"Long Spread","data":[], "id":"dataseriesA"}, + {"type":"flags","data":[], "onSeries": "dataseriesA"} + ] + }, + { + "extension": { "layout": "single", "col": 6, "height": "500px"}, + "rangeSelector": {"enabled": false}, + "tooltip": {"xDateFormat": "%Y-%m-%d %H:%M:%S, %A"}, + "plotOptions": {"candlestick": {"color": "#d75442", "upColor": "#6ba583"}}, + "chart":{"type":"line"}, + "title":{"text":"Spread Short"}, + "xAxis":{"title":{"text":"Date"}}, + "series":[ + {"type":"candlestick", "name":"Long Spread","data":[], "id":"dataseriesA"}, + {"type":"flags","data":[], "onSeries": "dataseriesA"} + ] + } + ] + )EOF"; + _c.update(_cfgStr); + _c.reset(); + }; + + State getState(string &symbolA, Depth &depthA, string &symbolB, Depth &depthB) { + + if (!_needCheckOrder && _st != STATE_NA) { + return _st; + } + + //Log("sync orders"); + auto orders = exchange.GetOrders(); + if (!orders.Valid) { + return STATE_NA; + } + + if (orders.size() > 0) { + for (auto &order : orders) { + exchange.CancelOrder(order.Id); + } + return STATE_NA; + } + + Sleep(500); + + //Log("sync positions"); + + auto positions = exchange.GetPosition(); + if (!positions.Valid) { + return STATE_NA; + } + + // cache orders and positions; + _needCheckOrder = false; + + if (positions.size() == 0) { + //Log("Position is empty"); + return STATE_IDLE; + } + + + State st[2] = {STATE_IDLE, STATE_IDLE}; + double holdAmount[2] = {0, 0}; + double holdPrice[2] = {}; + for (auto &pos : positions) { + int idx = -1; + if (pos.ContractType == symbolA) { + idx = 0; + } else if (pos.ContractType == symbolB) { + idx = 1; + } + if (idx >= 0) { + holdPrice[idx] = pos.Price; + holdAmount[idx] += pos.Amount; + st[idx] = pos.Type == PD_LONG || pos.Type == PD_LONG_YD ? STATE_HOLD_LONG : STATE_HOLD_SHORT; + } + } + + if (holdAmount[0] > holdAmount[1]) { + st[1] = STATE_IDLE; + } else if (holdAmount[0] < holdAmount[1]) { + st[0] = STATE_IDLE; + } + + if (st[0] != STATE_IDLE && st[1] != STATE_IDLE) { + // update + _holdPrice = _N(holdPrice[1] - holdPrice[0], 4); + _holdAmount = holdAmount[0]; + return st[0]; + } else if (st[0] == STATE_IDLE && st[1] == STATE_IDLE) { + return STATE_IDLE; + } else { + double amount = abs(holdAmount[0] - holdAmount[1]); + auto idx_fat = st[0] == STATE_IDLE ? 1 : 0; + if (_isCover) { + exchange.SetContractType(st[0] == STATE_IDLE ? symbolB : symbolA); + if (st[idx_fat] == STATE_HOLD_LONG) { + exchange.SetDirection("closebuy"); + exchange.Sell((st[0] == STATE_IDLE ? depthB.Bids[0].Price: depthA.Bids[0].Price)-SlidePrice, amount); + } else { + exchange.SetDirection("closesell"); + exchange.Buy((st[0] == STATE_IDLE ? depthB.Asks[0].Price : depthA.Asks[0].Price)+SlidePrice, amount); + } + } else { + exchange.SetContractType(st[0] == STATE_IDLE ? symbolA : symbolB); + if (st[idx_fat] == STATE_HOLD_LONG) { + exchange.SetDirection("sell"); + exchange.Sell((st[0] == STATE_IDLE ? depthA.Bids[0].Price : depthB.Bids[0].Price)-SlidePrice, amount); + } else { + exchange.SetDirection("buy"); + exchange.Buy((st[0] == STATE_IDLE ? depthA.Asks[0].Price : depthB.Asks[0].Price)+SlidePrice, amount); + } + } + + _needCheckOrder = true; + + return STATE_NA; + } + Log(positions); + Panic("WTF"); + } + bool Loop(string &symbolA, Depth &depthA, string &symbolB, Depth &depthB, string extra="") { + + _loopCount++; + auto diffLong = _N(depthB.Bids[0].Price - depthA.Asks[0].Price, 4); + auto diffShort = _N(depthB.Asks[0].Price - depthA.Bids[0].Price, 4); + + _feederA.feed(diffLong, &_c, 0); + _feederB.feed(diffShort, &_c, 2); + + auto barsA = _feederA.get(); + auto barsB = _feederB.get(); + + if (barsA.size() < max(LeavePeriod, NPeriod) + 2) { + LogStatus(_D(), "Calc His", barsA.size()); + return true; + } + + bool expired = false; + auto seconds = Unix(); + if (seconds - _lastCache > 600) { + _needCheckOrder = true; + expired = true; + } + + State st = getState(symbolA, depthA, symbolB, depthB); + if (st == STATE_NA) { + return true; + } + if (st == STATE_IDLE) { + _holdPrice = 0; + } + // cache st + _st = st; + if (expired) { + _lastCache = seconds; + } + + if (Unix() - seconds > 5) { + Log("skip this tick"); + return true; + } + + + LogStatus(_D(), "State: ", _state_desc[st], "Hold:", _holdPrice, "Long:", diffLong, "Short:", diffShort, "Loop:", _loopCount, extra); + + if (st == STATE_IDLE && _isCover) { + auto account = exchange.GetAccount(); + if (account.Valid) { + double profit = _N(exchange.GetName() == "Futures_OKCoin" ? account.Stocks + account.FrozenStocks : account.Balance + account.FrozenBalance, 8); + LogProfit(profit, _hedgeCount > 0 ? format("Net: %f @", profit) : ""); + } + _isCover = false; + return true; + } + auto ratio = abs(diffLong - diffShort); + bool condOpenLong = (st == STATE_IDLE || st == STATE_HOLD_LONG) && (diffLong - _countOpen * max(1.0, _holdPrice * 0.1)) > TA.Highest(barsA.High(), NPeriod) && _countOpen < AddMax; + bool condOpenShort = (st == STATE_IDLE || st == STATE_HOLD_SHORT) && (diffShort + _countOpen * max(1.0, _holdPrice * 0.1)) < TA.Lowest(barsB.Low(), NPeriod) && _countOpen < AddMax; + bool condCoverLong = false; + bool condCoverShort = false; + bool isLeave = false; + bool isStopLoss = false; + bool isStopWin = false; + if (st == STATE_HOLD_LONG) { + auto leavePrice = (diffShort + _countCover + ratio); + isLeave = leavePrice < TA.Lowest(barsB.Low(), LeavePeriod); + if (!isLeave) { + isStopLoss = diffShort - _holdPrice >= StopLoss; + if (!isStopLoss) { + isStopWin = _holdPrice - diffShort >= StopWin; + if (isStopWin) { + Log("Stop Win", "HOLD:", _holdPrice, "SHORT:", diffShort); + } + } else { + Log("StopLoss", "HOLD:", _holdPrice, "SHORT:", diffShort); + } + } else { + Log("Leave normally", "LeavePrice:", leavePrice); + } + condCoverLong = isLeave || isStopLoss || isStopWin; + } else if (st == STATE_HOLD_SHORT) { + auto leavePrice = (diffLong - _countCover - ratio); + isLeave = leavePrice > TA.Highest(barsA.High(), NPeriod); + if (!isLeave) { + isStopLoss = _holdPrice - diffLong >= StopLoss; + if (!isStopLoss) { + isStopWin = diffLong - _holdPrice >= StopWin; + if (isStopWin) { + Log("Stop Win", "HOLD:", _holdPrice, "LONG:", diffLong); + } + } else { + Log("StopLoss", "HOLD:", _holdPrice, "LONG:", diffLong); + } + } else { + Log("Leave normally", "LeavePrice:", leavePrice); + } + condCoverShort = isLeave || isStopLoss || isStopWin; + } + + string action, color; + double opPrice; + int chartIdx = 0; + if (condOpenLong) { + // Must Increase + if (_countOpen > 0 && diffLong <= _holdPrice) { + return STATE_IDLE; + } + + _isCover = false; + _countOpen++; + _countCover = 0; + _holdPrice = diffLong; + auto amount = _addArr[_countOpen]; + + if (_countOpen > 0) { + Log("Add Position Long", _countOpen); + } + exchange.SetContractType(symbolB); + exchange.SetDirection("sell"); + exchange.Sell(depthB.Bids[0].Price-SlidePrice, amount); + + exchange.SetContractType(symbolA); + exchange.SetDirection("buy"); + exchange.Buy(depthA.Asks[0].Price+SlidePrice, amount); + action = "L"; + color = "blue"; + opPrice = diffLong; + chartIdx = 1; + } else if (condOpenShort) { + // Must Decrease + if (_countOpen > 0 && diffShort >= _holdPrice) { + return STATE_IDLE; + } + + _isCover = false; + _countOpen++; + _countCover = 0; + _holdPrice = diffShort; + auto amount = _addArr[_countOpen]; + + if (_countOpen > 0) { + Log("Add Position Short", _countOpen); + } + exchange.SetContractType(symbolA); + exchange.SetDirection("sell"); + exchange.Sell(depthA.Bids[0].Price-SlidePrice, amount); + + exchange.SetContractType(symbolB); + exchange.SetDirection("buy"); + exchange.Buy(depthB.Asks[0].Price+SlidePrice, amount); + + action = "S"; + color = "red"; + opPrice = diffShort; + chartIdx = 3; + } else if (condCoverLong) { + _isCover = true; + _countOpen = 0; + _countCover++; + _hedgeCount++; + if (_countCover > 0) { + Log("Cover Position Long", _countCover); + } + exchange.SetContractType(symbolB); + exchange.SetDirection("closesell"); + exchange.Buy(depthB.Asks[0].Price+SlidePrice, _holdAmount); + + exchange.SetContractType(symbolA); + exchange.SetDirection("closebuy"); + exchange.Sell(depthA.Bids[0].Price-SlidePrice, _holdAmount); + + action = "CL"; + color = "blue"; + opPrice = diffShort; + + chartIdx = 3; + } else if (condCoverShort) { + _hedgeCount++; + _isCover = true; + _countOpen = 0; + _countCover++; + if (_countCover > 0) { + Log("Cover Position Short", _countCover); + } + exchange.SetContractType(symbolA); + exchange.SetDirection("closesell"); + exchange.Buy(depthA.Asks[0].Price+SlidePrice, _holdAmount); + + exchange.SetContractType(symbolB); + exchange.SetDirection("closebuy"); + exchange.Sell(depthB.Bids[0].Price-SlidePrice, _holdAmount); + action = "CS"; + color = "blue"; + opPrice = diffLong; + chartIdx = 1; + } else { + return true; + } + _needCheckOrder = true; + + _c.add(chartIdx, {{"x", UnixNano()/1000000}, {"title", action}, {"text", format("diff: %f", opPrice)}, {"color", color}}); + Log(st, "Long:", diffLong, "Short:", diffShort, "Hold:", _holdPrice); + return true; + } + + private: + vector _addArr; + string _state_desc[4] = {"NA", "IDLE", "LONG", "SHORT"}; + int _countOpen = 0; + int _countCover = 0; + int _lastCache = 0; + int _hedgeCount = 0; + int _loopCount = 0; + double _holdPrice = 0; + BarFeeder _feederA = BarFeeder(DPeriod); + BarFeeder _feederB = BarFeeder(DPeriod); + State _st = STATE_NA; + string _cfgStr; + double _holdAmount = 0; + bool _isCover = false; + bool _needCheckOrder = true; + Chart _c = Chart(""); +}; + +inline unsigned char toHex(unsigned char x) { + return x > 9 ? x + 55 : x + 48; +} + +std::string urlencode(const std::string& str) { + std::string strTemp = ""; + size_t length = str.length(); + for (size_t i = 0; i < length; i++) + { + if (isalnum((unsigned char)str[i]) || + (str[i] == '-') || + (str[i] == '_') || + (str[i] == '.') || + (str[i] == '~')) + strTemp += str[i]; + else if (str[i] == ' ') + strTemp += "+"; + else + { + strTemp += '%'; + strTemp += toHex((unsigned char)str[i] >> 4); + strTemp += toHex((unsigned char)str[i] % 16); + } + } + return strTemp; +} + +uint64_t _Time(string &s) { + // 测试 + // Log(s); + + tm t_init; + t_init.tm_year = 70; + t_init.tm_mon = 0; + t_init.tm_mday = 1; + t_init.tm_hour = 0; + t_init.tm_min = 0; + t_init.tm_sec = 0; + + tm t; + int year, month, day, hour, minute, second, ms; + sscanf(s.c_str(), "%d-%d-%dT%d:%d:%d.%dZ", &year, &month, &day, &hour, &minute, &second, &ms); + t.tm_year = year - 1900; + t.tm_mon = month - 1; + t.tm_mday = day; + t.tm_hour = hour; + t.tm_min = minute; + t.tm_sec = second; + t.tm_isdst = 0; + + return uint64_t(mktime(&t))*1000+ms-uint64_t(mktime(&t_init))*1000; +} + +void main() { + // 测试 + // exchange.IO("base", "https://www.okex.me"); // 测试 + if (IsSetProxy) { + exchange.SetProxy(Proxy); + } + + LogReset(); + LogProfitReset(); + SetErrorFilter("ready|timeout|500"); + Log("Init OK"); + + string symbolA = InstrumentA; + string symbolB = InstrumentB; + Hedge h; + + if (IsVirtual()) { + while (true) { + exchange.SetContractType(symbolA); + auto depthA = exchange.GetDepth(); + if (depthA.Valid) { + exchange.SetContractType(symbolB); + auto depthB = exchange.GetDepth(); + if (depthB.Valid) { + h.Loop(symbolA, depthA, symbolB, depthB); + } + } + } + return; + } + if (exchange.GetName() != "Futures_OKCoin") { + Panic("only support Futures_OKCoin"); + } + string realSymbolA = exchange.SetContractType(symbolA)["instrument"]; + string realSymbolB = exchange.SetContractType(symbolB)["instrument"]; + + string qs = urlencode(json({{"op", "subscribe"}, {"args", {"futures/depth5:" + realSymbolA, "futures/depth5:" + realSymbolB}}}).dump()); + Log("try connect to websocket"); + auto ws = Dial("wss://real.okex.com:10442/ws/v3|compress=gzip_raw&mode=recv&reconnect=true&payload="+qs); + Log("connect to websocket success"); + + Depth depthA, depthB; + auto fillDepth = [](json &data, Depth &d) { + d.Valid = true; + d.Asks.clear(); + d.Asks.push_back({atof(string(data["asks"][0][0]).c_str()), atof(string(data["asks"][0][1]).c_str())}); + d.Bids.clear(); + d.Bids.push_back({atof(string(data["bids"][0][0]).c_str()), atof(string(data["bids"][0][1]).c_str())}); + }; + string timeA; + string timeB; + while (true) { + auto buf = ws.read(); + + // 测试 + // Log("buf:", buf); + + json obj; + try { + obj = json::parse(buf); + } catch (json::parse_error& e) { + Log(buf); + Log(e.what()); + continue; + } + if (obj["data"].size() == 0) { + continue; + } + auto data = obj["data"][0]; + string ins = data["instrument_id"]; + if (ins == realSymbolA) { + fillDepth(data, depthA); + timeA = data["timestamp"]; + } else if (ins == realSymbolB) { + fillDepth(data, depthB); + timeB = data["timestamp"]; + } + + if (depthA.Valid && depthB.Valid) { + auto diffA = uint64_t(UnixNano()/1000000)-_Time(timeA); + auto diffB = uint64_t(UnixNano()/1000000)-_Time(timeB); + // Log("diffA:", diffA, "diffB:", diffB); // 测试 + if (diffA > MaxDelay || diffB > MaxDelay) { + continue; + } + h.Loop(symbolA, depthA, symbolB, depthB, format("market delay (ms): %d, %d", diffA, diffB)); + } + } +} + + + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/163447 + +> 更新时间 + +2019-09-10 17:58:50 diff --git "a/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.md" "b/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.md" index 4f43a3b7..4ca3311d 100644 --- "a/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.md" +++ "b/CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.md" @@ -5,7 +5,7 @@ CoinPark交易所通用协议 6.27 16:00 更新 关闭了SSL验证 > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/Deribit\346\234\237\346\235\203\346\265\213\350\257\225\347\255\226\347\225\245.md" "b/Deribit\346\234\237\346\235\203\346\265\213\350\257\225\347\255\226\347\225\245.md" new file mode 100644 index 00000000..614459bb --- /dev/null +++ "b/Deribit\346\234\237\346\235\203\346\265\213\350\257\225\347\255\226\347\225\245.md" @@ -0,0 +1,119 @@ + +> 策略名称 + +Deribit期权测试策略 + +> 策略作者 + +小小梦 + +> 策略描述 + +## Deribit期权测试策略 + +测试代码,测试期权开仓、平仓、下单撤单,行情获取等。 +使用的是Deribit测试环境,用于实际实盘,可以删除```exchange.IO("base", "https://test.deribit.com")```行代码。 + +![IMG](https://www.fmz.com/upload/asset/1705e6bb63a19de89463.png) + + + +> 源码 (javascript) + +``` javascript +function CancelAll() { + while (1) { + var orders = exchange.GetOrders() + for (var i = 0; i < orders.length; i++) { + exchange.CancelOrder(orders[i].Id, orders[i]) + Sleep(500) + } + if (orders && orders.length == 0) { + break + } + Sleep(500) + } + Log(exchange.GetOrders()) +} + +function main() { + contract = "BTC-27DEC19-7250-P" + exchange.IO("base", "https://test.deribit.com") // 测试,使用deribit的模拟测试环境,如果实盘,请删除此句 + exchange.SetContractType(contract) // 设置期权合约 + + // 取消当前所有挂单 + CancelAll() + + // 获取当前账户信息 + LogStatus(exchange.GetAccount()) + Sleep(500) + + // 获取当前行情信息 + Log(exchange.GetTicker()) + Sleep(500) + + // 获取当前深度信息 + Log(exchange.GetDepth()) + Sleep(500) + + // 获取当前市场最近成交记录 + Log(exchange.GetTrades()) + Sleep(500) + + // 获取当前K线数据 + Log(exchange.GetRecords()) + Sleep(500) + + // 测试下单 + exchange.SetDirection("buy") + var id = exchange.Buy(0.002, 0.1) // 第一个参数指的是 权利金,第二个参数指的是标的物数量 + Log("id:", id) + Sleep(500) + + // 获取订单信息 + Log(exchange.GetOrder(id)) + Sleep(500) + + // 获取当前所有挂单 + Log(exchange.GetOrders()) + Sleep(500) + + // 获取当前期权持仓 + Log(exchange.GetPosition()) + Sleep(500) + + // 撤销挂单 + exchange.CancelOrder(id) + Sleep(500) + + // 再次获取当前挂单,检查是否撤销 + Log(exchange.GetOrders()) + Sleep(500) + + // 吃单成交 + exchange.SetDirection("sell") + var ticker = exchange.GetTicker() + var id2 = exchange.Sell(ticker.Buy, 0.1) + Sleep(500) + + // 获取持仓 + Log(exchange.GetPosition()) + Sleep(500) + + // 平仓 + exchange.SetDirection("closesell") + var pos = exchange.GetPosition(contract) + Log("pos", pos) + var id3 = exchange.Buy(ticker.Sell, pos[0].Amount) + Log(exchange.GetPosition()) + Sleep(500) +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/179475 + +> 更新时间 + +2019-12-25 15:17:30 diff --git a/Dual Thrust OKEX Feature.md b/Dual Thrust OKEX Feature.md index b4fcc4fd..5febda00 100644 --- a/Dual Thrust OKEX Feature.md +++ b/Dual Thrust OKEX Feature.md @@ -5,7 +5,7 @@ Dual Thrust OKEX Feature > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/FCoin\346\235\240\346\235\206\344\272\244\346\230\223\346\250\241\346\235\277.md" "b/FCoin\346\235\240\346\235\206\344\272\244\346\230\223\346\250\241\346\235\277.md" deleted file mode 100644 index 90e1c2b7..00000000 --- "a/FCoin\346\235\240\346\235\206\344\272\244\346\230\223\346\250\241\346\235\277.md" +++ /dev/null @@ -1,78 +0,0 @@ - -> 策略名称 - -FCoin杠杆交易模板 - -> 策略作者 - -wmjbs - -> 策略描述 - -1.此模板仅支持Fcoin的杠杆账户 -2.目前仅有卖出功能,买入功能和杠杆账户资产获取功能 -3.希望有能力的朋友进行改进,加入撤单功能和获取未完成订单功能 - - - -> 源码 (javascript) - -``` javascript -/* -1.此模板仅支持Fcoin的杠杆账户 -2.目前仅有卖出功能、买入功能和杠杆账户资产获取功能 -3.希望有能力的朋友进行改进,加入撤单功能和获取未完成订单功能 -*/ - -$.fcoinSell = function(price, amount) { - var message = "&symbol=btcusdt" + "&side=sell" + "&type=limit" + "&price=" + price.toString() + "&amount=" + amount.toString() + "&exchange=main" + "&account_type=margin" - id = exchanges[0].IO("api", "POST", "/v2/orders", message) - return id; -} - -$.fcoinBuy = function(price, amount) { - var message = "&symbol=btcusdt" + "&side=buy" + "&type=limit" + "&price=" + price.toString() + "&amount=" + amount.toString() + "&exchange=main" + "&account_type=margin" - id = exchanges[0].IO("api", "POST", "/v2/orders", message) - return id; -} - -$.Get_Account = function() { - var account = null; - while (true) { - var Currency = "btcusdt"; - account = exchange.IO("api", "GET", "/v2/broker/leveraged_accounts/account", "account_type=" + Currency); - if (account.status == 'ok') { - break; - } - Sleep(1500) - } - return { - Info: null, - Balance: Math.abs(account.data.available_quote_currency_amount), - FrozenBalance: Math.abs(account.data.frozen_quote_currency_amount), - Stocks: Math.abs(account.data.available_base_currency_amount), - FrozenStocks: Math.abs(account.data.frozen_base_currency_amount) - } -} - -// 测试代码 -function main() { - - var buyorder = $.fcoinBuy(6000, 0.001); - var sellorder = $.fcoinSell(9000, 0.001); - - Log(buyorder); - Log(sellorder); - - Log($.Get_Account()); - Log($.Get_Account().Stocks); -} -``` - -> 策略出处 - -https://www.fmz.com/strategy/151157 - -> 更新时间 - -2019-06-09 10:47:22 diff --git "a/FMEX[\347\251\272\345\244\264]\350\266\213\345\212\277\346\214\226\347\237\277\347\255\226\347\225\245\357\274\210\351\232\217\346\234\272\347\275\221\346\240\274\346\216\222\345\272\217\357\274\211.md" "b/FMEX[\347\251\272\345\244\264]\350\266\213\345\212\277\346\214\226\347\237\277\347\255\226\347\225\245\357\274\210\351\232\217\346\234\272\347\275\221\346\240\274\346\216\222\345\272\217\357\274\211.md" new file mode 100644 index 00000000..90951af3 --- /dev/null +++ "b/FMEX[\347\251\272\345\244\264]\350\266\213\345\212\277\346\214\226\347\237\277\347\255\226\347\225\245\357\274\210\351\232\217\346\234\272\347\275\221\346\240\274\346\216\222\345\272\217\357\274\211.md" @@ -0,0 +1,329 @@ + +> 策略名称 + +FMEX[空头]趋势挖矿策略(随机网格排序) + +> 策略作者 + +古力十段 + +> 策略描述 + +FMex排序挖矿空头版本代码使用说明。(注意api地址)(加强版-增加仓位管理-增加时间设定,调整单量方向等-购买联系微信:ying5737) +(预计日跌幅1%以上,赚币赚矿,反之亏损明显) +保证金市场风险巨大,你可能随时面临100%损失。或有不明bug100%损失,概不负责。 + +原理:盘口下单随机成交/ +先持仓SHORT100u。//注意:先手动持仓SHORT100u。 + +- 检测现有订单是否超过界限,如果超过了就立马取消该订单/ +- 检测是否成交形成了仓位,如果大于仓位xxu,则减仓到既定仓位以下/ + +几种情况: +全局挂单:为区别市商策略,特定定义远端排序为挂单,参数为买(35u)单量卖(35u)左右。参数可调。 +市商: +最大多头持仓100u,若大于该仓位,约每6s减20u仓位,直到小于100u. +最大空头持仓1000u,若大于该仓位,约每6s减200u仓位,直到小于100u. +大于1u多仓启动减多仓策略,挂单为short:卖3卖4卖5(各30u单量) +大于800u空仓,启动减空仓策略,挂单为long:买2买3买4(各30u单量) +正常持仓,SHORT 卖2卖3卖4 + +//参数中的备注描述,仅供参考,另可加挡位 +风险自负/参数可调,购买加强版联系微信:ying5737 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Url|https://api.fmex.com|交易所api地址| +|g_minPercent|0.05|挂单:挖矿的下限,离最新价的百分比,如果是 1% 则填写 1| +|g_maxPercent|0.05|挂单:挖矿的上限,离最新价的百分比,如果是 1% 则填写 1| +|g_perAmount|35|挂单:每个订单量多少张,最多只能挂50个订单| +|g_kongtouAmount|35|挂单:| +|g_maxHoldingLong|100|挂单:多单最大持仓量| +|g_maxHoldingShort|1000|挂单:空单最大持仓量| +|sp_jiancangAmount|true|市商/排序:减仓多仓| +|sp_jiacangAmount|true|市商/排序:增加多仓| +|sp_kongtouAmount|30|市商/排序: 空头数| +|sp_perAmount|30|市商/排序:单个订单大小| +|mainIntervel|false|Intervel| +|Intervel|false|Intervel0| +|sp_baseAmountLong|true|多仓| +|sp_baseAmountShort|800|空仓| + + +> 源码 (javascript) + +``` javascript +exchange.IO("base", Url)//保证金市场风险巨大,你可能随时面临100%损失。或有不明bug100%损失,概不负责。 +//实盘地址:https://api.fmex.com 测试网https://api.testnet.fmex.com//注意:先持仓short100u。 +var ordersInfo = {//(加强版-增加仓位管理-增加时间设定-调整单量方向等-价格美丽/购买联系微信:ying5737) + buyId: 0, + buyPrice: 0, + sellId: 0, + sellPrice: 0, + minPrice: 0, + maxPrice: 0 +} +var depthInfo = {//注意:先手动持仓short100u。 + asks: [], + bids: [] +} +function getTicker(symbol) { + url = "/v2/market/ticker/" + symbol; + data = exchange.IO("api", "GET", url); + return data.data; +} +function getAccounts() { + data = exchange.IO("api", "GET", "/v3/contracts/accounts") + return data.data; +} + +function createOrderPrice(body) { + parameter = "symbol=" + body.symbol + "&type=" + body.type + "&direction=" + body.direction + "&post_only=" + body.post_only + "&price=" + body.price + "&quantity=" + body.quantity; + + resultData = exchange.IO("api", "POST", "/v3/contracts/orders", parameter) + return resultData; +} +function createOrder(body) { + parameter = "symbol=" + body.symbol + "&type=" + body.type + "&direction=" + body.direction + "&quantity=" + body.quantity; + + resultData = exchange.IO("api", "POST", "/v3/contracts/orders", parameter) + + return resultData; +} + +function getOrders() { + resultData = exchange.IO("api", "GET", "/v3/contracts/orders/open"); + return resultData.data +} + +function cancelOrder(id) { + resultData = exchange.IO("api", "POST", "/v3/contracts/orders/" + id + "/cancel"); + return resultData; + +} + +function getPosition() { + resultData = exchange.IO("api", "GET", "/v3/broker/auth/contracts/positions"); + return resultData.data; +} + +function getMatches(id) { + resultData = exchange.IO("api", "GET", "/v3/contracts/orders/" + id + "/matches"); + return resultData.data; +} + +function getCandles(resolution, symbol) { + resultData = exchange.IO("api", "GET", "/v2/market/candles/" + resolution + "/" + symbol); + return resultData.data; +} +function cleanOrders(lastPrice) { + ordersInfo = getOrders(); + orders = ordersInfo.results; + for (var i = 0; i < orders.length; i++) { + diffPercent = Math.abs(lastPrice - orders[i].price) / lastPrice * 100 + if (diffPercent < g_minPercent || diffPercent > g_maxPercent) { + orderInfo = cancelOrder(orders[i].id); + + Log("挂单取消订单:"); + } + } +} +function getToOrderPrice(basePrice, direct) { + return parseInt(basePrice * (direct * (g_minPercent + Math.random() * (g_maxPercent - g_minPercent)) / 100 + 1)) +} +function cleanPosition() { + res = getPosition(); + res.results.forEach(function(it) { + if (it.symbol == 'BTCUSD_P') { + if (it.quantity) { + if (it.quantity > g_maxHoldingLong && it.direction.toUpperCase() == 'LONG') { + data = createOrder({ + symbol: "BTCUSD_P", + type: "MARKET", + direction: it.direction.toUpperCase() == 'LONG' ? "SHORT" : "LONG", + quantity: 20, + }) + Log("平仓:"); + } + if (it.quantity > g_maxHoldingShort && it.direction.toUpperCase() == 'SHORT') { + data = createOrder({ + symbol: "BTCUSD_P", + type: "MARKET", + direction: it.direction.toUpperCase() == 'LONG' ? "SHORT" : "LONG", + quantity: 20, + }) + Log("平仓:"); + } + } + } + }); +} +function guadan() { + tickerInfo = getTicker('BTCUSD_P'); + ticker = tickerInfo.ticker; + + var lastPrice = ticker[0]; + Log("lastPrice: "+lastPrice); + buyPrice = getToOrderPrice(lastPrice, -1); + sellPrice = getToOrderPrice(lastPrice, 1); + + LongOrderInfo = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: buyPrice, + quantity: g_perAmount, + }) + Log("挂单LONG:" ); + shortOrderInfo = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: sellPrice, + quantity: g_kongtouAmount, + }) + Log("挂单SHORT:" ); + + cleanOrders(lastPrice) + cleanPosition(); +} +function shishang() { + Log("市商/排序挖矿**********************************"); + tickerInfo = getTicker('BTCUSD_P'); + ticker = tickerInfo.ticker; + Log("市商/排序挖矿ticker:"); + lastPrice = ticker[0] + buyPrice = ticker[2] + sellPrice = ticker[4] + Log("lastPrice:"+lastPrice+":buyPrice:"+buyPrice+":sellPrice:" + sellPrice); + if (lastPrice == buyPrice) { + sellPrice = (buyPrice + 0.5).toFixed(1) + } + if (lastPrice == sellPrice) { + buyPrice = (sellPrice - 0.5).toFixed(1) + } + Log("buyPrice:"+buyPrice+":sellPrice:" + sellPrice); + // const LastK7 = k[7]; // 最近第九根 + res = getPosition(); + Log("市商/排序挖矿Position:" + JSON.stringify(res)); + res.results.forEach(function(it) { + + if (it.symbol == 'BTCUSD_P') { + if (it.quantity) { + if (it.quantity > sp_baseAmountLong && it.direction.toUpperCase() == 'LONG') { + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice + 1.5, + quantity: sp_perAmount, + }) + Log("排序10:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice + 2, + quantity: sp_perAmount, + }) + Log("排序9:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice + 2.5, + quantity: sp_perAmount, + }) + Log("排序8:"); + } else if (it.quantity > sp_baseAmountShort && it.direction.toUpperCase() == 'SHORT') { + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 0.5, + quantity: sp_perAmount, + }) + Log("市商/排序-2:"); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 1, + quantity: sp_perAmount, + }) + Log("市商/排序-3:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 1.5, + quantity: sp_perAmount, + }) + Log("市商/排序-4:" ); + } else { + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice - 1, + quantity: sp_perAmount, + }) + Log("市商-3:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice - 1.5, + quantity: sp_perAmount, + }) + Log("市商-4:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice - 2, + quantity: sp_perAmount, + }) + Log("市商-5:"); + + } + } + } + }) +} +/********************END 市商/排序挖矿***************************************************************************************************/ +function main() { + + while(true){ + + guadan(); + Sleep(Intervel * 1000) + + shishang() + Sleep(mainIntervel * 1000) + } +}//FMex排序挖矿多头版本代码使用说明。(注意api地址)(加强版-增加仓位管理-增加时间设定等-购买联系微信:ying5737) +``` + +> 策略出处 + +https://www.fmz.com/strategy/178417 + +> 更新时间 + +2019-12-21 07:34:12 diff --git "a/FMEX\346\214\226\347\237\277\347\255\226\347\225\245\357\274\210\346\216\222\345\272\217\357\274\211btc\345\235\207\350\241\241\346\210\226\343\200\220\351\234\207\350\215\241\347\211\210\343\200\221.md" "b/FMEX\346\214\226\347\237\277\347\255\226\347\225\245\357\274\210\346\216\222\345\272\217\357\274\211btc\345\235\207\350\241\241\346\210\226\343\200\220\351\234\207\350\215\241\347\211\210\343\200\221.md" new file mode 100644 index 00000000..1712c943 --- /dev/null +++ "b/FMEX\346\214\226\347\237\277\347\255\226\347\225\245\357\274\210\346\216\222\345\272\217\357\274\211btc\345\235\207\350\241\241\346\210\226\343\200\220\351\234\207\350\215\241\347\211\210\343\200\221.md" @@ -0,0 +1,359 @@ + +> 策略名称 + +FMEX挖矿策略(排序)btc均衡或【震荡版】 + +> 策略作者 + +古力十段 + +> 策略描述 + +FMex排序挖矿均衡代码使用说明。(注意api地址)(加强版-增加仓位管理-增加时间设定,调整单量,方向等-购买联系微信:ying5737) + +保证金市场风险巨大,你可能随时面临100%损失。或有不明bug100%损失,概不负责。 + +原理:盘口下单随机成交/ +//注意:先手动持仓long1u。 + +- 检测现有订单是否超过界限,如果超过了就立马取消该订单/ +- 检测是否成交形成了仓位,如果大于仓位xxu,则减仓到既定仓位以下/ + +几种情况: +全局挂单:为区别市商策略,特定定义远端排序为挂单,参数为买(35u)单量卖(35u)左右。参数可调。 +市商: +最大多头持仓700u,若大于该仓位,约每6s减20u仓位,直到小于700u. +最大空头持仓700u,若大于该仓位,约每6s减20u仓位,直到小于700u. +大于500u多仓启动减多仓策略,挂单为short:卖3卖4卖5(各30u单量) +大于500u空仓,启动减空仓策略,挂单为long:买2买3买4(各30u单量) +正常持仓,SHORT 卖7卖8卖9 long买4买7买8 + + + +//可其他账户持仓对冲,对行情有把握后,亦可以单独开 + +//参数中的备注描述,仅供参考,另可加挡位 +风险自负/参数可调,购买加强版联系微信:ying5737 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Url|https://api.fmex.com|交易所api地址| +|g_minPercent|0.05|挂单:挖矿的下限,离最新价的百分比,如果是 1% 则填写 1| +|g_maxPercent|0.05|挂单:挖矿的上限,离最新价的百分比,如果是 1% 则填写 1| +|g_perAmount|35|挂单:每个订单量多少张,最多只能挂50个订单| +|g_kongtouAmount|35|挂单:| +|g_maxHoldingLong|700|挂单:多单最大持仓量| +|g_maxHoldingShort|700|挂单:空单最大持仓量| +|sp_jiancangAmount|true|市商/排序:减仓多仓| +|sp_jiacangAmount|true|市商/排序:增加多仓| +|sp_kongtouAmount|30|市商/排序: 空头数| +|sp_perAmount|30|市商/排序:单个订单大小| +|mainIntervel|false|Intervel| +|Intervel|false|Intervel0| +|sp_baseAmountLong|500|多仓| +|sp_baseAmountShort|500|空仓| + + +> 源码 (javascript) + +``` javascript +exchange.IO("base", Url)//保证金市场风险巨大,你可能随时面临100%损失。或有不明bug100%损失,概不负责。 +//实盘地址:https://api.fmex.com 测试网https://api.testnet.fmex.com//注意:先持仓long1u。 +var ordersInfo = {//(加强版-增加仓位管理-增加时间设定-调整单量方向等-价格美丽/购买联系微信:ying5737) + buyId: 0, + buyPrice: 0, + sellId: 0, + sellPrice: 0, + minPrice: 0, + maxPrice: 0 +} +var depthInfo = {//注意:先手动持仓long1u。 + asks: [], + bids: [] +} +function getTicker(symbol) { + url = "/v2/market/ticker/" + symbol; + data = exchange.IO("api", "GET", url); + return data.data; +} +function getAccounts() { + data = exchange.IO("api", "GET", "/v3/contracts/accounts") + return data.data; +} + +function createOrderPrice(body) { + parameter = "symbol=" + body.symbol + "&type=" + body.type + "&direction=" + body.direction + "&post_only=" + body.post_only + "&price=" + body.price + "&quantity=" + body.quantity; + + resultData = exchange.IO("api", "POST", "/v3/contracts/orders", parameter) + return resultData; +} +function createOrder(body) { + parameter = "symbol=" + body.symbol + "&type=" + body.type + "&direction=" + body.direction + "&quantity=" + body.quantity; + + resultData = exchange.IO("api", "POST", "/v3/contracts/orders", parameter) + + return resultData; +} + +function getOrders() { + resultData = exchange.IO("api", "GET", "/v3/contracts/orders/open"); + return resultData.data +} + +function cancelOrder(id) { + resultData = exchange.IO("api", "POST", "/v3/contracts/orders/" + id + "/cancel"); + return resultData; + +} + +function getPosition() { + resultData = exchange.IO("api", "GET", "/v3/broker/auth/contracts/positions"); + return resultData.data; +} + +function getMatches(id) { + resultData = exchange.IO("api", "GET", "/v3/contracts/orders/" + id + "/matches"); + return resultData.data; +} + +function getCandles(resolution, symbol) { + resultData = exchange.IO("api", "GET", "/v2/market/candles/" + resolution + "/" + symbol); + return resultData.data; +} +function cleanOrders(lastPrice) { + ordersInfo = getOrders(); + orders = ordersInfo.results; + for (var i = 0; i < orders.length; i++) { + diffPercent = Math.abs(lastPrice - orders[i].price) / lastPrice * 100 + if (diffPercent < g_minPercent || diffPercent > g_maxPercent) { + orderInfo = cancelOrder(orders[i].id); + + Log("挂单取消订单:"); + } + } +} +function getToOrderPrice(basePrice, direct) { + return parseInt(basePrice * (direct * (g_minPercent + Math.random() * (g_maxPercent - g_minPercent)) / 100 + 1)) +} +function cleanPosition() { + res = getPosition(); + res.results.forEach(function(it) { + if (it.symbol == 'BTCUSD_P') { + if (it.quantity) { + if (it.quantity > g_maxHoldingLong && it.direction.toUpperCase() == 'LONG') { + data = createOrder({ + symbol: "BTCUSD_P", + type: "MARKET", + direction: it.direction.toUpperCase() == 'LONG' ? "SHORT" : "LONG", + quantity: 20, + }) + Log("平仓:"); + } + if (it.quantity > g_maxHoldingShort && it.direction.toUpperCase() == 'SHORT') { + data = createOrder({ + symbol: "BTCUSD_P", + type: "MARKET", + direction: it.direction.toUpperCase() == 'LONG' ? "SHORT" : "LONG", + quantity: 20, + }) + Log("平仓:"); + } + } + } + }); +} +function guadan() { + tickerInfo = getTicker('BTCUSD_P'); + ticker = tickerInfo.ticker; + + var lastPrice = ticker[0]; + Log("lastPrice: "+lastPrice); + buyPrice = getToOrderPrice(lastPrice, -1); + sellPrice = getToOrderPrice(lastPrice, 1); + + LongOrderInfo = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: buyPrice, + quantity: g_perAmount, + }) + Log("挂单LONG:" ); + shortOrderInfo = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: sellPrice, + quantity: g_kongtouAmount, + }) + Log("挂单SHORT:" ); + + cleanOrders(lastPrice) + cleanPosition(); +} +function shishang() { + Log("市商/排序挖矿**********************************"); + tickerInfo = getTicker('BTCUSD_P'); + ticker = tickerInfo.ticker; + Log("市商/排序挖矿ticker:"); + lastPrice = ticker[0] + buyPrice = ticker[2] + sellPrice = ticker[4] + Log("lastPrice:"+lastPrice+":buyPrice:"+buyPrice+":sellPrice:" + sellPrice); + if (lastPrice == buyPrice) { + sellPrice = (buyPrice + 0.5).toFixed(1) + } + if (lastPrice == sellPrice) { + buyPrice = (sellPrice - 0.5).toFixed(1) + } + Log("buyPrice:"+buyPrice+":sellPrice:" + sellPrice); + // const LastK7 = k[7]; + res = getPosition(); + Log("市商/排序挖矿Position:" + JSON.stringify(res)); + res.results.forEach(function(it) { + + if (it.symbol == 'BTCUSD_P') { + if (it.quantity) { + if (it.quantity > sp_baseAmountLong && it.direction.toUpperCase() == 'LONG') { + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice + 1.5, + quantity: sp_perAmount, + }) + Log("排序10:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice + 2, + quantity: sp_perAmount, + }) + Log("排序9:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice + 2.5, + quantity: sp_perAmount, + }) + Log("排序8:"); + } else if (it.quantity > sp_baseAmountShort && it.direction.toUpperCase() == 'SHORT') { + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 0.5, + quantity: sp_perAmount, + }) + Log("市商/排序-2:"); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 1, + quantity: sp_perAmount, + }) + Log("市商/排序-3:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 1.5, + quantity: sp_perAmount, + }) + Log("市商/排序-4:" ); + } else { + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice - 3.5, + quantity: sp_perAmount, + }) + Log("市商-3:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice - 4.5, + quantity: sp_perAmount, + }) + Log("市商-4:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice - 4, + quantity: sp_perAmount, + }) + Log("市商-5:"); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 2, + quantity: sp_perAmount, + }) + Log("市商/排序-3:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 3.5, + quantity: sp_perAmount, + }) + Log("市商/排序-4:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 4, + quantity: sp_perAmount, + }) + Log("市商/排序-4:" ); + } + } + } + }) +} +/********************END 市商/排序挖矿***************************************************************************************************/ +function main() { + + while(true){ + + guadan(); + Sleep(Intervel * 1000) + + shishang() + Sleep(mainIntervel * 1000) + } +}//FMex排序挖矿多头版本代码使用说明。(注意api地址)(加强版-增加仓位管理-增加时间设定等-购买联系微信:ying5737) +``` + +> 策略出处 + +https://www.fmz.com/strategy/178700 + +> 更新时间 + +2019-12-21 07:31:42 diff --git "a/FMEX\347\256\200\345\215\225\344\272\244\346\230\223\346\214\226\347\237\277\346\234\272\345\231\250\344\272\272.md" "b/FMEX\347\256\200\345\215\225\344\272\244\346\230\223\346\214\226\347\237\277\346\234\272\345\231\250\344\272\272.md" new file mode 100644 index 00000000..d091a734 --- /dev/null +++ "b/FMEX\347\256\200\345\215\225\344\272\244\346\230\223\346\214\226\347\237\277\346\234\272\345\231\250\344\272\272.md" @@ -0,0 +1,187 @@ + +> 策略名称 + +FMEX简单交易挖矿机器人 + +> 策略作者 + +小草 + +> 策略描述 + +## 策略原理 + +**FMEX根据成交量大小来决定返还,由于taker有很高的手续费,此策略采用maker占据买一卖一,尽可能成交。** + +**每隔一段时间检查仓位,如果有持仓过多,则只开平仓单减少仓位** + +**策略仅供学习参考,按需修改。管理仓位简单,未经长时间测试,欢迎反馈问题,不定期更新** + +**如用于实盘,需要修改参数里的基地址** + +排序挖矿机器人: https://www.fmz.com/strategy/171042 +挂单挖矿机器人: https://www.fmz.com/strategy/171258 +交易挖矿机器人: https://www.fmz.com/strategy/171560 + + +FMZ已支持FMEX测试网,需要更新最新的托管者,等10月25号正式网上线后会自动切换。相关问题反馈:https://www.fmz.com/bbs-topic/4476 + +## 问题和改进方向 + +- 根据每分钟成交量的大小,挖矿效率也是不同的,可以考虑进去。 +- 可以maker成交后,立即taker平仓,需要考虑到挖矿收益是否能覆盖成本。 +- 策略较为死板,无法应对单边行情,可自行择时交易。 +- 行情波动剧烈可能做成maker。可用IO更改下单方式。 +- **可参考现货交易价格,确定挂单,减少单边成交** + +## 排序挖矿说明 + +https://fcoin.zendesk.com/hc/zh-cn/articles/360037172894-FMex%E4%BA%A4%E6%98%93%E6%8C%96%E7%9F%BF%E7%AE%97%E6%B3%95%E8%AF%B4%E6%98%8E + +每个永续合约交易对的每日交易挖矿额度,将分为两部分计算,并在合计后统一于次日返还。每部分分别返还该交易对当日额度的50%,具体算法为: + + + +用户在某合约交易对当日可获得的交易挖矿FMEX返还(第一部分)计算方法为: + +该交易对每日交易挖矿返还额度的50% * 用户在该交易对的成交量 / 该交易对的当日总成交量 + + + +用户在某交易对当日可获得的交易挖矿FMEX返还(第二部分)计算方法为: + +定义每天中的每1分钟为一个交易挖矿周期,每个周期分配交易对当日交易挖矿额度的1/2880。每个周期内,按照用户成交量的占比分配该交易挖矿周期的返还额度 + +用户在该交易对每个交易挖矿周期所获FMEX返还的总和,即该用户在该交易对当日可获得的挖矿FMEX返还(第二部分) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Intervel|2|休眠时间| +|Amount|10|下单量| +|HoldAmount|100|最大单边持仓量| +|CoverAmount|2|每次平仓量| +|CoverTime|60|检查仓位间隔| +|ProfitTime|60|打印收益时间间隔| +|Url|https://api.testnet.fmex.com|API基地址| + + +> 源码 (javascript) + +``` javascript +exchange.IO("base", Url) //切换基地址,方便切换实盘和模拟盘,实盘地址:https://api.fmex.com + +var ordersInfo = {buyId:0, buyPrice:0, buyAmount:0, sellId:0, sellPrice:0, sellAmount:0, pos:0} +var depthInfo = {asks:[], bids:[]} +var lastProfitTime = 0 //控制打印收益时间 +var lastRestTime = Date.now() //定时重置策略 +var lastCoverTime = 0 //检查仓位 + +function showTable(){ + var table = {type: 'table', title: '信息', cols: ['买一价', '卖一价', '买挂单量', '卖挂单量', '当前持仓量'], + rows: [[ordersInfo.buyPrice, ordersInfo.sellPrice, ordersInfo.buyAmount, ordersInfo.sellAmount, ordersInfo.pos]]} + LogStatus('`' + JSON.stringify(table) + '`\n'+JSON.stringify(ordersInfo)) +} + +function reset(){ //重置策略,防止一些订单卡住,可能会影响其它正在运行的策略 + var orders = exchange.GetOrders() + if(orders){ + for(var i=0;i0){ + if(pos[0].Type == 0){ //多仓 + ordersInfo.pos = pos[0].Amount + }else{ + ordersInfo.pos = -pos[0].Amount + } + } +} + +function main() { + exchange.SetContractType('swap') + exchange.SetMarginLevel(0) //全仓模式 + reset() + while(true){ + var ticker = _C(exchange.GetTicker) + var sellPrice = ticker.Sell + var buyPrice = ticker.Buy + if(Date.now()-lastCoverTime > CoverTime*1000){ + lastCoverTime = Date.now() + getPostiton() + } + if(ordersInfo.pos <= HoldAmount){ + if(buyPrice != ordersInfo.buyPrice){ + var cancelId = ordersInfo.buyId + exchange.SetDirection('buy') + var buyId = exchange.Buy(buyPrice, Amount) + ordersInfo.buyPrice = buyPrice + ordersInfo.buyAmount = Amount + if(buyId){ordersInfo.buyId = buyId}else{ordersInfo.buyId = 0} + if(cancelId){exchange.CancelOrder(cancelId)} //先下单后撤单,保证始终有挂单 + } + }else{ + if(ordersInfo.buyId){ + exchange.CancelOrder(ordersInfo.buyId) + } + ordersInfo.buyId = 0 + ordersInfo.buyPrice = 0 + ordersInfo.buyAmount = 0 + } + if(ordersInfo.pos >= -HoldAmount){ + if(sellPrice != ordersInfo.sellPrice){ + var cancelId = ordersInfo.sellId + exchange.SetDirection('sell') + var sellId = exchange.Sell(sellPrice, Amount) + ordersInfo.sellPrice = sellPrice + ordersInfo.sellAmount = Amount + if(sellId){ordersInfo.sellId = sellId}else{ordersInfo.sellId = 0} + if(cancelId){exchange.CancelOrder(cancelId)} + } + }else{ + if(ordersInfo.sellId){ + exchange.CancelOrder(ordersInfo.sellId) + } + ordersInfo.sellId = 0 + ordersInfo.sellPrice = 0 + ordersInfo.sellAmount = 0 + } + if(Date.now()-lastProfitTime > ProfitTime*1000){ + lastProfitTime = Date.now() + var account = exchange.GetAccount() + if(account){ + LogProfit(_N(account.Info.data.BTC[0]+account.Info.data.BTC[1]+account.Info.data.BTC[2],6)) + } + } + + if(Date.now()-lastRestTime > 10*60*1000){ + lastRestTime = Date.now() + reset() + } + showTable() + Sleep(Intervel*1000) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/171560 + +> 更新时间 + +2019-12-09 11:15:46 diff --git "a/FMEX\347\256\200\345\215\225\346\214\202\345\215\225\346\214\226\347\237\277\346\234\272\345\231\250\344\272\272.md" "b/FMEX\347\256\200\345\215\225\346\214\202\345\215\225\346\214\226\347\237\277\346\234\272\345\231\250\344\272\272.md" new file mode 100644 index 00000000..d51b75b9 --- /dev/null +++ "b/FMEX\347\256\200\345\215\225\346\214\202\345\215\225\346\214\226\347\237\277\346\234\272\345\231\250\344\272\272.md" @@ -0,0 +1,241 @@ + +> 策略名称 + +FMEX简单挂单挖矿机器人 + +> 策略作者 + +小草 + +> 策略描述 + +## 策略原理 + +**FMEX挂单挖矿将深度按照离盘口的远近分为不同的组,按挂单量占组内比例以及挖矿效率系数决定返还。策略将会根据当前深度,寻找收益最大的挂单位置挂单,尽量远离盘口。达到最大化资金利用的目的。不同深度的挖矿效率可能相差百倍。** + +**每隔一段时间检查仓位,如果有持仓,每次按盘口价平固定数量(需要自己设置)的仓位,直到不持仓。** + +**策略仅供学习参考,按需修改。管理仓位简单,未经长时间测试,欢迎反馈问题,不定期更新。** + +**如用于实盘,需要修改参数里的基地址** + +排序挖矿机器人: https://www.fmz.com/strategy/171042 +挂单挖矿机器人: https://www.fmz.com/strategy/171258 +交易挖矿机器人: https://www.fmz.com/strategy/171560 + +FMZ已支持FMEX测试网,需要更新最新的托管者,等10月25号正式网上线后会自动切换。相关问题反馈:https://www.fmz.com/bbs-topic/4476 + +## 问题和改进方向 + +- 由于FMEX最多返回150档深度,因此深度信息不完整,价格较高或较低时无法获取到准确的订单,因此无法计算效率。本策略将这些挂单组排除,可以有更好的方式处理。 +- 挖矿系数可自行定义,为了避免成交,向后的深度权重可以设置高一点。 +- 平仓方式简单,可自行修改。 + +## FMex挂单挖矿算法说明 + +https://fcoin.zendesk.com/hc/zh-cn/articles/360037685413-FMex%E6%8C%82%E5%8D%95%E6%8C%96%E7%9F%BF%E7%AE%97%E6%B3%95%E8%AF%B4%E6%98%8E + +定义每天中的每5分钟为一个挂单挖矿周期,每个周期分配交易对当日挂单挖矿额度的1/288。 + +每个周期内,随机选取一个时间点,对该交易对买卖盘挂单情况做快照镜像,按照挂单金额在不同价格范围内的占比(即在某价格范围内用户挂单金额占总挂单金额的占比)分配挖矿额度,其中: + +挂单价格 在 当前市场价(即快照时的价格) 上方 1%范围内,分配该挂单挖矿周期返还额度的 1/10 + + + +挂单价格 在 当前市场价 下方 1%范围内,分配该挂单挖矿周期返还额度的 1/10 + + +挂单价格 在 当前市场价 上方 1%-2%范围,分配该挂单挖矿周期返还额度的 1/20 + +挂单价格 在 当前市场价 下方 1%-2%范围,分配该挂单挖矿周期返还额度的 1/20 + + +....... + + +挂单价格 在 当前市场价 上方 20%范围外,分配该挂单挖矿周期返还额度的 1/20 + +挂单价格 在 当前市场价 下方 20%范围外,分配该挂单挖矿周期返还额度的 1/20 + + + +补充说明 + +1. 挂单金额的具体定义为挂单占用的资产(BTC),挂单占用的资产(BTC)= Quantity(下单数量)/ Price(价格)。 + +2. 挂单挖矿按日返还,每日0点之后(GMT+8)的新增挂单,才能参与当日的挂单挖矿。也就是说,挂单挖矿是按当日统计的,跨日的挂单不会统计在次日的挂单挖矿中,敬请用户知晓。 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Intervel|2|休眠时间| +|Amount|10|下单量| +|CoverAmount|2|每次平仓量| +|CoverTime|60|检查仓位并平仓间隔| +|ProfitTime|60|打印收益时间间隔| +|Url|https://api.testnet.fmex.com|API地址| + + +> 源码 (javascript) + +``` javascript + + +exchange.IO("base", Url) //切换基地址,方便切换实盘和模拟盘,实盘地址:https://api.fmex.com +//挖矿分组,[下限百分比,上限百分比,挖矿系数] +var groups = [[0,1,1/10],[1,2,1/20],[2,3,1/20],[3,4,1/20],[4,6,1/40],[6,8,1/40],[8,10,1/40],[10,12,1/40],[12,14,1/40],[14,16,1/40],[16,18,1/40],[18,20,1/40],[20,100,1/20]] +var ordersInfo = {buyId:0, buyPrice:0, sellId:0, sellPrice:0, minPrice:0, maxPrice:0} +var depthInfo = {asks:[], bids:[]} +var lastProfitTime = 0 //控制打印收益时间 +var lastRestTime = Date.now() //定时重置策略 +var lastCoverTime = Date.now() //检查仓位并平仓 + +function adjustNum(num){ //控制价格精度 + return num >= _N(num,0)+0.5 ? _N(num,0)+0.5 : _N(num,0) +} + +function calcDepth(depth){ //计算最佳挂单位置 + depthInfo = {asks:[], bids:[]} + var last_price = adjustNum((depth.asks[0] + depth.bids[0])/2) //上一次成交价 + var j = 0 //买单深度迭代标记位置 + var k = 0 + var max_asks = 0 + var max_bids = 0 + for(var i=0;i sell_price_bound[0] && ordersInfo.sellPrice <= sell_price_bound[1]) ? Amount : 0 + var ratio = _N(10000*Amount*fact/Math.max(ask_amount+Amount-my_ask_amount,Amount),5) + depthInfo.asks.push(['sell_'+groups[i][0]+'-'+groups[i][1]+'%', fact, sell_price_bound[0], sell_price_bound[1], ask_amount, ratio, depth.asks[depth.asks.length-2] >= sell_price_bound[1]]) + if(ratio >= depthInfo.asks[max_asks][5] && depth.asks[depth.asks.length-2] >= sell_price_bound[1]){ //保证是完整的深度信息 + max_asks = depthInfo.asks.length-1 + } //大于等于保证相同挖矿效率下远离盘口的优先 + + while(depth.bids[k*2] >= buy_price_bound[1] && k*2 < depth.bids.length){ + bid_amount += depth.bids[k*2+1] + k += 1 + } + var my_bid_amount = (ordersInfo.buyPrice < buy_price_bound[0] && ordersInfo.buyPrice >= buy_price_bound[1]) ? Amount : 0 + ratio = _N(10000*Amount*fact/Math.max(bid_amount+Amount-my_bid_amount,Amount),5) + depthInfo.bids.push(['buy_'+groups[i][0]+'-'+groups[i][1]+'%', fact, buy_price_bound[0], buy_price_bound[1], bid_amount, ratio, depth.bids[depth.bids.length-2] <= buy_price_bound[1]]) + if(ratio >= depthInfo.bids[max_bids][5] && depth.bids[depth.bids.length-2] <= buy_price_bound[1]){ + max_bids = depthInfo.bids.length-1 + } + } + return [depthInfo.asks[max_asks][3]-0.5, depthInfo.bids[max_bids][3]+0.5] //由于无法确定边界归属,所以在最大边界价格处-0.5 +} + +function showTable(){ + var table = {type: 'table', title: '挂单信息', cols: ['分组位置', '挖矿系数', '下界价格', '上界价格', '累积深度', '额度占比(万分之一)', '深度信息是否完整'], rows: []} + for(var i=0;i0){ + if(pos[0].Type == 0){ //平多仓,采用盘口吃单,会损失手续费,可改为盘口挂单,会增加持仓风险。 + exchange.SetDirection('sell') + var sellId = exchange.Sell(depth.bids[0], Math.min(CoverAmount, pos[0].Amount), '平多仓') + if(sellId){exchange.CancelOrder(sellId)} //平仓单会立即撤销 + }else{ + exchange.SetDirection('buy') + var buyId = exchange.Buy(depth.asks[0], Math.min(CoverAmount, pos[0].Amount), '平空仓') + if(buyId){exchange.CancelOrder(buyId)} + } + } +} + +function trade(price){ + var sellPrice = price[0] + var buyPrice = price[1] + if(buyPrice != ordersInfo.buyPrice){ + var cancelId = ordersInfo.buyId + exchange.SetDirection('buy') + var buyId = exchange.Buy(buyPrice, Amount) + ordersInfo.buyPrice = buyPrice + if(buyId){ordersInfo.buyId = buyId}else{ordersInfo.buyId = 0} + if(cancelId){exchange.CancelOrder(cancelId)} //先下单后撤单,保证始终有挂单 + } + if(sellPrice != ordersInfo.sellPrice){ + var cancelId = ordersInfo.sellId + exchange.SetDirection('sell') + var sellId = exchange.Sell(sellPrice, Amount) + ordersInfo.sellPrice = sellPrice + if(sellId){ordersInfo.sellId = sellId}else{ordersInfo.sellId = 0} + if(cancelId){exchange.CancelOrder(cancelId)} + } +} + +function main() { + exchange.SetContractType('swap') + exchange.SetMarginLevel(0) //全仓模式 + reset() + while(true){ + var req = HttpQuery(Url+'/v2/market/depth/L150/btcusd_p') //GetDepth默认20档深度,为获取更多深度信息,使用原始API接口 + if(!req){continue} + var depth = JSON.parse(req).data + ordersInfo.minPrice = depth.bids[depth.bids.length-2] + ordersInfo.maxPrice = depth.asks[depth.asks.length-2] + var price = calcDepth(depth) + trade(price) //交易函数 + + if(Date.now()-lastProfitTime > ProfitTime*1000){ + lastProfitTime = Date.now() + var account = exchange.GetAccount() + if(account){ + LogProfit(_N(account.Info.data.BTC[0]+account.Info.data.BTC[1]+account.Info.data.BTC[2],6)) + } + } + if(Date.now()-lastCoverTime > CoverTime*1000){ + lastCoverTime = Date.now() + var pos = exchange.GetPosition() + if(pos){cover(pos,depth)} + } + if(Date.now()-lastRestTime > 10*60*1000){ + lastRestTime = Date.now() + reset() + } + showTable() + Sleep(Intervel*1000) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/171258 + +> 更新时间 + +2019-12-09 11:16:06 diff --git "a/FMEX\347\256\200\345\215\225\346\216\222\345\272\217\346\214\226\347\237\277\346\234\272\345\231\250\344\272\272.md" "b/FMEX\347\256\200\345\215\225\346\216\222\345\272\217\346\214\226\347\237\277\346\234\272\345\231\250\344\272\272.md" new file mode 100644 index 00000000..e402c38a --- /dev/null +++ "b/FMEX\347\256\200\345\215\225\346\216\222\345\272\217\346\214\226\347\237\277\346\234\272\345\231\250\344\272\272.md" @@ -0,0 +1,215 @@ + +> 策略名称 + +FMEX简单排序挖矿机器人 + +> 策略作者 + +小草 + +> 策略描述 + +## 策略原理 + +**策略将会根据当前深度,自动寻找收益最大的挂单位置挂单,未被占用的位置优先,远离盘口优先。达到最大化资金利用。不同深度的挖矿效率可能相差百倍。** + + +**每隔一段时间检查仓位,如果有持仓,每次按盘口价平固定数量(需要自己设置)的仓位,直到不持仓** + +**策略仅供学习参考,按需修改。管理仓位简单,未经长时间测试,欢迎反馈问题,不定期更新** + +**如用于实盘,需要修改参数里的基地址** + +排序挖矿机器人: https://www.fmz.com/strategy/171042 +挂单挖矿机器人: https://www.fmz.com/strategy/171258 +交易挖矿机器人: https://www.fmz.com/strategy/171560 + +FMZ已支持FMEX测试网,需要更新最新的托管者,等10月25号正式网上线后会自动切换。相关问题反馈:https://www.fmz.com/bbs-topic/4476 + +## 问题和改进方向 + +- 仓位管理较为简单,可自行修改。比如改为盘口挂单而不是直接吃单、累积到一定仓位再平等。 +- 挖矿系数可自行定义,如不想挂买一卖一,以及为了避免成交,向后的深度权重可以设置高一点。 +- 没有分散挂单,导致同策略的竞争。后期竞争较大时,可以改进一次挂多组订单。 + +## 排序挖矿说明 + +https://fcoin.zendesk.com/hc/zh-cn/articles/360037685493-FMex%E6%8E%92%E5%BA%8F%E6%8C%96%E7%9F%BF%E7%AE%97%E6%B3%95%E8%AF%B4%E6%98%8E + +排序挖矿全称为“挂单排序挖矿”,为了区别于已存在的“挂单挖矿”,故简称为排序挖矿。 + + +定义每天中的每1分钟为一个排序挖矿周期,每个周期分配交易对当日排序挖矿额度的1/1440。 + + + +每个周期内,随机选取一个时间点,对该交易对买卖盘挂单情况做快照镜像,其中: + +买1 按用户挂单金额占比 分配该排序挖矿周期返还额度的1/4 + +卖1 按用户挂单金额占比 分配该排序挖矿周期返还额度的1/4 + +买2到买11 这10档的挂单,按用户在每1档内的挂单金额占比 分别分配该排序挖矿周期返还额度的1/40 + +卖2到卖11 这10档的挂单,按用户在每1档内的挂单金额占比 分别分配该排序挖矿周期返还额度的1/40 + + + +当日某用户在某交易对的排序挖矿的总返还,为用户在该交易对每个周期排序挖矿所获FMEX返还的总和。 + + + +补充说明: + +1. 必须是当天0点(GMT+8)之后的新挂单,才有参与当日排序挖矿的资格。 + +2. 被排序挖矿快照到(每分钟随机一次)的挂单,如果已经部分成交,仍然按照全部订单金额计算。 + +3. 排序挖矿和现有的交易挖矿、挂单挖矿并存,分别独立返还FMEX。一个订单在满足规则的情况下将可能同时享受多种挖矿返还。 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Intervel|2|休眠时间| +|Amount|10|下单量| +|CoverAmount|2|每次平仓量| +|CoverTime|60|检查仓位并平仓间隔| +|ProfitTime|60|打印收益时间间隔| +|Url|https://api.testnet.fmex.com|API基地址| + + +> 源码 (javascript) + +``` javascript +exchange.IO("base", Url) //切换基地址,方便切换实盘和模拟盘,实盘地址:https://api.fmex.com + +var ordersInfo = {buyId:0, buyPrice:0, sellId:0, sellPrice:0} +var depthInfo = {asks:[], bids:[]} +var lastProfitTime = 0 //控制打印收益时间 +var lastRestTime = Date.now() //定时重置策略 +var lastCoverTime = Date.now() //检查仓位并平仓 + +function calcDepth(depth){ //计算最佳挂单位置 + depthInfo = {asks:[], bids:[]} + var max_asks = 0 + var max_bids = 0 + var ask_price = depth.Asks[0].Price + var bid_price = depth.Bids[0].Price + for(var i=0;i<11;i++){ + var fact = i==0 ? 1/4 : 1/40 //官方的挖矿系数,可按需设置,如离盘口越远越大,减少成交风险 + var my_ask_amount = depth.Asks[i].Price == ordersInfo.sellPrice ? Amount : 0 //排除掉自己订单的干扰 + var my_bid_amount = depth.Bids[i].Price == ordersInfo.buyPrice ? Amount : 0 + while(ask_price <= depth.Asks[i].Price){ //考虑到未被占用的深度位置 + var ask_amount = ask_price == depth.Asks[i].Price ? depth.Asks[i].Amount : 0 + var ratio = _N(10000*Amount*fact/Math.max(ask_amount+Amount-my_ask_amount,Amount),5) //避免因深度更新延时导致除0 + depthInfo.asks.push(['sell_'+(i+1), ask_price, ask_amount, ratio]) + if(ratio >= depthInfo.asks[max_asks][3]){max_asks = depthInfo.asks.length-1} //大于等于保证相同挖矿效率下远离盘口的优先 + ask_price += 0.5 + } + while(bid_price >= depth.Bids[i].Price){ + var bid_amount = bid_price == depth.Bids[i].Price ? depth.Bids[i].Amount : 0 + var ratio = _N(10000*Amount*fact/Math.max(bid_amount+Amount-my_bid_amount,Amount),5) + depthInfo.bids.push(['buy_'+(i+1), bid_price, bid_amount, ratio]) + if(ratio >= depthInfo.bids[max_bids][3]){max_bids = depthInfo.bids.length-1} + bid_price -= 0.5 + } + } + return [depthInfo.asks[max_asks][1], depthInfo.bids[max_bids][1]] +} + +function showTable(){ + var table = {type: 'table', title: '挂单信息', cols: ['位置', '价格', '数量', '额度占比(万分之一)'], rows: []} + for(var i=0;i0){ + if(pos[0].Type == 0){ //平多仓,采用盘口吃单,会损失手续费,可改为盘口挂单,会增加持仓风险。 + exchange.SetDirection('sell') + var sellId = exchange.Sell(depth.Bids[0].Price, Math.min(CoverAmount, pos[0].Amount), '平多仓') + if(sellId){exchange.CancelOrder(sellId)} //平仓单会立即撤销 + }else{ + exchange.SetDirection('buy') + var buyId = exchange.Buy(depth.Asks[0].Price, Math.min(CoverAmount, pos[0].Amount), '平空仓') + if(buyId){exchange.CancelOrder(buyId)} + } + } +} + +function main() { + exchange.SetContractType('swap') + exchange.SetMarginLevel(0) //全仓模式 + reset() + while(true){ + var depth = _C(exchange.GetDepth) + var price = calcDepth(depth) + var sellPrice = price[0] + var buyPrice = price[1] + if(buyPrice != ordersInfo.buyPrice){ + var cancelId = ordersInfo.buyId + exchange.SetDirection('buy') + var buyId = exchange.Buy(buyPrice, Amount) + ordersInfo.buyPrice = buyPrice + if(buyId){ordersInfo.buyId = buyId}else{ordersInfo.buyId = 0} + if(cancelId){exchange.CancelOrder(cancelId)} //先下单后撤单,保证始终有挂单 + } + if(sellPrice != ordersInfo.sellPrice){ + var cancelId = ordersInfo.sellId + exchange.SetDirection('sell') + var sellId = exchange.Sell(sellPrice, Amount) + ordersInfo.sellPrice = sellPrice + if(sellId){ordersInfo.sellId = sellId}else{ordersInfo.sellId = 0} + if(cancelId){exchange.CancelOrder(cancelId)} + } + if(Date.now()-lastProfitTime > ProfitTime*1000){ + lastProfitTime = Date.now() + var account = exchange.GetAccount() + if(account){ + LogProfit(_N(account.Info.data.BTC[0]+account.Info.data.BTC[1]+account.Info.data.BTC[2],6)) + } + } + if(Date.now()-lastCoverTime > CoverTime*1000){ + lastCoverTime = Date.now() + var pos = exchange.GetPosition() + if(pos){cover(pos,depth)} + } + if(Date.now()-lastRestTime > 10*60*1000){ + lastRestTime = Date.now() + reset() + } + showTable() + Sleep(Intervel*1000) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/171042 + +> 更新时间 + +2019-12-09 11:15:15 diff --git "a/Get cryptocurrency current and max supply|\350\216\267\345\217\226\345\270\201\347\247\215\344\276\233\345\272\224\351\207\217.md" "b/Get cryptocurrency current and max supply|\350\216\267\345\217\226\345\270\201\347\247\215\344\276\233\345\272\224\351\207\217.md" index d5eeec72..d1fd494c 100644 --- "a/Get cryptocurrency current and max supply|\350\216\267\345\217\226\345\270\201\347\247\215\344\276\233\345\272\224\351\207\217.md" +++ "b/Get cryptocurrency current and max supply|\350\216\267\345\217\226\345\270\201\347\247\215\344\276\233\345\272\224\351\207\217.md" @@ -5,7 +5,7 @@ Get cryptocurrency current and max supply|获取币种供应量 > 策略作者 -botvsing +小草 > 策略描述 diff --git a/Iceberg Buy Order.md b/Iceberg Buy Order.md index 8843b611..fdf78a19 100644 --- a/Iceberg Buy Order.md +++ b/Iceberg Buy Order.md @@ -5,7 +5,7 @@ Iceberg Buy Order > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/OKex\346\234\237\350\264\247\346\265\213\350\257\225for\346\226\260\346\211\213.md" "b/OKex\346\234\237\350\264\247\346\265\213\350\257\225for\346\226\260\346\211\213.md" new file mode 100644 index 00000000..b76c27c8 --- /dev/null +++ "b/OKex\346\234\237\350\264\247\346\265\213\350\257\225for\346\226\260\346\211\213.md" @@ -0,0 +1,149 @@ + +> 策略名称 + +OKex期货测试for新手 + +> 策略作者 + +tomjava + +> 策略描述 + +OKex期货使用较麻烦,故我写了这么一个框架,方便新用户理解和使用。注意ETH是10美元为一张的。 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Interval|10|轮询周期(秒)| +|mnum|20|30分钟线周期| +|initRatio|0.5|初始仓位比例| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2019-01-01 00:00:00 +end: 2019-10-10 00:00:00 +period: 1d +exchanges: [{"eid":"OKEX","currency":"ETH_USDT","stocks":0}] +args: [["OpMode",1,10989],["MaxAmount",1,10989],["TradeFee",0.001,10989]] +*/ +//注册币乎后https://m.bihu.com/signup?i=1ewtKO&s=4&c=4 +//搜索 物联网区块链 可以联系到作者区班主 +var isInit = 1; //表示初始态 +function oper(){ + var allAmount; + var cashRatio; + var lastPrice; + var wantRatio; + var wantOper=0;//期待的操作,0不操作,1买入,-1卖出 + var mhigh; + var mlow; + + + var mrecords = exchange.GetRecords(PERIOD_M30); + //一定周期内的高低点 + mhigh=TA.Highest(mrecords, mnum, 'High'); + mlow=TA.Lowest(mrecords, mnum, 'Low'); + + var midLine = (mhigh+mlow)/2; + + var ticker = _C(exchange.GetTicker); + var nowPrice=ticker.Sell; + var account = _C(exchange.GetAccount); + var objid; + var order; + + if (isInit == 1) { //初始化状态为默认仓; + /*exchange.SetDirection("sell"); + objid = exchange.Sell(nowPrice,Math.floor(nowPrice*account.Stocks*0.2/10)); //Okex必须取整 + order = exchange.GetOrder(objid); // 参数id为订单号码,需填入你想要查询的订单的号码 + + if (objid) { //如果购买成功 + isInit=2; //初始化成功 + account = _C(exchange.GetAccount); + Log(account); + Log("公允价格",midLine,"高点",mhigh,"低点",mlow); + Log("刚下订单的信息,ID:", order.Id, "Price:", order.Price, "Amount:", order.Amount, + "DealAmount:", order.DealAmount, "type:", order.Type); + }*/ + + exchange.SetDirection("buy"); + objid = exchange.Buy(nowPrice,Math.floor(nowPrice*account.Stocks*0.2/10)); //Okex必须取整 + order = exchange.GetOrder(objid); // 参数id为订单号码,需填入你想要查询的订单的号码 + + if (objid) { //如果购买成功 + isInit=2; //初始化成功 + account = _C(exchange.GetAccount); + Log(account); + Log("公允价格",midLine,"高点",mhigh,"低点",mlow); + Log("刚下订单的信息,ID:", order.Id, "Price:", order.Price, "Amount:", order.Amount, + "DealAmount:", order.DealAmount, "type:", order.Type); + } + + exchange.SetDirection("buy"); + objid = exchange.Buy(nowPrice,Math.floor(nowPrice*account.Stocks*0.2/10)); //Okex必须取整 + order = exchange.GetOrder(objid); // 参数id为订单号码,需填入你想要查询的订单的号码 + + if (objid) { //如果购买成功 + isInit=2; //初始化成功 + account = _C(exchange.GetAccount); + Log(account); + Log("公允价格",midLine,"高点",mhigh,"低点",mlow); + Log("刚下订单的信息,ID:", order.Id, "Price:", order.Price, "Amount:", order.Amount, + "DealAmount:", order.DealAmount, "type:", order.Type); + } + }else if(isInit==2){ //日常操作检测 + //打印未成交仓位 + var orders = _C(exchange.GetOrders); + + for (var i = 0; i < orders.length; i++) { + Log("下单",orders[i]); + } + + var positions = exchange.GetPosition(); + Log("持仓数",positions.length); + for (i = 0; i < positions.length; i++) { //下两张多单会合并成一张单 + if (positions[i].Type == PD_LONG) { + //exchange.SetDirection("closebuy"); + //exchange.Sell(nowPrice,positions[i].Amount); + } else { + // exchange.SetDirection("closesell"); + // exchange.Buy(nowPrice,positions[i].Amount); + } + Log("持仓",positions[i]); + } + //如果没有挂单也没有持单 + if(orders.length<2){//&&positions.length==0){ + isInit=3; + account = _C(exchange.GetAccount); + Log("已成交"); + Log(account); + } + }else{ + } +} + +function main() { + var initAccount = _C(exchange.GetAccount); + Log(initAccount); + exchange.SetContractType("quarter") // 举例设置为OKEX期货当周合约 + exchange.SetMarginLevel(5); // 设置杠杆为5倍 + while (true) { + oper(); + Sleep(Interval*1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/170842 + +> 更新时间 + +2019-11-14 17:03:33 diff --git "a/Push Binance deal order to WeChat|\345\256\236\346\227\266\346\216\250\351\200\201\345\270\201\345\256\211\346\210\220\344\272\244\345\210\260\345\276\256\344\277\241(wss\345\215\217\350\256\256\347\273\203\344\271\240\357\274\211.md" "b/Push Binance deal order to WeChat|\345\256\236\346\227\266\346\216\250\351\200\201\345\270\201\345\256\211\346\210\220\344\272\244\345\210\260\345\276\256\344\277\241(wss\345\215\217\350\256\256\347\273\203\344\271\240\357\274\211.md" index c37f3e22..bb19ee40 100644 --- "a/Push Binance deal order to WeChat|\345\256\236\346\227\266\346\216\250\351\200\201\345\270\201\345\256\211\346\210\220\344\272\244\345\210\260\345\276\256\344\277\241(wss\345\215\217\350\256\256\347\273\203\344\271\240\357\274\211.md" +++ "b/Push Binance deal order to WeChat|\345\256\236\346\227\266\346\216\250\351\200\201\345\270\201\345\256\211\346\210\220\344\272\244\345\210\260\345\276\256\344\277\241(wss\345\215\217\350\256\256\347\273\203\344\271\240\357\274\211.md" @@ -5,7 +5,7 @@ Push Binance deal order to WeChat|实时推送币安成交到微信(wss协议练 > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/Python API \346\265\213\350\257\225.md" "b/Python API \346\265\213\350\257\225.md" index 81730463..bacbc034 100644 --- "a/Python API \346\265\213\350\257\225.md" +++ "b/Python API \346\265\213\350\257\225.md" @@ -16,6 +16,14 @@ Python API 测试 > 源码 (python) ``` python + +'''backtest +start: 2019-09-14 00:00:00 +end: 2019-10-13 00:00:00 +period: 1h +exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] +''' + import sys import time import talib @@ -39,6 +47,7 @@ def main(): else: ret = g[item]() Log('%s => %s' % (item, ret)) + Log(sys.version) testExchanges = [ 'GetName', 'GetUSDCNY', 'GetRate', ['SetRate', 1.0], 'GetAccount', 'GetCurrency', 'GetLabel', 'GetMinStock', 'GetMinPrice', 'GetFee', 'GetRecords', @@ -50,7 +59,7 @@ def main(): ['CancelOrder', 1], ['Buy', -1, 1000.0], 'GetAccount', - ['Sell', -1, 3], + ['Sell', -1, 1], 'GetAccount', ['Sell', 9999.9, 0.2, "OK"], 'GetOrders', @@ -70,9 +79,9 @@ def main(): Log('exchange.%s => %s' % (item, ret)) # test market order - exchange.Buy(1000) - exchange.Buy(-1, 200, "buy 200 RMB") - exchange.Sell(exchange.GetAccount().Stocks) + exchange.Buy(-1, 1000) + exchange.Buy(-1, 200, "buy 200 ") + exchange.Sell(-1, exchange.GetAccount().Stocks) # test Go ret, ok = exchange.Go("GetTicker").wait() if ok: @@ -135,4 +144,4 @@ https://www.fmz.com/strategy/21365 > 更新时间 -2016-12-18 18:00:34 +2019-10-14 12:35:16 diff --git "a/Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.md" "b/Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.md" deleted file mode 100644 index 53ac70d6..00000000 --- "a/Python \345\217\214\345\271\263\345\217\260\345\257\271\345\206\262\347\255\226\347\225\245.md" +++ /dev/null @@ -1,192 +0,0 @@ - -> 策略名称 - -Python 双平台对冲策略 - -> 策略作者 - -Zero - -> 策略描述 - -Python 双平台对冲策略 - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|MinSpreadA|0.51|A->B差价| -|MinSpreadB|0.52|B->A差价| -|MaxAmount|0.3|最大操作量| -|BalanceTime|10|平衡周期(秒)| -|LoopInterval|200|轮询周期(ms)| - - - - -|按钮|默认值|描述| -|----|----|----| -|A->B|0.51|更改价差(A->B)| -|B->A|0.52|更改价差(B->A)| - - -> 源码 (python) - -``` python -import time -import json - -def cancelAll(): - ret = False - for e in exchanges: - while True: - n = 0 - for order in _C(e.GetOrders): - ret = True - e.CancelOrder(order.Id) - n+=1 - if n == 0: - break - return ret - -def main(): - global MinSpreadA, MinSpreadB - SetErrorFilter("canceled") - if len(exchanges) != 2: - raise Exception("只支持两个交易所对冲") - - LogReset() - LogProfitReset() - cancelAll() - - initStocks = 0.0 - initBalance = 0.0 - minAmount = 0.1 - lastTradeTime = 0 - lastTradeErrExchange = '' - accountsCache = [] - hedgeNum = [0, 0] - names = [] - baseCurrency = exchange.GetCurrency() - for e in exchanges: - if e.GetCurrency() != baseCurrency: - raise Exception("必须是同样的货币才可以对冲 " + baseCurrency) - names.append(e.GetName()) - account = _C(e.GetAccount) - accountsCache.append(account) - initStocks += account.Stocks - initBalance += account.Balance - Log("Switch", e.GetLabel(), "To", e.IO("websocket")) - minAmount = 0.01 if baseCurrency == "BTC" else 0.1 - Log("总钱:", _N(initBalance), "总币", _N(initStocks), 'Python:', __import__('sys').version) - while True: - if not accountsCache: - accountsCache = [_C(e.GetAccount) for e in exchanges] - Sleep(LoopInterval) - cmd = GetCommand() - if cmd: - Log("CMD", cmd) - arr = cmd.split(':') - if arr[0] == 'A->B': - MinSpreadA = float(arr[1]) - elif arr[0] == 'B->A': - MinSpreadB = float(arr[1]) - - depthA = exchanges[0].GetDepth() - if not depthA: - continue - depthB = exchanges[1].GetDepth() - if not depthB: - continue - if lastTradeTime > 0 and time.time() - lastTradeTime > BalanceTime: - needUpdate = cancelAll() - if not needUpdate: - for account in accountsCache: - if account.FrozenBalance >= 0.1 or account.FrozenStocks > 0.001: - needUpdate = True - break - if needUpdate: - accountsCache = [_C(e.GetAccount) for e in exchanges] - nowStocks = 0.0 - nowBalance = 0.0 - for account in accountsCache: - nowStocks += account.Stocks - nowBalance += account.Balance - diff = _N(nowStocks - initStocks, 5) - isReverse = None - if abs(diff) < minAmount: - LogProfit(_N(nowBalance-initBalance, 3), "总钱:", _N(nowBalance), "总币", _N(nowStocks), "币差:", diff) - lastTradeTime = 0 - elif diff > minAmount: - isReverse = depthA.Bids[0].Price < depthB.Bids[0].Price - elif -diff > minAmount: - isReverse = depthA.Asks[0].Price > depthB.Asks[0].Price - if isReverse is not None: - depths = [depthA, depthB] - opAmount = None - for pos in ([1, 0] if isReverse else [0, 1]): - if diff >= minAmount: - opAmount = min(diff, accountsCache[pos].Stocks, depths[pos].Bids[0].Amount + depths[pos].Bids[1].Amount) - diff -= opAmount - if opAmount >= minAmount: - exchanges[pos].Sell(depths[pos].Bids[1].Price, opAmount) - elif -diff >= minAmount: - opAmount = min(-diff, _N(accountsCache[pos].Balance / depths[pos].Asks[1].Price, 3), depths[pos].Asks[0].Amount + depths[pos].Asks[1].Amount) - diff += opAmount - if opAmount >= minAmount: - exchanges[pos].Buy(depths[pos].Asks[1].Price, opAmount) - if opAmount is not None: - lastTradeTime = time.time() - accountsCache = [] - continue - # end of balanceAccount - - diffA = _N(depthA.Bids[0].Price - depthB.Asks[0].Price, 3) - diffB = _N(depthB.Bids[0].Price - depthA.Asks[0].Price, 3) - LogStatus('`' + json.dumps({'type': 'table', 'title': '运行信息', 'cols': ['名称', '钱', '冻结的钱', '币', '冻结的币', '买一', '卖一', '阀值', '差价', '次数'], 'rows': [[names[0], accountsCache[0].Balance, accountsCache[0].FrozenBalance, accountsCache[0].Stocks, accountsCache[0].FrozenStocks, depthA.Bids[0].Price, depthA.Asks[0].Price, MinSpreadA, diffA, hedgeNum[0]], [names[1], accountsCache[1].Balance, accountsCache[1].FrozenBalance, accountsCache[1].Stocks, accountsCache[1].FrozenStocks, depthB.Bids[0].Price, depthB.Asks[0].Price, MinSpreadB, diffB, hedgeNum[0]]]}) + '`') - HPos = 0 - if diffA >= MinSpreadA: - orderH = depthA.Bids[0] - orderL = depthB.Asks[0] - exchangeH = exchanges[0] - exchangeL = exchanges[1] - accountH = accountsCache[0] - accountL = accountsCache[1] - elif diffB >= MinSpreadB: - HPos = 1 - orderH = depthB.Bids[0] - orderL = depthA.Asks[0] - exchangeH = exchanges[1] - exchangeL = exchanges[0] - accountH = accountsCache[1] - accountL = accountsCache[0] - else: - continue - - opPrice = _N((orderH.Price + orderL.Price) / 2.0, 2) - opAmount = min(MaxAmount, orderH.Amount, orderL.Amount, accountH.Stocks, _N(accountL.Balance / opPrice, 3)) - if opAmount >= minAmount: - tasks = [[exchangeH.Sell, "H"], [exchangeL.Buy, "L"]] - if lastTradeErrExchange == "L": - tasks.reverse() - lastTradeErrExchange = "" - for task in tasks: - if task[0](opPrice, opAmount) is None: - lastTradeErrExchange = task[1] - break - lastTradeTime = time.time() - accountsCache = [] - hedgeNum[HPos] += 1 - - -``` - -> 策略出处 - -https://www.fmz.com/strategy/21023 - -> 更新时间 - -2016-09-26 11:33:18 diff --git "a/Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.md" "b/Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.md" index 6ba754ca..7f5a769b 100644 --- "a/Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.md" +++ "b/Python \346\234\272\345\231\250\345\255\246\344\271\240\344\271\213 SVM \351\242\204\346\265\213\344\271\260\345\215\226.md" @@ -28,6 +28,13 @@ numpy pandas TA-Lib scipy statsmodels sklearn cvxopt hmmlearn pykalman arch matp > 源码 (python) ``` python +'''backtest +start: 2019-09-06 00:00:00 +end: 2019-10-05 00:00:00 +period: 1h +exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] +''' + from sklearn import svm import numpy as np @@ -125,4 +132,4 @@ https://www.fmz.com/strategy/21370 > 更新时间 -2018-06-05 16:46:36 +2019-10-06 17:54:30 diff --git a/README.md b/README.md index cef58d77..3652858a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,62 @@ > 开源策略 - - [C++商品期货高频交易策略之Penny Jump](https://www.fmz.com/strategy/163427) + - [优先版/FMEX[多头]趋势mining策略,附图,赚币赚钱赚矿](https://www.fmz.com/strategy/178347) + - [8.9 Dual Thrust 区间突破策略 Python 版](https://www.fmz.com/strategy/177504) + - [8.8 增强版唐奇安通道策略](https://www.fmz.com/strategy/176458) + - [8.7 日内高低点突破策略](https://www.fmz.com/strategy/175316) + - [8.6 使用DMI辅助MACD策略](https://www.fmz.com/strategy/174672) + - [8.5 AROON阿隆指标策略](https://www.fmz.com/strategy/173417) + - [8.4 动态阶梯突破策略](https://www.fmz.com/strategy/172610) + - [8.3 经典MACD交易策略](https://www.fmz.com/strategy/171604) + - [8.2 自适应动态双均线策略Python版](https://www.fmz.com/strategy/170551) + - [8.11 菲阿里四价策略](https://www.fmz.com/strategy/179505) + - [fcoin-多空力量排序](https://www.fmz.com/strategy/161034) + - [Deribit期权测试策略](https://www.fmz.com/strategy/179475) + - [8.10 经典恒温器策略](https://www.fmz.com/strategy/179014) + - [恒温器 Thermostat 择时策略研究](https://www.fmz.com/strategy/127033) + - [FMEX[空头]趋势挖矿策略(随机网格排序)](https://www.fmz.com/strategy/178417) + - [FMEX挖矿策略(排序)btc均衡或【震荡版】](https://www.fmz.com/strategy/178700) + - [简单的做市对冲功能](https://www.fmz.com/strategy/178194) + - [深度做市 盘口控制 操盘机器人 做市工具](https://www.fmz.com/strategy/146238) + - [区块链量化投资系列课程(4) - 动态平衡策略](https://www.fmz.com/strategy/110545) + - [区块链量化投资系列课程(3) - 跨期套利](https://www.fmz.com/strategy/104964) + - [FMEX简单挂单挖矿机器人](https://www.fmz.com/strategy/171258) + - [FMEX简单交易挖矿机器人](https://www.fmz.com/strategy/171560) + - [FMEX简单排序挖矿机器人](https://www.fmz.com/strategy/171042) + - [商品期货布林指标突破策略(教学)](https://www.fmz.com/strategy/177584) + - [暴雪网格-7*24小时交易机器人](https://www.fmz.com/strategy/175807) + - [根据商品期货计划委托工具实现一个短线策略(教学)](https://www.fmz.com/strategy/176022) + - [自适应动态双均线策略My语言版](https://www.fmz.com/strategy/170606) + - [商品期货计划委托工具(教学)](https://www.fmz.com/strategy/175150) + - [牛熊猴市判断V1.0_区班主](https://www.fmz.com/strategy/170014) + - [OKex期货测试for新手](https://www.fmz.com/strategy/170842) + - [教学策略TCI策略(麦语言移植)](https://www.fmz.com/strategy/174457) + - [牛熊小卖部策略V1.0_OKex合约](https://www.fmz.com/strategy/171038) + - [简单预定买入后卖出机器人|Buy then Sell (ping-pong strategy)](https://www.fmz.com/strategy/121228) + - [单商品小卖部策略V2.0_年化130%](https://www.fmz.com/strategy/170557) + - [经典均线策略V1.0_区班主注释简化](https://www.fmz.com/strategy/169569) + - [Python API 测试](https://www.fmz.com/strategy/21365) + - [单货币动态均衡V1.0_区班主](https://www.fmz.com/strategy/169701) + - [利用回归幅度构建多品种反转策略](https://www.fmz.com/strategy/69937) + - [经典均线策略](https://www.fmz.com/strategy/12348) + - [简单多品种商品期货均线策略](https://www.fmz.com/strategy/57029) + - [Python 机器学习之 SVM 预测买卖](https://www.fmz.com/strategy/21370) + - [抛物线转向SAR与价格高低点策略](https://www.fmz.com/strategy/168073) + - [SeamlessConnWS](https://www.fmz.com/strategy/167755) + - [多级百分比止盈策略](https://www.fmz.com/strategy/166753) + - [裸K上下影线在交易策略中的应用](https://www.fmz.com/strategy/165130) + - [C++期货高频套币策略OKEX Websocket版](https://www.fmz.com/strategy/163447) + - [期货看穿式测试](https://www.fmz.com/strategy/152670) + - [移植 OKCoin 韭菜收割机](https://www.fmz.com/strategy/34388) + - [数字货币期货现货差价监控](https://www.fmz.com/strategy/164680) + - [基于期货基本面分析的交易策略](https://www.fmz.com/strategy/161412) + - [香农网格)](https://www.fmz.com/strategy/164257) + - [单点狙击高频加仓自动反手解套算法](https://www.fmz.com/strategy/164256) + - [马丁格尔网格btc](https://www.fmz.com/strategy/164255) + - [肯特纳通道升级版金肯特纳kingkeltner策略](https://www.fmz.com/strategy/164250) + - [单边网格x现货](https://www.fmz.com/strategy/164251) + - [单边网格 (OK期货)](https://www.fmz.com/strategy/164252) - [多线程批量任务](https://www.fmz.com/strategy/159978) - [HFT strategy](https://www.fmz.com/strategy/162372) - [MACD画图范例](https://www.fmz.com/strategy/151972) @@ -17,17 +72,13 @@ - [双均线策略与相对强弱RSI指标组合|Combination of Double MA and RSI](https://www.fmz.com/strategy/128250) - [动向指数(DMI)与高低点策略|DMI and High-Low Strategy](https://www.fmz.com/strategy/128418) - [瀑布线策略|PBX Strategy](https://www.fmz.com/strategy/128420) - - [基于期货基本面分析的交易策略](https://www.fmz.com/strategy/161412) - [做市策略(basefex)](https://www.fmz.com/strategy/162413) - - [测试图表](https://www.fmz.com/strategy/162093) - [钉钉推送](https://www.fmz.com/strategy/159668) - [火币点卡](https://www.fmz.com/strategy/162055) - [时间格式工具](https://www.fmz.com/strategy/161505) - [能量潮OBV在量化交易中的详细用法和实战技巧](https://www.fmz.com/strategy/159997) - [火币精度](https://www.fmz.com/strategy/159104) - - [简单多品种商品期货均线策略 (Copy)](https://www.fmz.com/strategy/159506) - [交易所最小数量和精度](https://www.fmz.com/strategy/108887) - - [期货看穿式测试](https://www.fmz.com/strategy/152670) - [肯特纳通道升级版金肯特纳kingkeltner策略](https://www.fmz.com/strategy/159285) - [基于箱体理论的交易策略,支持商品期货和数字货币](https://www.fmz.com/strategy/158088) - [多交易所集合行情/下单 策略 范例](https://www.fmz.com/strategy/125569) @@ -59,11 +110,9 @@ - [DMI 测试范例](https://www.fmz.com/strategy/154050) - [动态平衡策略 python 版](https://www.fmz.com/strategy/152830) - [麦语言网格策略](https://www.fmz.com/strategy/142701) - - [annotation属性](https://www.fmz.com/strategy/149661) - [日志|Logger](https://www.fmz.com/strategy/151754) - [三角套利-基础版](https://www.fmz.com/strategy/151145) - [期货反手加倍算法](https://www.fmz.com/strategy/3648) - - [FCoin杠杆交易模板](https://www.fmz.com/strategy/151157) - [每日市价定投](https://www.fmz.com/strategy/151259) - [2014年的简易比特币高频策略机器人](https://www.fmz.com/strategy/1088) - [三角套利策略体验版](https://www.fmz.com/strategy/149489) @@ -75,8 +124,6 @@ - [Deribit websocket 范例](https://www.fmz.com/strategy/147765) - [python 状态栏表格 显示按钮范例](https://www.fmz.com/strategy/147155) - [boll+maboll](https://www.fmz.com/strategy/146391) - - [深度做市](https://www.fmz.com/strategy/146238) - - [单边网格 (Copy)](https://www.fmz.com/strategy/144679) - [websocket 版OKEX跨期对冲策略(教学)](https://www.fmz.com/strategy/144378) - [rest 版OKEX跨期对冲策略(教学)](https://www.fmz.com/strategy/144406) - [60行三角对冲策略(教学)](https://www.fmz.com/strategy/144257) @@ -84,7 +131,6 @@ - [简单均线策略|Moving Average Bot 30 lines](https://www.fmz.com/strategy/103070) - [MACD Cpp Demo](https://www.fmz.com/strategy/142259) - [KDJ Cpp Demo](https://www.fmz.com/strategy/142260) - - [恒温器 Thermostat 择时策略研究](https://www.fmz.com/strategy/127033) - [API 测试新手入门](https://www.fmz.com/strategy/4) - [基于随机森林的趋势策略](https://www.fmz.com/strategy/140199) - [海龟汤策略](https://www.fmz.com/strategy/139249) @@ -129,8 +175,6 @@ - [MA5](https://www.fmz.com/strategy/125474) - [移植 OKCoin 韭菜收割机 注释](https://www.fmz.com/strategy/124178) - [指数均衡策略 (教学)](https://www.fmz.com/strategy/120581) - - [简单预定买入后卖出机器人|Buy then Sell (ping-pong strategy)](https://www.fmz.com/strategy/121228) - - [经典均线策略](https://www.fmz.com/strategy/12348) - [闪崩机器人 (教学)](https://www.fmz.com/strategy/118939) - [模拟测试kdj](https://www.fmz.com/strategy/119057) - [BTC-V反策略](https://www.fmz.com/strategy/117202) @@ -153,8 +197,6 @@ - [50行多平台对冲策略(教学)](https://www.fmz.com/strategy/113278) - [Dual Thrust OKEX期货 (教学)](https://www.fmz.com/strategy/112425) - [[VNC] SVM Test](https://www.fmz.com/strategy/112188) - - [区块链量化投资系列课程(3) - 跨期套利](https://www.fmz.com/strategy/104964) - - [区块链量化投资系列课程(4) - 动态平衡策略](https://www.fmz.com/strategy/110545) - [单平台均衡策略](https://www.fmz.com/strategy/345) - [商品期货跨期对冲 - 单品种套利合约](https://www.fmz.com/strategy/27122) - [新手上路CoinEx交易 (LTC_USDT)](https://www.fmz.com/strategy/103464) @@ -167,7 +209,6 @@ - [币安出售所有山寨币](https://www.fmz.com/strategy/97629) - [商品期货 - 形态策略(增强型锤子)](https://www.fmz.com/strategy/97130) - [追涨杀跌](https://www.fmz.com/strategy/96634) - - [Python 机器学习之 SVM 预测买卖](https://www.fmz.com/strategy/21370) - [Python简单测试策略](https://www.fmz.com/strategy/20761) - [破冰者](https://www.fmz.com/strategy/9929) - [Dual Thrust OKCoin 期货](https://www.fmz.com/strategy/12101) @@ -183,8 +224,6 @@ - [python版CTP商品期货交易类库(支持2/3 测试版)](https://www.fmz.com/strategy/24288) - [指数量化](https://www.fmz.com/strategy/91704) - [顺大势逆小势策略之代码实现及可行性分析](https://www.fmz.com/strategy/59356) - - [判断MA线的排列 - btcdw](https://www.fmz.com/strategy/89969) - - [基于回归幅度的反转交易策略](https://www.fmz.com/strategy/69937) - [单边网格](https://www.fmz.com/strategy/88472) - [okex币币最小交易量](https://www.fmz.com/strategy/88754) - [基于CCI周期性区间交易策略](https://www.fmz.com/strategy/60287) @@ -212,7 +251,6 @@ - [定投简单版](https://www.fmz.com/strategy/67098) - [回测保存K线到本地CSV](https://www.fmz.com/strategy/61867) - [bitfinex保证金交易](https://www.fmz.com/strategy/57333) - - [简单多品种商品期货均线策略](https://www.fmz.com/strategy/57029) - [测试 默认 参数组功能](https://www.fmz.com/strategy/40155) - [全球10大交易系统之 Aberration 多品种商品期货交易系统](https://www.fmz.com/strategy/25943) - [Dual Thrust 商品期货](https://www.fmz.com/strategy/13011) @@ -244,11 +282,9 @@ - [js R-Breaker](https://www.fmz.com/strategy/36195) - [JS版本Dual Thrust](https://www.fmz.com/strategy/36100) - [图表界面信息展示实例1](https://www.fmz.com/strategy/36026) - - [移植 OKCoin 韭菜收割机](https://www.fmz.com/strategy/34388) - [R-Breaker11 交易策略](https://www.fmz.com/strategy/23874) - [比特币现货阶梯差价对冲](https://www.fmz.com/strategy/30573) - [范例-定时测试微信消息推送](https://www.fmz.com/strategy/15098) - - [Python API 测试](https://www.fmz.com/strategy/21365) - [从第三方获取K线 (商品期货版) Rev. 161216](https://www.fmz.com/strategy/15498) - [商品期货跨期对冲 - 百行代码实现](https://www.fmz.com/strategy/23896) - [短信通知类库](https://www.fmz.com/strategy/26921) @@ -256,7 +292,6 @@ - [高频收割机一号](https://www.fmz.com/strategy/6237) - [R-Breaker 交易策略](https://www.fmz.com/strategy/23531) - [均线策略(python版)](https://www.fmz.com/strategy/21157) - - [Python 双平台对冲策略](https://www.fmz.com/strategy/21023) - [各大平台API可用率统计](https://www.fmz.com/strategy/4404) - [均线-趋势_数字货币策略V0.2](https://www.fmz.com/strategy/21369) - [高频交易策略之 - Penny Jump](https://www.fmz.com/strategy/358) diff --git a/SeamlessConnWS.md b/SeamlessConnWS.md new file mode 100644 index 00000000..7960d8ad --- /dev/null +++ b/SeamlessConnWS.md @@ -0,0 +1,260 @@ + +> 策略名称 + +SeamlessConnWS + +> 策略作者 + +小小梦 + +> 策略描述 + +https://www.fmz.com/bbs-topic/4328 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|IsUsedWebSocket|false|是否启用WebSocket| +|Hook_GetTicker|false|Hook行情接口GetTicker| + + +> 源码 (javascript) + +``` javascript +function WSConnecter_Huobi (method, symbol) { + // wss : wss://api.huobi.pro/ws + /* Subscribe + { + "sub": "market.btcusdt.detail", + } + */ + /* Subscribe string + '{"sub": "market.btcusdt.detail"}' + */ + + var strSubscribe = "" + if (method == "GetTicker") { + symbol = symbol.toLowerCase() + symbol = symbol.replace("_", "") + strSubscribe = '{"sub": "market.' + symbol + '.detail"}' // symbol : btcusdt + } else { + throw "未实现:" + method + "方法!" + } + + var self = {} + self.method = method + self.pingCount = 0 + Log("Dial函数链接:", "wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + strSubscribe) + Log("订阅信息:", strSubscribe) + self.client = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + strSubscribe) + self.client.write(strSubscribe) + + self.Read = function () { + try { + var ret = self.client.read() + var objRet = JSON.parse(ret) + if (objRet.ping) { + var pong = {"pong" : objRet.ping} + // Log("huobiConn 收到心跳包,发送pong:", JSON.stringify(pong)) + self.client.write(JSON.stringify(pong)) + self.pingCount++ + return null + } else { + /* 封装成FMZ的ticker结构 + { + "ch":"market.btcusdt.detail", + "ts":1569477791639, + "tick":{ + "id":205028275148, + "low":8217, + "high":8624.87, + "open":8517.89, + "close":8386.36, + "vol":361804831.52344716, + "amount":43197.45945060976, + "version":205028275148, + "count":335763 + } + } + */ + var ticker = {} + if (!objRet.tick) { + return null + } + + ticker.Info = objRet.tick + ticker.High = objRet.tick.high + ticker.Low = objRet.tick.low + ticker.Last = objRet.tick.close + ticker.Volume = objRet.tick.vol + ticker.Buy = objRet.tick.close + ticker.Sell = objRet.tick.close + ticker.Time = objRet.ts + + return ticker + } + } catch (e) { + Log("error:", e) + return null + } + } + + self.Close = function () { + self.client.close() + Log("method:", self.method, "断开ws链接") + } + + return self +} + +function WSConnecter_Binance (method, symbol) { + // wss : wss://stream.binance.com:9443 + // /ws/ + // Stream 名称: @ticker + // /ws/btcusdt@ticker + + var strSubscribe = "" + if (method == "GetTicker") { + symbol = symbol.toLowerCase() + symbol = symbol.replace("_", "") + strSubscribe = "/ws/" + symbol + "@ticker" + } else { + throw "未实现:" + method + "方法!" + } + + var self = {} + self.pingCount = 0 + self.method = method + Log("Dial函数链接:", "wss://stream.binance.com:9443" + strSubscribe + "|reconnect=true") + self.client = Dial("wss://stream.binance.com:9443" + strSubscribe + "|reconnect=true") + + self.Read = function () { + try { + var ret = self.client.read() + var objRet = JSON.parse(ret) + if (objRet.ping) { + var pong = {"pong" : objRet.ping} + Log("binanceConn 收到心跳包,发送pong:", JSON.stringify(pong)) + self.client.write(JSON.stringify(pong)) + self.pingCount++ + return null + } else { + /* + { + "e":"24hrTicker", + "E":1569479950378, + "s":"BTCUSDT", + "p":"-72.67000000", + "P":"-0.855", + "w":"8380.87678669", + "x":"8504.99000000", + "c":"8430.98000000", + "Q":"0.10865300", + "b":"8430.02000000", // Buy1 + "B":"2.00000000", + "a":"8431.00000000", + "A":"0.24020700", + "o":"8503.65000000", + "h":"8629.96000000", + "l":"8215.64000000", + "v":"52091.18312400", + "q":"436569787.43499342", + "O":1569393550372, + "C":1569479950372, + "F":182689950, + "L":183168699, + "n":478750 + } + */ + + var ticker = {} + ticker.Info = objRet + ticker.Buy = objRet.b + ticker.Sell = objRet.a + ticker.High = objRet.h + ticker.Low = objRet.l + ticker.Volume = objRet.v + ticker.Last = objRet.c + ticker.Time = objRet.E + + Log("推送行情:", ticker) // 测试 + + return ticker + } + } catch (e) { + Log("error:", e) + return null + } + } + + self.Close = function () { + self.client.close() + Log("断开ws链接") + } + + return self +} + + +var _DictConnectCreater = { + "Huobi" : WSConnecter_Huobi, + "Binance" : WSConnecter_Binance, +} + +var _ConnMap = {} + +function init () { + if (IsUsedWebSocket) { + var connectCreater = null + if (exchanges.length != 1) { + Log("切换为ws接口只针对 exchange 交易所对象(即第一个添加的交易所对象)") + } + var isFound = false + for (var name in _DictConnectCreater) { + if (exchange.GetName() == name) { + connectCreater = _DictConnectCreater[name] + isFound = true + } + } + + if (!isFound) { + throw "没有找到实现" + } + + if (Hook_GetTicker) { + var symbol = exchange.GetCurrency() + _ConnMap.GetTicker = connectCreater("GetTicker", symbol) + exchange.GetTicker = function () { + return _C(_ConnMap.GetTicker.Read) + } + } + // ... + + } +} + +/* 不会触发 +function onexit(){ + for (var method in _ConnMap) { + _ConnMap[method].Close() + } +} +*/ + +// 测试 +function main () { + + +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/167755 + +> 更新时间 + +2019-09-26 17:00:42 diff --git "a/annotation\345\261\236\346\200\247.md" "b/annotation\345\261\236\346\200\247.md" deleted file mode 100644 index 41f7c83c..00000000 --- "a/annotation\345\261\236\346\200\247.md" +++ /dev/null @@ -1,249 +0,0 @@ - -> 策略名称 - -annotation属性 - -> 策略作者 - -量化新人 - -> 策略描述 - -BotVS支持策略同时展现多个图表, 这是一个简单的例子. 如果不能正常展示, 请清空浏览器缓存后刷新 - - - -> 源码 (javascript) - -``` javascript -/*backtest -start: 2019-01-22 00:00:00 -end: 2019-01-23 00:00:00 -period: 30m -exchanges: [{"eid":"OKCoin_EN","currency":"BTC_USD"}] -*/ -// function main() { -// var cfgA = { -// extension: { -// layout: 'single', // 不参于分组,单独显示, 默认为分组 'group' -// height: 300, // 指定高度 -// }, -// title: { -// text: '盘口图表' -// }, -// xAxis: { -// type: 'datetime' -// }, -// series: [{ -// name: '买一', -// data: [], -// }, { -// name: '卖一', -// data: [], -// }] -// } -// var cfgB = { -// title: { -// text: '差价图' -// }, -// xAxis: { -// type: 'datetime' -// }, -// series: [{ -// name: '差价', -// type: 'column', -// data: [], -// }], -// annotations: [{ -// shapes: [{ -// point: '0', -// type: 'circle', -// r: 10 -// }, { -// point: '3', -// type: 'rect', -// width: 20, -// height: 20, -// x: -10, -// y: -25 -// }], -// labels: [{ -// point: { -// x: 6, -// y: 195, -// xAxis: 0, -// yAxis: 0 -// } -// }] -// }] -// } - -// var cfgC = { -// __isStock: false, -// title: { -// text: '饼图' -// }, -// series: [{ -// type: 'pie', -// name: 'one', -// data: [ -// ["A", 25], -// ["B", 25], -// ["C", 25], -// ["D", 25], -// ] // 指定初始数据后不需要用add函数更新, 直接更改图表配置就可以更新序列. -// }] -// }; -// var cfgD = { -// extension: { -// layout: 'single', -// col: 8, // 指定宽度占的单元值, 总值 为12 -// height: '300px', -// }, -// title: { -// text: '盘口图表' -// }, -// xAxis: { -// type: 'datetime' -// }, -// series: [{ -// name: '买一', -// data: [], -// }, { -// name: '卖一', -// data: [], -// }] -// } -// var cfgE = { -// __isStock: false, -// extension: { -// layout: 'single', -// col: 4, -// height: '300px', -// }, -// title: { -// text: '饼图2' -// }, -// series: [{ -// type: 'pie', -// name: 'one', -// data: [ -// ["A", 25], -// ["B", 25], -// ["C", 25], -// ["D", 25], -// ] -// }] -// }; - -// var chart = Chart([cfgA, cfgB, cfgC, cfgD, cfgE]); -// chart.reset() -// // 为饼图清加一个数点,add只能更新通过add方式添加的数据点, 内置的数据点无法后期更新 -// chart.add(3, { -// name: "ZZ", -// y: 25 -// }); -// while (true) { -// Sleep(1000) -// var ticker = exchange.GetTicker() -// if (!ticker) { -// continue; -// } -// var diff = ticker.Sell - ticker.Buy -// cfgA.subtitle = { -// text: '买一 ' + ticker.Buy + ', 卖一 ' + ticker.Sell, -// }; -// cfgB.subtitle = { -// text: '价差 ' + diff, -// }; - -// chart.add([0, [ ticker.Buy]]); -// chart.add([1, [ ticker.Sell]]); -// // 相当于更新第二个图表的第一个数据序列 -// chart.add([2, [new Date().getTime(), diff]]); -// chart.add(4, [new Date().getTime(), ticker.Buy]); -// chart.add(5, [new Date().getTime(), ticker.Buy]); -// cfgC.series[0].data[0][1] = 789 -// cfgE.series[0].data[0][1] = 789 -// // update实际上等于重置了图表的配置 -// chart.update([cfgA, cfgB, cfgC, cfgD, cfgE]); -// } -// } -var cfgA = { - extension: { - layout: 'single', // 不参于分组,单独显示, 默认为分组 'group' - height: 300, // 指定高度 - col: 8, // 指定宽度占的单元值, 总值 为12 - }, - title: { - text: 'stock' - }, - - series: [ // 数据系列,该属性保存的是 各个 数据系列(线, K线图, 标签等..) - { - type: 'candlestick', - name: "line1", - data: [] - }, // 索引为0, data 数组内存放的是该索引系列的 数据 ] - { - type: 'flags', - data: [{ - x: 1548170700000, - y: 3575.8, - title: '1卖', - text: 'Shape: "squarepin"' - }], - onSeries: 'dataseries', - shape: 'squarepin', - width: 16 - }, - ], - annotations: [{ - shapes: [{ - fill: 'none', - stroke: 'red', - strokeWidth: 3, - type: 'path', - points: [{ - x: 1548167400000, - y: 3562.59, - - }, { - x: 1548171000000, - y: 3561.34, - - }], - }] - }] - -} - -function main() { - var ObjChart = Chart(cfgA); // 调用 Chart 函数,初始化 图表。 - ObjChart.reset(); // 清空 - var recordsArr = [] - while (true) { - var nowTime = new Date().getTime(); // 获取本次轮询的 时间戳, 即一个 毫秒 的时间戳。用来确定写入到图表的X轴的位置。 - // var ticker = _C(exchange.GetTicker); // 获取行情数据 - var records = _C(exchange.GetRecords, PERIOD_M30) - var lastKline = records[records.length - 1] - Log("ticker:", lastKline) - - - var newItem = [lastKline.Time, lastKline.Open, lastKline.High, lastKline.Low, lastKline.Close] - recordsArr.push(newItem) - - cfgA.series[0].data = recordsArr - ObjChart.update(cfgA); - Sleep(2000); - } -} -``` - -> 策略出处 - -https://www.fmz.com/strategy/149661 - -> 更新时间 - -2019-06-21 14:19:14 diff --git "a/fcoin-\345\244\232\347\251\272\345\212\233\351\207\217\346\216\222\345\272\217.md" "b/fcoin-\345\244\232\347\251\272\345\212\233\351\207\217\346\216\222\345\272\217.md" new file mode 100644 index 00000000..9c578560 --- /dev/null +++ "b/fcoin-\345\244\232\347\251\272\345\212\233\351\207\217\346\216\222\345\272\217.md" @@ -0,0 +1,253 @@ + +> 策略名称 + +fcoin-多空力量排序 + +> 策略作者 + +小天才收割机 + +> 策略描述 + +fcoin挖矿策略 +盘口多空比排序挖矿 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Interval|1000|出错重试间隔(毫秒)| +|LoopInterval|0.1|轮询间隔(秒)| +|Step|0.1|网格间隔(元)| +|Lot|0.005|手数| +|MaxNets|6|最大网格数| +|DisableLog|false|关闭订单跟踪| +|MinStock|0.01|最小交易币数| +|amountPrecision|4|数量精度| +|pricePrecision|true|价格精度| +|level|true|计算均价深度| +|BUY_START_LEVEL|5|买单起始深度| +|SELL_START_LEVEL|5|卖单起始深度| +|ratioThresh|2|挂单量比值阈值| +|DepthLevel|6|统计深度| + + +> 源码 (javascript) + +``` javascript + +function CancelPendingOrders() { + var orders = _C(exchange.GetOrders); + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]); + } +} + +function onexit() { + CancelPendingOrders(); + Sleep(100); + Log("exit"); +} + +var initPrice = _C(exchange.GetTicker).Buy; +var currency = _C(exchange.GetCurrency); + +if(currency == "BTC_USDT") { + MinStock = 0.005; + amountPrecision = 4; + pricePrecision = 1; +} else if(currency == "ETH_USDT") { + MinStock = 0.05; + amountPrecision = 4; + pricePrecision = 2; +} else if(currency == "LTC_USDT") { + MinStock = 0.5; + amountPrecision = 4; + pricePrecision = 2; +} else if(currency == "EOS_USDT") { + MinStock = 1; + amountPrecision = 4; + pricePrecision = 3; +} else if(currency == "XRP_USDT") { + MinStock = 10; + amountPrecision = 2; + pricePrecision = 4; +} else if(currency == "BCH_USDT") { + MinStock = 0.05; + amountPrecision = 4; + pricePrecision = 1; +} + +Step = 1 / Math.pow(10, pricePrecision); +MaxNets = 50; + +function updateProfit(accountInit, accountNow, ticker) { + var netNow = accountNow.Balance + accountNow.FrozenBalance + ((accountNow.Stocks + accountNow.FrozenStocks) * ticker.Buy); + var netInit = accountInit.Balance + accountInit.FrozenBalance + ((accountInit.Stocks + accountInit.FrozenStocks) * initPrice); + LogProfit(_N(netNow - netInit, 2)); +} + +var LastOrdersLength = null; + +var initAccount = _C(exchange.GetAccount); +var initPrice = _C(exchange.GetTicker).Last; +var initInUSD = _N(initAccount.Stocks * initPrice + initAccount.Balance, 2); + +function calcDepth(orders) { + var base = parseInt(orders[0].Price); + var allAmount = 0; + var n = 0; + for (var i = 0; i < orders.length && n < DepthLevel; i++) { + var p = parseInt(orders[i].Price); + if (p != base) { + n++; + base = p; + } + allAmount += orders[i].Amount; + } + return allAmount; +} + +function onTick() { + var ticker = _C(exchange.GetTicker); + var account = _C(exchange.GetAccount); + var orders = _C(exchange.GetOrders); + var depth = _C(exchange.GetDepth); + if (LastOrdersLength != null && LastOrdersLength != orders.length) { + updateProfit(initAccount, account, ticker); + } + LastOrdersLength = orders.length; + + var currentInUSD = _N(account.Stocks * ticker.Last + account.Balance, 2); + LogProfit(currentInUSD - initInUSD, "&"); + + var msg = ""; + msg += "lastPrice = " + ticker.Last + "\n" + + "初始币:" + initAccount.Stocks + ",初始钱:" + initAccount.Balance + ", initUSD:" + initInUSD + "\n" + + "当前币:" + account.Stocks + ",当前钱:" + account.Balance + ", currentUSD:" + currentInUSD; + + // 多空力量对比 + var asksAmount = calcDepth(depth.Asks); + var bidsAmount = calcDepth(depth.Bids); + var ratio = Math.max(asksAmount/bidsAmount, bidsAmount/asksAmount); + ratio = asksAmount > bidsAmount ? ratio : -ratio; + var buy_start_level = BUY_START_LEVEL; + var sell_start_level = SELL_START_LEVEL; + if(ratio > ratioThresh) { + buy_start_level = 1; + sell_start_level = 6; + } else if(ratio <= -2) { + sell_start_level = 1; + buy_start_level = 6; + } + + //var buy = depth.Bids[level].Price; + //var sell = depth.Asks[level].Price; + // 盘口上下加权平均 + var avg_buy = 0; + var buy_amount = 0; + var avg_sell = 0; + var sell_amount = 0; + for(var i = 1; i <= level; ++i) { + avg_buy += depth.Bids[i - 1].Price * depth.Bids[i - 1].Amount; + buy_amount += depth.Bids[i - 1].Amount; + avg_sell += depth.Asks[i - 1].Price * depth.Asks[i - 1].Amount; + sell_amount += depth.Asks[i - 1].Amount; + } + var buy = _N(avg_buy / buy_amount, pricePrecision); + var sell = _N(avg_sell / sell_amount, pricePrecision); + + //var mid = adjustFloat(ticker.Buy + ((ticker.Sell - ticker.Buy) / 2)); + var mid = _N(buy + ((sell - buy) / 2), pricePrecision); + // var numBuy = parseInt(Math.min(MaxNets / 2 , (mid - buy) / Step, account.Balance / buy / Lot)); + var numBuy = parseInt(Math.min(MaxNets / 2, account.Balance / buy / Lot)); + var numSell = parseInt(Math.min(MaxNets / 2, account.Stocks / Lot)); + var num = Math.max(numBuy, numSell); + + msg += "\nticker.sell = " + ticker.Sell + ", ticker.buy = " + ticker.Buy + + ", mid = " + _N((ticker.Buy + ticker.Sell) / 2, pricePrecision) + "\n" + + "avg_sell = " + sell + ", avg_buy = " + buy + ", mid = " + mid; + msg += "\n多/空 = " + ratio; + LogStatus(msg); + + var ordersKeep = []; + var queue = []; + for(var i = buy_start_level; i < numBuy + buy_start_level; ++i) { + var buyPrice = _N(mid - (i * Step), pricePrecision); + var alreadyBuy = false; + for (j = 0; j < orders.length; j++) { + if (orders[j].Type == ORDER_TYPE_BUY) { + if (Math.abs(orders[j].Price - buyPrice) < (Step / 2)) { + alreadyBuy = true; + ordersKeep.push(orders[j].Id); + } + } + } + if ((!alreadyBuy) && (i < numBuy)) { + queue.push([buyPrice, ORDER_TYPE_BUY]); + } + } + + for(var i = sell_start_level; i < numSell + sell_start_level; ++i) { + var sellPrice = _N(mid + (i * Step), pricePrecision); + var alreadySell = false; + for (j = 0; j < orders.length; j++) { + if (orders[j].Type == ORDER_TYPE_SELL) { + if (Math.abs(orders[j].Price - sellPrice) < (Step / 2)) { + alreadySell = true; + ordersKeep.push(orders[j].Id); + } + } + } + if ((!alreadySell) && (i < numSell)) { + queue.push([sellPrice, ORDER_TYPE_SELL]); + } + } + + for (var i = 0; i < orders.length; i++) { + var keep = false; + for (var j = 0; j < ordersKeep.length; j++) { + if (orders[i].Id == ordersKeep[j]) { + keep = true; + } + } + if (!keep) { + exchange.CancelOrder(orders[i].Id); + LastOrdersLength--; + } + } + + for (var i = 0; i < queue.length; i++) { + if (queue[i][1] == ORDER_TYPE_BUY) { + exchange.Buy(_N(queue[i][0], pricePrecision), Lot); + } else { + exchange.Sell(_N(queue[i][0], pricePrecision), Lot); + } + LastOrdersLength++; + } +} + +function main() { + if (DisableLog) { + EnableLog(false); + } + Log(initAccount); + LoopInterval = Math.max(LoopInterval, 1); + // Lot = Math.max(MinStock, Lot); + Lot = MinStock; + while (true) { + onTick(); + Sleep(LoopInterval * 1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/161034 + +> 更新时间 + +2019-12-26 11:24:50 diff --git "a/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.md" "b/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.md" index c605b92f..dec7c6b9 100644 --- "a/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.md" +++ "b/fcoin\346\214\226\347\237\277\346\274\224\347\244\272.md" @@ -5,7 +5,7 @@ fcoin挖矿演示 > 策略作者 -华丽转身 +张超 > 策略描述 diff --git "a/\344\270\211\350\247\222\345\245\227\345\210\251-\345\237\272\347\241\200\347\211\210.md" "b/\344\270\211\350\247\222\345\245\227\345\210\251-\345\237\272\347\241\200\347\211\210.md" index b0e3f762..67993804 100644 --- "a/\344\270\211\350\247\222\345\245\227\345\210\251-\345\237\272\347\241\200\347\211\210.md" +++ "b/\344\270\211\350\247\222\345\245\227\345\210\251-\345\237\272\347\241\200\347\211\210.md" @@ -5,7 +5,7 @@ > 策略作者 -cruiselijq +红色的雪 diff --git "a/\344\274\230\345\205\210\347\211\210-FMEX[\345\244\232\345\244\264]\350\266\213\345\212\277mining\347\255\226\347\225\245\357\274\214\351\231\204\345\233\276\357\274\214\350\265\232\345\270\201\350\265\232\351\222\261\350\265\232\347\237\277.md" "b/\344\274\230\345\205\210\347\211\210-FMEX[\345\244\232\345\244\264]\350\266\213\345\212\277mining\347\255\226\347\225\245\357\274\214\351\231\204\345\233\276\357\274\214\350\265\232\345\270\201\350\265\232\351\222\261\350\265\232\347\237\277.md" new file mode 100644 index 00000000..5274b8b6 --- /dev/null +++ "b/\344\274\230\345\205\210\347\211\210-FMEX[\345\244\232\345\244\264]\350\266\213\345\212\277mining\347\255\226\347\225\245\357\274\214\351\231\204\345\233\276\357\274\214\350\265\232\345\270\201\350\265\232\351\222\261\350\265\232\347\237\277.md" @@ -0,0 +1,332 @@ + +> 策略名称 + +优先版-FMEX[多头]趋势mining策略,附图,赚币赚钱赚矿 + +> 策略作者 + +古力十段 + +> 策略描述 + +**FMex排序挖矿多头版本代码使用说明** + +(注意api地址)(另有加强版-增加仓位管理-增加时间设定,调整单量方向等-购买联系微信:ying5737)讨论联系微信:ying5737 +(预计日行情稳定涨幅1%以上,赚币又赚钱,反之亏损明显) +保证金市场风险巨大,你可能随时面临100%损失。或有不明bug100%损失,概不负责。 + +**策略原理:** + +![](http://https://wx1.sinaimg.cn/mw690/c5775633ly1gaajdxk8a8j20u10f4dhx.jpg) +图片仅供参考 +https://wx1.sinaimg.cn/mw690/c5775633ly1gaajdxk8a8j20u10f4dhx.jpg + +盘口下单随机成交/该策略默认倾向于持有多头仓位/ +先持仓long100u。//注意:先手动持仓long100u。 + +**- 检测现有订单是否超过界限,如果超过了就立马取消该订单/ +- 检测是否成交形成了仓位,如果大于仓位xxu,则减仓到既定仓位以下/** + +**几种挂单情况:** + +**全局挂单:** +为区别市商策略,特定定义远端排序为挂单,参数为买(35u)单量卖(35u)左右。参数可调,目前在7档左右。 + +**市商(盘口近端挂单):** +最大多头持仓1000u,若大于该仓位,约每6s减20u仓位,直到小于1000u. +最大空头持仓100u,若大于该仓位,约每6s减20u仓位,直到小于100u. +大于800u多仓启动减多仓策略,挂单为short:卖8卖9卖10卖11(各30u单量)缓慢成交空头仓位 +大于1u空头仓位,启动减空头仓位策略,挂单为long:买2买3买4(各30u单量)极易成交多单 +正常持仓,long买3/4买5(盘口波动随机成交多单) + +**//参数中的备注描述,仅供参考,另可加挡位** +******风险自负/参数可调,购买加强版联系微信:ying5737** +**优化方向:加入均线或K线对比来确定方向,挡位优化,增加单量等/****** + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Url|https://api.fmex.com|交易所api地址| +|g_minPercent|0.06|挂单:挖矿的下限,离最新价的百分比,如果是 1% 则填写 1| +|g_maxPercent|0.06|挂单:挖矿的上限,离最新价的百分比,如果是 1% 则填写 1| +|g_perAmount|35|挂单:每个订单量多少张,最多只能挂50个订单| +|g_kongtouAmount|35|挂单:单独定义空头单量/暂未启用| +|g_maxHoldingLong|1000|挂单:多单最大持仓量| +|g_maxHoldingShort|100|挂单:空单最大持仓量| +|sp_jiancangAmount|true|市商/排序:减仓多仓/暂未启用| +|sp_jiacangAmount|true|市商/排序:增加多仓/暂未启用| +|sp_kongtouAmount|30|市商/排序: 空头数//暂未启用| +|sp_perAmount|30|市商/排序:单个订单大小| +|mainIntervel|false|Intervel| +|Intervel|false|Intervel0| +|sp_baseAmountLong|800|多仓转向成交空头| +|sp_baseAmountShort|true|空头仓位转成交多头| + + +> 源码 (javascript) + +``` javascript +exchange.IO("base", Url)//保证金市场风险巨大,你可能随时面临100%损失。或有不明bug100%损失,概不负责。 +//实盘地址:https://api.fmex.com 测试网https://api.testnet.fmex.com//注意:先持仓long100u。 +var ordersInfo = {//(加强版-增加仓位管理-增加时间设定-调整单量方向等-价格美丽/购买联系微信:ying5737)请备注fm + buyId: 0, + buyPrice: 0, + sellId: 0, + sellPrice: 0, + minPrice: 0, + maxPrice: 0 +} +var depthInfo = {//注意:先手动持仓long100u。 + asks: [], + bids: [] +} +function getTicker(symbol) { + url = "/v2/market/ticker/" + symbol; + data = exchange.IO("api", "GET", url); + return data.data; +} +function getAccounts() { + data = exchange.IO("api", "GET", "/v3/contracts/accounts") + return data.data; +} + +function createOrderPrice(body) { + parameter = "symbol=" + body.symbol + "&type=" + body.type + "&direction=" + body.direction + "&post_only=" + body.post_only + "&price=" + body.price + "&quantity=" + body.quantity; + + resultData = exchange.IO("api", "POST", "/v3/contracts/orders", parameter) + return resultData; +} +function createOrder(body) { + parameter = "symbol=" + body.symbol + "&type=" + body.type + "&direction=" + body.direction + "&quantity=" + body.quantity; + + resultData = exchange.IO("api", "POST", "/v3/contracts/orders", parameter) + + return resultData; +} + +function getOrders() { + resultData = exchange.IO("api", "GET", "/v3/contracts/orders/open"); + return resultData.data +} + +function cancelOrder(id) { + resultData = exchange.IO("api", "POST", "/v3/contracts/orders/" + id + "/cancel"); + return resultData; + +} + +function getPosition() { + resultData = exchange.IO("api", "GET", "/v3/broker/auth/contracts/positions"); + return resultData.data; +} + +function getMatches(id) { + resultData = exchange.IO("api", "GET", "/v3/contracts/orders/" + id + "/matches"); + return resultData.data; +} + +function getCandles(resolution, symbol) { + resultData = exchange.IO("api", "GET", "/v2/market/candles/" + resolution + "/" + symbol); + return resultData.data; +} +function cleanOrders(lastPrice) { + ordersInfo = getOrders(); + orders = ordersInfo.results; + for (var i = 0; i < orders.length; i++) { + diffPercent = Math.abs(lastPrice - orders[i].price) / lastPrice * 100 + if (diffPercent < g_minPercent || diffPercent > g_maxPercent) { + orderInfo = cancelOrder(orders[i].id); + + Log("挂单取消订单:"); + } + } +} +function getToOrderPrice(basePrice, direct) { + return parseInt(basePrice * (direct * (g_minPercent + Math.random() * (g_maxPercent - g_minPercent)) / 100 + 1)) +} +function cleanPosition() { + res = getPosition(); + res.results.forEach(function(it) { + if (it.symbol == 'BTCUSD_P') { + if (it.quantity) { + if (it.quantity > g_maxHoldingLong && it.direction.toUpperCase() == 'LONG') { + data = createOrder({ + symbol: "BTCUSD_P", + type: "MARKET", + direction: it.direction.toUpperCase() == 'LONG' ? "SHORT" : "LONG", + quantity: 20, + }) + Log("平仓:"); + } + if (it.quantity > g_maxHoldingShort && it.direction.toUpperCase() == 'SHORT') { + data = createOrder({ + symbol: "BTCUSD_P", + type: "MARKET", + direction: it.direction.toUpperCase() == 'LONG' ? "SHORT" : "LONG", + quantity: 20, + }) + Log("平仓:"); + } + } + } + }); +} +function guadan() { + tickerInfo = getTicker('BTCUSD_P'); + ticker = tickerInfo.ticker; + + var lastPrice = ticker[0]; + Log("lastPrice: "+lastPrice); + buyPrice = getToOrderPrice(lastPrice, -1); + sellPrice = getToOrderPrice(lastPrice, 1); + + LongOrderInfo = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: buyPrice, + quantity: g_perAmount, + }) + Log("挂单LONG:" ); + shortOrderInfo = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: sellPrice, + quantity: g_kongtouAmount, + }) + Log("挂单SHORT:" ); + + cleanOrders(lastPrice) + cleanPosition(); +} +function shishang() { + Log("市商/排序挖矿**********************************"); + tickerInfo = getTicker('BTCUSD_P'); + ticker = tickerInfo.ticker; + Log("市商/排序挖矿ticker:"); + lastPrice = ticker[0] + buyPrice = ticker[2] + sellPrice = ticker[4] + Log("lastPrice:"+lastPrice+":buyPrice:"+buyPrice+":sellPrice:" + sellPrice); + if (lastPrice == buyPrice) { + sellPrice = (buyPrice + 0.5).toFixed(1) + } + if (lastPrice == sellPrice) { + buyPrice = (sellPrice - 0.5).toFixed(1) + } + Log("buyPrice:"+buyPrice+":sellPrice:" + sellPrice); + // const LastK7 = k[7]; // 最近第7k + res = getPosition(); + Log("市商/排序挖矿Position:" + JSON.stringify(res)); + res.results.forEach(function(it) { + + if (it.symbol == 'BTCUSD_P') { + if (it.quantity) { + if (it.quantity > sp_baseAmountLong && it.direction.toUpperCase() == 'LONG') { + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice + 5.5, + quantity: sp_perAmount, + }) + Log("排序10:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice + 5, + quantity: sp_perAmount, + }) + Log("排序9:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "SHORT", + post_only: true, + price: lastPrice + 4.5, + quantity: sp_perAmount, + }) + Log("排序8:"); + } else if (it.quantity > sp_baseAmountShort && it.direction.toUpperCase() == 'SHORT') { + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 0.5, + quantity: sp_perAmount, + }) + Log("市商/排序-2:"); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 1, + quantity: sp_perAmount, + }) + Log("市商/排序-3:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 1.5, + quantity: sp_perAmount, + }) + Log("市商/排序-4:" ); + } else { + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 1.5, + quantity: sp_perAmount, + }) + Log("市商-4:" ); + order = createOrderPrice({ + symbol: "BTCUSD_P", + type: "LIMIT", + direction: "LONG", + post_only: true, + price: lastPrice - 2, + quantity: sp_perAmount, + }) + Log("市商-5:"); + + } + } + } + }) +} +/********************END 市商/排序挖矿***************************************************************************************************/ +function main() { + + while(true){ + + guadan(); + Sleep(Intervel * 1000) + + shishang() + Sleep(mainIntervel * 1000) + } +}//FMex排序挖矿多头版本代码使用说明。(注意api地址)(加强版-增加仓位管理-增加时间设定等-购买联系微信:ying5737) +``` + +> 策略出处 + +https://www.fmz.com/strategy/178347 + +> 更新时间 + +2019-12-29 19:00:38 diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230\344\271\260\345\205\245\347\256\200\345\215\225\347\211\210|Simple Iceberg order to buy.md" "b/\345\206\260\345\261\261\345\247\224\346\211\230\344\271\260\345\205\245\347\256\200\345\215\225\347\211\210|Simple Iceberg order to buy.md" index d19ab6a2..d91ae738 100644 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230\344\271\260\345\205\245\347\256\200\345\215\225\347\211\210|Simple Iceberg order to buy.md" +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230\344\271\260\345\205\245\347\256\200\345\215\225\347\211\210|Simple Iceberg order to buy.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230\345\215\226\345\207\272\347\256\200\345\215\225\347\211\210|Simple Iceberg order to sell.md" "b/\345\206\260\345\261\261\345\247\224\346\211\230\345\215\226\345\207\272\347\256\200\345\215\225\347\211\210|Simple Iceberg order to sell.md" index 9c990270..cc37f3ab 100644 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230\345\215\226\345\207\272\347\256\200\345\215\225\347\211\210|Simple Iceberg order to sell.md" +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230\345\215\226\345\207\272\347\256\200\345\215\225\347\211\210|Simple Iceberg order to sell.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.md" "b/\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.md" deleted file mode 100644 index a6f9592d..00000000 --- "a/\345\210\244\346\226\255MA\347\272\277\347\232\204\346\216\222\345\210\227 - btcdw.md" +++ /dev/null @@ -1,39 +0,0 @@ - -> 策略名称 - -判断MA线的排列 - btcdw - -> 策略作者 - -比特币大王www.btcdw.com - - - - - -> 源码 (python) - -``` python -def main(): # - records = exchange.GetRecords(PERIOD_M3) #获取3分钟K线数据 - ma_5 = TA.MA(records, 5) #返回一个5分钟移动平均线数组 - ma_10 = TA.MA(records, 10) #返回一个10分钟移动平均线数组 - ma_20 = TA.MA(records, 20) #返回一个20分钟移动平均线数组 - if len(ma_5) == len(ma_10) == len(ma_20): #判断3线数组是不是一样长 - for i in range(0, len(ma_5)): #从0开始遍历ma_5数组到最大元素(次数)个数 - if ma_5[i] > ma_10[i] > ma_20[i]: - Log("1") - Sleep(1000) - elif ma_5[i] < ma_10[i]< ma_20[i]: - Sleep(1000) - Log("0") - -``` - -> 策略出处 - -https://www.fmz.com/strategy/89969 - -> 更新时间 - -2018-05-04 01:33:33 diff --git "a/\345\210\251\347\224\250\345\233\236\345\275\222\345\271\205\345\272\246\346\236\204\345\273\272\345\244\232\345\223\201\347\247\215\345\217\215\350\275\254\347\255\226\347\225\245.md" "b/\345\210\251\347\224\250\345\233\236\345\275\222\345\271\205\345\272\246\346\236\204\345\273\272\345\244\232\345\223\201\347\247\215\345\217\215\350\275\254\347\255\226\347\225\245.md" new file mode 100644 index 00000000..200ff9c7 --- /dev/null +++ "b/\345\210\251\347\224\250\345\233\236\345\275\222\345\271\205\345\272\246\346\236\204\345\273\272\345\244\232\345\223\201\347\247\215\345\217\215\350\275\254\347\255\226\347\225\245.md" @@ -0,0 +1,107 @@ + +> 策略名称 + +利用回归幅度构建多品种反转策略 + +> 策略作者 + +Hukybo + +> 策略描述 + +# 摘要 +河水并不需要计划自己的行进路线,却毫无例外的到达海洋。价格也同样如此,它总是沿着最小阻力线去运动,它总是怎么容易怎么来。如果上升的阻力比下跌的阻力小,价格就会上涨,反之亦然。通常一个大幅度的反转形态,意味着随后会有更大幅度的运动。无论是上升趋势,还是下降趋势,在每一次重大的趋势运动之后,都将产生一定程度的回撤。回撤与原有价格幅度往往构成一定程度的百分比,就称之为百分比回撤。 +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4390) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|cycleLength|50|周期长度| +|backRatio|true|回撤比率| +|contractType|rb000/rb888,ru000/ru888|合约类型| +|unit|true|下单数量| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2016-01-01 09:00:00 +end: 2019-01-01 15:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","minfee":10,"fee":[0,0]}] +*/ + +function main() { + // 参数 + cycleLength = 50; // 周期长度 + backRatio = 1; // 回撤比率 + contractType = 'rb000/rb888,ru000/ru888'; // 合约类型 + unit = 1; // 下单数量 + + // 仓位表 + var contractType_Dic = {}; // 创建一个空对象,用于接收不同的合约类型 + var contractType_Array1 = contractType.split(","); // 分割合约类型参数 + var contractType_Array2 = []; // 创建一个空数组,用于接收不同的交易合约 + for (var i = 0; i < contractType_Array1.length; i++) { // 遍历每个设置的合约 + contractType_Array2.push(contractType_Array1[i].split('/')[1]); // 分别存储交易合约 + } + contractType_Array2.toString(); // 把数组转变为字符串 + for (var key in contractType_Array2) { // 遍历字符串 + contractType_Dic[contractType_Array2[key]] = { + falsePosition: 0 // 把每个交易合约的初始仓位赋值为0 + } + } + + // CTA框架 + $.CTA(contractType, function(st) { + var bars = st.records; // 获取K线数组 + var j = bars[bars.length - 2].Close; // 获取上根K线收盘价 + var high = TA.Highest(bars, cycleLength, 'High'); // 计算N日内的最高价 + var low = TA.Lowest(bars, cycleLength, 'Low'); // 计算N日内的最低价 + var highBack = high * (1 - backRatio / 100); // 计算N日内的最高价的回撤1%的值 + var lowBack = low * (1 + backRatio / 100); // 计算N日内的最低价的回撤1%的值 + + // 过滤K线数量 + if (!bars || bars.length < cycleLength + 1) { + return; + } + + //多头平仓 + if (contractType_Dic[st.symbol].falsePosition > 0 && j < (lowBack + highBack) / 2) { + contractType_Dic[st.symbol].falsePosition = 0; + return -unit; + } + + //空头平仓 + if (contractType_Dic[st.symbol].falsePosition < 0 && j > (lowBack + highBack) / 2) { + contractType_Dic[st.symbol].falsePosition = 0; + return unit; + } + + //多头开仓 + if (contractType_Dic[st.symbol].falsePosition == 0 && j > lowBack && j > highBack) { + contractType_Dic[st.symbol].falsePosition = 1; + return unit; + } + + //空头开仓 + if (contractType_Dic[st.symbol].falsePosition == 0 && j < lowBack && j < highBack) { + contractType_Dic[st.symbol].falsePosition = -1; + return -unit; + } + + }); +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/69937 + +> 更新时间 + +2019-10-12 15:23:07 diff --git "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" index ccbf5ebd..d2df71ed 100644 --- "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" +++ "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" @@ -12,7 +12,7 @@ Hukybo 阅读原文:[区块链量化投资系列课程(3) - 跨期套利](https://quantinfo.com/Article/View/816/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%283%29---%E8%B7%A8%E6%9C%9F%E5%A5%97%E5%88%A9.html) ### NO.1 索罗斯在1987年撰写的《金融炼金术》 一书中,曾经提出过一个重要的命题:I believe the market prices are always wrong in the sense that they present a biased view of the future. -[]( https://dn-filebox.qbox.me/ff79e72d5042d66611bb87f552cb8413238bee41.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/3a50b5d2432cb4ff4eed.png) ) 市场有效假说只是理论上的假设,实际上市场参与者并不总是理性的,并且在每一个时间点上,参与者不可能完全获取和客观解读所有的信息,再者就算是同样的信息,每个人的反馈都不尽相同。 也就是说,价格本身就已经包含了市场参与者的错误预期,所以本质上市场价格总错误的。这或许是套利者的利润来源。 @@ -23,7 +23,7 @@ Hukybo 根据上述原理,我们也就知道,在一个非有效的期货市场中,不同时期交割合约之间受到市场影响也并不总是同步,其定价也并非完全有效的原因。 那么,根据同一种交易标的的不同时期交割合约价格为基础,如果两个价格出现了较大的价差幅度,就可以同时买卖不同时期的期货合约,进行跨期套利。 -[]( https://dn-filebox.qbox.me/8b2eeef30c771f29c2463b8e2bafeb2e68fc6113.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/39c5e58ad36a6ef82d32.png) ) 与商品期货一样,数字货币也有与之相关的跨期套利合约组合。如在 OkEX 交易所中就有:ETC 当周、ETC 次周、ETC 季度。 举个例子,假设 ETC 当周和 ETC 季度的价差长期维持在 5 左右。如果某一天价差达到 7,我们预计价差会在未来某段时间回归到 5。那么就可以卖出 ETC 当周,同时买入 ETC 季度,来做空这个价差。反之亦然。 @@ -34,7 +34,7 @@ Hukybo 尽管这种价差是存在的,但是人工操作耗时、准确性差以及价格变化的影响,人工套利往往存在诸多不确定性。 通过量化模型捕捉套利机会并制定套利交易策略,以及程序化算法自动向交易所下达交易订单,快速准确捕捉机会,高效稳定赚取收益,这就是量化套利的魅力所在。 -[]( https://dn-filebox.qbox.me/5f2018b8b1842582feb548f9479e2d2e529ad5c0.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/39fb7e34588bd2e7ddcf.png) ) 本篇将会教大家如何在数字货币交易中,利用发明者量化交易平台和 OkEX 交易所中 ETC 期货合约,以一个简单的套利策略,来演示如果捕捉瞬时的套利机会,把握住每一次可以看得到的利润,同时对冲有可能遇到的风险。 @@ -42,7 +42,7 @@ Hukybo ### NO.4 创建一个数字货币跨期套利策略 难易度:普通级 - [](https://dn-filebox.qbox.me/32464ad1bda6480421765081ba72c0422ce82016.jpg ) + []( ![IMG](https://www.fmz.com/upload/asset/3975b5c50dd3e4618d12.png) ) 策略环境: - 交易标的:以太经典(ETC) @@ -62,7 +62,7 @@ Hukybo ### NO.5 上面是一个简单的数字货币跨期套利策略逻辑描述,那么如何在程序中实现自己的想法呢?我们试着在发明者量化交易平台先把框架搭建起来。 **策略框架:** - [发明者量化(www.fmz.com)](https://dn-filebox.qbox.me/6611dc32473011546052197ef9633a633cddea98.jpg ) + [发明者量化(www.fmz.com)]( ![IMG](https://www.fmz.com/upload/asset/399e03afb094d0d149ed.png) ) 对照着策略思路以及交易流程,可以很轻松把策略框架搭建起来。整个策略可以简化为三个步骤: 1.交易前预处理。 2.获取并计算数据。 @@ -85,73 +85,69 @@ var bars = [ ] var oldTime = 0 第2步:配置策略的外部参数。 -[发明者量化(www.fmz.com)]( https://dn-filebox.qbox.me/9feef4532dda92b1e37686dbed489e632d918901.jpg ) +[发明者量化(www.fmz.com)]( ![IMG](https://www.fmz.com/upload/asset/398ab0b260d21ee7462c.png) ) 第3步:定义数据处理函数 **基础数据函数**:Data ( ) 创建一个构造函数 Data,并定义它的内部属性。包括:账户数据、持仓数据、K线数据时间戳、套利A/B合约的买/卖一价、正/反套价差。 -[发明者量化(www.fmz.com)]( https://dn-filebox.qbox.me/25258da6f6aa0469ba5b0ffddc813c578e7bfc7b.jpg ) +[发明者量化(www.fmz.com)]( ![IMG](https://www.fmz.com/upload/asset/39a74331ead8bf6351b6.png) ) **获取持仓函数**:mp ( ) 遍历整个持仓数组,返回指定合约、指定方向的持仓数量,如果没有就返回 false -[]( https://dn-filebox.qbox.me/e366fea7a0552d80123f0f3eba614071f2dba348.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/39283091a2290f3c2e4a.png) ) **K线和指标函数**:boll ( ) 根据正/反套价差数据,合成新的K线序列。并返回由boll指标计算的上轨、中轨、下轨数据。 -[]( https://dn-filebox.qbox.me/3aea8fcbd0e4e4e0dfdff28b0cb13aec79b3547e.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/3973481a1310ddffa47d.png) ) **下单函数**:trade ( ) 传入下单合约名称和下单类型,然后以对价下单,并返回下单后的结果。由于需要同时下两个不同方向的单子,所以在函数内部根据下单合约名称对买/卖一价做了转换。 -[]( https://dn-filebox.qbox.me/857d21ada91345aa6c0aa260a934c53fd85a51dc.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/3a36d770938d35a407b1.png) ) **取消订单函数**:cancelOrders ( ) 获取所有未成交订单数组,并逐个取消。并且如果有未成交的订单就返回false,如果没有未成交的订单就返回true。 -[]( https://dn-filebox.qbox.me/d69b810e42b8826747c43505c3d0fe3e4fc10984.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/395b0a12d3a6814d13a3.png) ) **处理持有单个合约**:isEven ( ) 在处理套利交易中出现单腿情况,这里直接用简单的平掉所有仓位处理。当然,也可以改为追单方式。 -[]( https://dn-filebox.qbox.me/7eb8fef77840dc3ba1a1e99aaa1c7492542fcdde.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/3a4db92b687659c4ffe6.png) ) **画图函数**:drawingChart ( ) 调用 ObjChart.add ( ) 方法,在图表中画出必要的行情数据和指标数据:上轨、中轨、下轨、正/反套价差。 -[]( https://dn-filebox.qbox.me/12d6b96d0e1666c7f6dd54a7f25c48e7e991a0ac.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/39e1621a909a34c5b9d1.png) ) 第4步:在入口函数 main ( ) 里面,执行交易前预处理代码,这些代码在程序启动后,只运行一次。包括: - 过滤控制台中不是很重要的信息 SetErrorFilter ( ) - 设置要交易的数字货币币种 exchange.IO ( ) - 程序启动前清空之前绘制的图表 ObjChart.reset ( ) - 程序启动前清空之前的状态栏信息 LogProfitReset ( ) -[]( https://dn-filebox.qbox.me/2061c1225d3c94ceda5372a4bfa3cdb98aa485c4.jpg ) + +[]( ![IMG](https://www.fmz.com/upload/asset/39082440603314ba0136.png) ) ### NO.7 定义完上述的交易前预处理,紧接着就要进入下一个步骤,进入轮询模式,重复执行 onTick ( ) 函数。 并设置 Sleep ( ) 轮询时的休眠时间,因为部分数字货币交易所的 API 对一定时间内内置了访问次数限制。 -[]( https://dn-filebox.qbox.me/c8365eb8140a2fc1de9d884ba45f6030aa546921.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/3a31da7c4d17305936a9.png) ) ##### 二、获取并计算数据 第1步:获取基础数据对象、账户余额、boll 指标数据,以供交易逻辑使用。 -[]( https://dn-filebox.qbox.me/5b54a0456b4dde1d6cb4e4098a3ccc68156c1e53.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/3a04d9408da5c6263b7d.png) ) ##### 三、下单并对后续处理 第1步:根据上述的策略逻辑,执行买卖操作。首先会判断价格和指标条件是否成立,然后再判断持仓条件是否成立,最后执行 trade ( ) 下单函数 -[]( https://dn-filebox.qbox.me/03b80df179d4c3b6d23493f1a3bcf198ff16a652.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/39573695cd117b864773.png) ) 第2步:下单完成后,需要对未成交的订单、持有单个合约等非正常情况做处理。以及绘制图表。 -[]( https://dn-filebox.qbox.me/d5f4100912fdbff321d8bd4c2ca3652590c2dbb6.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/39ecb07f954fa643c38e.png) ) ### NO.8 以上,我们通过 200 多行,就把一个简单的数字货币跨期套利策略完完整整的创建出来。完整的代码如下: - [](https://dn-filebox.qbox.me/572bfc18fa64b9f124794510da1b7e9ebbcd8826.jpg ) + []( ![IMG](https://www.fmz.com/upload/asset/39853edcb19072073099.png) ) ### NO.9 本篇策略只是一个抛砖引玉,真实的实盘可不是这么简单,不过你可以照着例子发挥自己天马行空的想象。 需要提醒大家的是,以我有限的经验来看,目前的数字货币市场状况,纯粹的期期套利策略基本上全部不值得跑,不论是无风险的三角套利还是跨市场套利。 -[]( https://dn-filebox.qbox.me/877c11bd2e8512df961f299ab38050bef7a7f6be.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/399dbae8aef4b1738435.png) ) 原因就在于,无论哪个数字货币交易所的期货市场,其保证金不是法币。现如今几乎所有的数字货币从今年初至今已经下跌了70%左右。也就是说策略始终都是在赚币,但是币价是下跌的。 放眼望去,数字货币市场俨然已经脱离了区块链,就像当年的郁金香一样,价格始终来自于人们的预期和信心,信心又来源于价格... -延伸阅读: -[区块链量化投资系列课程(1) - 简介](https://quantinfo.com/Article/View/818/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%281%29---%E7%AE%80%E4%BB%8B.html) -[区块链量化投资系列课程(2) - 认识数字货币](https://quantinfo.com/Article/View/819/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%282%29---%E8%AE%A4%E8%AF%86%E6%95%B0%E5%AD%97%E8%B4%A7%E5%B8%81.html) -[区块链量化投资系列课程(4) - 动态平衡策略](https://quantinfo.com/Article/View/1573/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%284%29---%E5%8A%A8%E6%80%81%E5%B9%B3%E8%A1%A1%E7%AD%96%E7%95%A5.html) - > 源码 (javascript) @@ -428,4 +424,4 @@ https://www.fmz.com/strategy/104964 > 更新时间 -2018-08-10 15:43:51 +2019-12-09 11:59:12 diff --git "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" index 019f4aee..dffc62fd 100644 --- "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" +++ "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" @@ -22,7 +22,7 @@ Hukybo 在这个方法中,债券基金的波动率其实很小,远远低于股票波动率,所以债券在这里被当做『 参照锚 』,也就是说,用债券来衡量股票究竟是涨得太多了,还是涨得太少了。如果,股票价格上涨,会使得股票的市值大于债券的市值,当两者市值比率超过设定的阈值时,则对总仓位进行重新调整,卖出股票,并且买入债券,使股债市值比例恢复至初始的 1:1。 反之,股票价格下跌,会使得股票的市值小于债券的市值,当两者市值比率超过设定的阈值时,则对总仓位进行重新调整,买入股票,并且卖出债券,使股债市值比例恢复至初始的 1:1。 -[]( https://dn-filebox.qbox.me/0b155ba7a40dfa853174cbc60ea89a40434b2441.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/38c501464347620f3d16.png) ) 就这样,在动态平衡股票和债券之间的比例,就够享受到股票成长的果实,并且减少了资产波动率。作为价值投资的先驱,格雷厄姆为我们提供了一个很好的思路。 @@ -97,7 +97,7 @@ BTC 已经持续了长达 8 个月下跌,甚至最大跌幅超过70%,这造 本篇动态平衡策略,只有一个核心参数(threshold 阈值),是一个很简单的投资方法,追求的不是超额的收益,而是稳健的收益。与趋势策略相反,动态平衡策略却是逆势而动。在市场热的时候减仓降温,市场冷清的时候加仓蛰伏,有点类似宏观经济调控。其实,动态平衡策略正是秉承了价格不可预测的观念,同时又捕捉价格波动的一门手艺。动态平衡策略的关键核心在设定和调整资产配置比例,还有触发阈值。 鉴于篇幅原因,一篇文章没办法做到面面俱到,要知道文字之外,存乎一心。动态平衡策略最重要的是投资思想,你甚至可以把本篇中的单个 BTC 资产换成一篮子区块链资产组合。 -[]( https://dn-filebox.qbox.me/a0d2ff01f4f8ed7ad77eeeecb6650129040f792b.jpg ) +[]( ![IMG](https://www.fmz.com/upload/asset/3a38be32a654bdd0d7cc.png) ) 最后,让我们以本杰明 · 格雷厄姆在《聪明的投资者》一书中的名言来结束本篇:股票市场并非一个能精确衡量价值的『 称重计 』,相反它是一个『 投票机 』,不计其数的人所做出的决定是一种理性和感性的掺杂物,有很多时候这些抉择和理性的价值评判相去甚远。投资的秘诀就是在价格远远低于内在价值时投资,并且相信市场趋势会回升。——本杰明 · 格雷厄姆《聪明的投资者》 @@ -207,4 +207,4 @@ https://www.fmz.com/strategy/110545 > 更新时间 -2018-08-10 12:38:55 +2019-12-09 12:01:25 diff --git "a/\345\215\225\345\225\206\345\223\201\345\260\217\345\215\226\351\203\250\347\255\226\347\225\245V2.0_\345\271\264\345\214\226130%.md" "b/\345\215\225\345\225\206\345\223\201\345\260\217\345\215\226\351\203\250\347\255\226\347\225\245V2.0_\345\271\264\345\214\226130%.md" new file mode 100644 index 00000000..7222d35b --- /dev/null +++ "b/\345\215\225\345\225\206\345\223\201\345\260\217\345\215\226\351\203\250\347\255\226\347\225\245V2.0_\345\271\264\345\214\226130%.md" @@ -0,0 +1,145 @@ + +> 策略名称 + +单商品小卖部策略V2.0_年化130% + +> 策略作者 + +tomjava + +> 策略描述 + +曾有人统计,从市场趋势而言,80%的时间都是处于震荡趋势的。网格策略就是应对震荡的一种策略。网格策略具体实现起来有多种方式,但是实质是设定一个相对稳定的加仓策略,只要价格波动满足策略的条件就执行加仓。我们举个例子,比如说价格每跌5%我们就加仓总资金的20%,这样我们在执行最多五次加仓后将会满额使用资金。这里我们同样也可以每上涨5%则减掉初始资金20%的仓位,那么五次后我们将清仓,这就是网格策略的基本思路。 +区班主今天介绍一种量化策略,类似网格交易,但是在此基础上,做了一些改进,在某些情况下,可以达到130%的年化收益。区班主把其命名为小卖部策略,就是想象操作者是一个小卖部的经营者。他瞄准市场的一个公允价格,一旦高于公允价格;他就抛出货品,低于公允价格,他就买入货品。另外他有一个小本子,记录了上次的交易价格,一旦货品价格低于上次的交易价格,他也可以突发买入,反之亦然。为了避免无限操作,当资金低于1成或者高于1成时,停止操作。 +具体描述一下步骤: +步骤一:观察商品的波动率,找一个公允价格指标,可以是某均线(30分钟线的20周期),也可以是布林中线;默认买入5成仓,并记录成交价格; +步骤二:如果低于公允价格指标3%就指示买入;高于公允价格3%就指示卖出;并记录成交价格; + 如果低于上次成交价格5%再指示买入;高于成交价格5%再指示卖出;并记录成交价格; +步骤三:根据当前仓位,决定收到买入指令时,如何操作;仓位1成和9成之间波动,超过此区间不操作,但是可以记录成交价格;每次操作只买入2成仓或1成仓,避免无限操作。 +之所以该策略叫单商品小卖部策略,因为该小卖部只有一种商品。后续做为改进方向,我们希望可以增加多种商品轮动,甚至背靠背做空对冲。 +我们来运行一下回测,首先我们选择波动率大的ETH来作为该种商品,周期是2019年1月1日到10月10日,这个区间有暴涨,也有暴跌。 +可以看到,回测效果还是不错,达到了130%的年化率,另外创造了1651元的交易费用,这个结果应该是交易所和交易者都欢喜的策略。 +缺点就是最大回撤还是有点高,达到30%左右。主要的回撤发送在商品大幅下跌的阶段。想想也很好理解,因为这个策略是锚定交易商品的,如果商品价格下跌,那么可能在高位囤了一些货,还没有来得及释放给市场,随着时间拉长,应该能补回来。 +注册币乎后https://m.bihu.com/signup?i=1ewtKO&s=4&c=4 ,搜索 物联网区块链 可以联系到作者区班主。 +另外需要提醒读者注意的是,本策略还和商品选择有关。尽量选择波动大,且长期看来升值的商品。另一个角度上来说,如果你会结合商品来调节参数,那么再小的波动,只要能覆盖手续费,应该也不是问题。 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Interval|10|轮询周期(秒)| +|mnum|20|30分钟线周期| +|initRatio|0.5|初始仓位比例| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2019-01-01 00:00:00 +end: 2019-10-10 00:00:00 +period: 1d +exchanges: [{"eid":"OKEX","currency":"ETH_USDT","stocks":0}] +args: [["OpMode",1,10989],["MaxAmount",1,10989],["TradeFee",0.001,10989]] +*/ +//注册币乎后https://m.bihu.com/signup?i=1ewtKO&s=4&c=4 +//搜索 物联网区块链 可以联系到作者区班主 +function main() { + var isInit = 1; //表示初始态 + var allAmount; + var cashRatio; + var initAccount = _C(exchange.GetAccount); + var lastPrice; + var wantRatio; + var wantOper=0;//期待的操作,0不操作,1买入,-1卖出 + Log(initAccount); + var mhigh; + var mlow; + while (true) { + var mrecords = exchange.GetRecords(PERIOD_M30); + //一定周期内的高低点 + mhigh=TA.Highest(mrecords, mnum, 'High'); + mlow=TA.Lowest(mrecords, mnum, 'Low'); + + var midLine = (mhigh+mlow)/2; + var ticker = _C(exchange.GetTicker); + var account = _C(exchange.GetAccount); + var nowPrice=ticker.Sell; + var obj; + + if (isInit == 1) { //初始化状态为默认仓; + //账户现金乘以比例,除以当前价格,保留小数前3位 + obj = $.Buy(_N(account.Balance * initRatio / ticker.Sell, 3)); + if (obj) { //如果购买成功,就标志开仓 + opAmount = obj.amount; + lastPrice = obj.price; + isInit=0; //初始化成功 + account = _C(exchange.GetAccount); + Log("初始开仓:购买量", opAmount); + Log("目前持币数", account.Stocks); + } + }else{ //日常操作检测 + if(nowPrice>midLine*1.03||nowPrice>lastPrice*1.07){ + wantOper=-1; + }else if(nowPrice0.9){ //现金比例大于0.9,不做任何操作 + wantRatio=0; + }else if(cashRatio>0.8){ //现金比例超过0.8,可以抛一成仓 + wantRatio=0.1; + }else{ //其他情况都可以抛掉2成仓 + wantRatio=0.2; + } + + obj = $.Sell(_N(allAmount*wantRatio/ticker.Sell, 3)); + if(obj){ + opAmount = obj.amount; + Log("平仓:卖出量",opAmount); + nowAccount = _C(exchange.GetAccount); + Log("目前现金",nowAccount.Balance,"盈利",allAmount - initAccount.Balance); + } + }else if (wantOper==1) { //开仓买入 + lastPrice=nowPrice; //不管买没买成功都修改了一下价格 + allAmount=account.Balance+account.Stocks*ticker.Sell; //计算出总金额 + cashRatio=parseFloat((account.Balance/allAmount).toFixed(3)); + //Log("准备买入",cashRatio); + if(cashRatio<0.1){ //现金比例小于0.1,已没钱买了 + wantRatio=0; + }else if(cashRatio<0.2){ //现金比例超过0.2,可以买一成仓 + wantRatio=0.1; + }else{ //其他情况都可以买2成仓 + wantRatio=0.2; + } + + obj = $.Buy(_N(allAmount*wantRatio/ticker.Sell, 3)); + if(obj){ + opAmount = obj.amount; + Log("买入:买入量",opAmount); + nowAccount = _C(exchange.GetAccount); + Log("目前现金",nowAccount.Balance,"盈利",allAmount - initAccount.Balance); + } + } + } + Sleep(Interval*1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/170557 + +> 更新时间 + +2019-10-20 15:52:19 diff --git "a/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225.md" "b/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225.md" new file mode 100644 index 00000000..ef77aafe --- /dev/null +++ "b/\345\215\225\347\202\271\347\213\231\345\207\273\351\253\230\351\242\221\345\212\240\344\273\223\350\207\252\345\212\250\345\217\215\346\211\213\350\247\243\345\245\227\347\256\227\346\263\225.md" @@ -0,0 +1,476 @@ + +> 策略名称 + +单点狙击高频加仓自动反手解套算法 + +> 策略作者 + +威尔士发 + +> 策略描述 + +先开仓,指定一个盈利点平仓,如果平不了,超过止损点,就再加仓拉低成本价, 一直加到盈利出场,如果加仓加到没钱或者币再加了,就开始反手做,原来是做空的,就反手做多,这样一直反复. 也可以不让自动反手,让程序一直等着解套. + +比如现在10元均价开的多仓,目标盈利是5毛钱,程序挂一个10.5元卖出的单,如果价格跌了,就加仓到当前价格的附近,调整均价,再挂一个目标盈利单, 如果还不行,继续加仓拉低均价,实在不行,被套了,就反手开始做空单. + +策略的自动反手机制 + +如果当前做多仓, 盈利出局,会自动再做多仓,如果被套,反手拿币做空仓, 空仓盈利后,继续做空仓,一直到加仓加不动了,反手开始做多仓,这样一直循环. 只要上次是盈利的就一直保持着上次的开仓方向 +策略会自动计算需要加仓的量的大小跟目标盈利点的新值 +需要注意的 + +此策略有完整的恢复机制,可以实际操作或者学习使用 +此策略100%赚钱的前提是: 你得准备好足够的资金加仓 +如果没有足够的资金,就让自动反手做, 会产生浮动盈亏 +如果你有足够的资金,就不需要自动反手了,一直让程序加仓就可以 +策略可以通过调整参数,实现高频的盘口型策略 +不适合期货,期货这样搞容易爆仓, 所以只能现货来操作 +开源的目的 + +吸引更多的人加入到量化交易这个交流圈子里来,而不是整天的闭门造车 + +V1.1 解决了OKCoin冻结0.0001个币导致程序卡住的bug + +更详细的说明, 移步: https://www.fmz.com/#!/bbs-topic/38 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|OpType|0|首次开仓方向: 做多|做空| +|OpAmount|0.1|开仓数量| +|OpMode|0|开仓方式: 吃单|挂单| +|MaxSpace|0.5|挂单失效距离| +|SlidePrice|0.1|下单滑动价(元)| +|MaxAmount|0.3|开仓最大单次下单量| +|AddGoal|true|加仓间距(元)| +|AddLine|0.8|加仓均价目标(元)| +|ProfitGoal|0.5|平仓目标(元)| +|Interval|true|轮询间隔(秒)| +|RestoreIt|false|恢复进度| +|RestoreType|0|持仓方向: 做多|做空| +|RestorePrice|false|持仓均价| +|RestoreAmount|false|持仓数量| +|RestoreProfit|false|上次盈利| +|SaveLocal|false|保存本地日志| +|AutoReverse|true|自动反手| +|MinStock|0.01|最小交易币数| + + +> 源码 (javascript) + +``` javascript + +var TradeType = OpType == 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; +var OrgAccount = null; +var Counter = {s : 0, f: 0}; +var LastProfit = 0; +var AllProfit = 0; +var LastTicker = null; +function _N(v, precision) { + if (typeof(precision) != 'number') { + precision = 4; + } + var d = parseFloat(v.toFixed(Math.max(10, precision+5))); + s = d.toString().split("."); + if (s.length < 2 || s[1].length <= precision) { + return d; + } + + var b = Math.pow(10, precision); + return Math.floor(d*b)/b; +} + +function EnsureCall(e, method) { + var r; + while (!(r = e[method].apply(this, Array.prototype.slice.call(arguments).slice(2)))) { + Sleep(Interval); + } + return r; +} + +function StripOrders(e, orderId) { + var order = null; + if (typeof(orderId) == 'undefined') { + orderId = null; + } + while (true) { + var dropped = 0; + var orders = EnsureCall(e, 'GetOrders'); + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == orderId) { + order = orders[i]; + } else { + var extra = ""; + if (orders[i].DealAmount > 0) { + extra = "成交: " + orders[i].DealAmount; + } else { + extra = "未成交"; + } + e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); + dropped++; + } + } + if (dropped == 0) { + break; + } + Sleep(300); + } + return order; +} + +function updateProfit(e, account, ticker) { + if (typeof(account) == 'undefined') { + account = GetAccount(e); + } + if (typeof(ticker) == 'undefined') { + ticker = EnsureCall(e, "GetTicker"); + } + var profit = (((account.Stocks + account.FrozenStocks) - (OrgAccount.Stocks + OrgAccount.FrozenStocks)) * ticker.Last) + ((account.Balance + account.FrozenBalance) - (OrgAccount.Balance + OrgAccount.FrozenBalance)); + LogProfit(_N(profit + LastProfit, 4), "币数:", _N(account.Stocks + account.FrozenStocks, 4), "钱数:", _N(account.Balance + account.FrozenBalance, 4)); +} + + +var preMsg = ""; +function GetAccount(e, waitFrozen) { + if (typeof(waitFrozen) == 'undefined') { + waitFrozen = false; + } + var account = null; + var alreadyAlert = false; + while (true) { + account = EnsureCall(e, "GetAccount"); + if (!waitFrozen || (account.FrozenStocks < MinStock && account.FrozenBalance < 0.01)) { + break; + } + if (!alreadyAlert) { + alreadyAlert = true; + Log("发现账户有冻结的钱或币", account); + } + Sleep(Interval); + } + msg = "成功: " + Counter.s + " 次, " + (AutoReverse ? "被":"解") + "套: " + Counter.f + " 次, 当前账户 钱: " + account.Balance + " 币: " + account.Stocks; + if (account.FrozenStocks > 0) { + msg += " 冻结的币: " + account.FrozenStocks; + } + if (account.FrozenBalance > 0) { + msg += " 冻结的钱: " + account.FrozenBalance; + } + + if (LastTicker != null && OrgAccount != null && OrgAccount != null) { + var profit = (((account.Stocks + account.FrozenStocks) - (OrgAccount.Stocks + OrgAccount.FrozenStocks)) * LastTicker.Last) + ((account.Balance + account.FrozenBalance) - (OrgAccount.Balance + OrgAccount.FrozenBalance)); + msg += " 平仓盈亏: " + AllProfit + ", 浮动盈亏: " + _N(profit, 4); + msg += " (初始账户 钱: " + OrgAccount.Balance + " 币 : " + OrgAccount.Stocks + ")"; + } + + + if (msg != preMsg) { + preMsg = msg; + LogStatus(msg, "#ff0000"); + } + return account; +} + +// mode = 0 : direct buy, 1 : buy as buy1 +function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, retryDelay) { + var initAccount = GetAccount(e, true); + var nowAccount = initAccount; + var orderId = null; + var prePrice = 0; + var dealAmount = 0; + var diffMoney = 0; + var isFirst = true; + var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell; + var isBuy = tradeType == ORDER_TYPE_BUY; + while (true) { + var ticker = EnsureCall(e, 'GetTicker'); + LastTicker = ticker; + var tradePrice = 0; + if (isBuy) { + tradePrice = _N((mode == 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4); + } else { + tradePrice = _N((mode == 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4); + } + if (orderId == null) { + if (isFirst) { + isFirst = false; + } else { + nowAccount = GetAccount(e, true); + } + var doAmount = 0; + if (isBuy) { + diffMoney = _N(initAccount.Balance - nowAccount.Balance, 4); + dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 4); + doAmount = Math.min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance-10) / tradePrice, 4)); + } else { + diffMoney = _N(nowAccount.Balance - initAccount.Balance, 4); + dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); + doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); + } + if (doAmount < MinStock) { + break; + } + prePrice = tradePrice; + orderId = tradeFunc(tradePrice, doAmount); + } else { + if (Math.abs(tradePrice - prePrice) > maxSpace) { + orderId = null; + } + var order = StripOrders(exchange, orderId); + if (order == null) { + orderId = null; + } + } + Sleep(retryDelay); + } + + if (dealAmount <= 0) { + return null; + } + + return {price: _N(diffMoney / dealAmount, 4), amount: dealAmount}; +} + +function loop(isFirst) { + var minStock = MinStock; + var initAccount = GetAccount(exchange, true); + Log(initAccount); + var holdPrice = 0; + var holdAmount = 0; + if (RestoreIt && isFirst) { + LastProfit = RestoreProfit; + TradeType = RestoreType == 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; + holdPrice = RestorePrice; + holdAmount = RestoreAmount; + if (holdAmount != 0) { + initAccount = { + Stocks: initAccount.Stocks, + FrozenStocks: initAccount.FrozenStocks, + Balance: initAccount.Balance, + FrozenBalance: initAccount.FrozenBalance, + }; + if (RestoreType == 0) { + initAccount.Stocks -= holdAmount; + initAccount.Balance += (holdPrice * holdAmount); + } else { + initAccount.Stocks += holdAmount; + initAccount.Balance -= (holdPrice * holdAmount); + } + OrgAccount = initAccount; + Log("恢复持仓状态为:", RestoreType == 0 ? "做多" : "做空", "均价:", holdPrice, "数量:", holdAmount); + if (RestoreType == 0) { + holdAmount = Math.min(initAccount.Stocks, holdAmount); + } + } + if (LastProfit != 0) { + AllProfit = LastProfit; + LogProfit(LastProfit, "恢复上次盈利"); + } + } + if (holdAmount == 0) { + var obj = Trade(exchange, TradeType, OpAmount, OpMode, SlidePrice, MaxAmount, MaxSpace, Interval); + if (!obj) { + throw "出师不利, 开仓失败"; + } else { + Log(TradeType == ORDER_TYPE_BUY ? "开多仓完成" : "开空仓完成", "均价:", obj.price, "数量:", obj.amount); + } + Log(GetAccount(exchange, true)); + holdPrice = obj.price; + holdAmount = obj.amount; + } + var openFunc = TradeType == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell; + var coverFunc = TradeType == ORDER_TYPE_BUY ? exchange.Sell : exchange.Buy; + var isFinished = false; + while (!isFinished) { + var account = GetAccount(exchange, true); + var openAmount = 0; + var openPrice = 0; + var coverPrice = 0; + var canOpen = true; + + if (TradeType == ORDER_TYPE_BUY) { + var upLine = AddLine; + openPrice = _N(holdPrice - AddGoal, 4); + openAmount = _N((holdAmount * (holdPrice - openPrice - upLine)) / upLine, 4); + coverPrice = _N(holdPrice + ProfitGoal, 4); + if (_N(account.Balance / openPrice, 4) < openAmount) { + Log("没有钱加多仓, 需要加仓: ", openAmount, "个"); + if (AutoReverse) { + return holdAmount; + } else { + canOpen = false; + } + } + } else { + var upLine = -AddLine; + openPrice = _N(holdPrice + AddGoal, 4); + coverPrice = _N(holdPrice - ProfitGoal, 4); + openAmount = _N((holdAmount * (holdPrice - openPrice - upLine) / upLine), 4); + if (account.Stocks < openAmount) { + Log("没有币加空仓, 需要币:", openAmount); + if (AutoReverse) { + return holdAmount; + } else { + canOpen = false; + } + } + } + if (holdAmount < minStock) { + Log("剩余币数过小, 放弃操作", holdAmount); + return 0; + } + openAmount = Math.max(minStock, openAmount); + + var order_count = 0; + var openId = null; + var coverId = null; + if (!canOpen) { + openId = -1; + Log("进入等待解套模式"); + } + + for (var i = 0; i < 10; i++) { + if (!openId) { + openId = openFunc(openPrice, openAmount); + } + if (!coverId) { + coverId = coverFunc(coverPrice, holdAmount); + } + if (openId && coverId) { + break; + } + Sleep(Interval); + } + if (!openId || !coverId) { + StripOrders(exchange); + throw "下单失败"; + } + if (openId > 0) { + order_count++; + } + if (coverId > 0) { + order_count++; + } + + var preAccount = account; + while (true) { + Sleep(Interval); + var ticker = EnsureCall(exchange, "GetTicker"); + var orders = EnsureCall(exchange, "GetOrders"); + LastTicker = ticker; + var nowAccount = GetAccount(exchange); + var diff = nowAccount.Stocks + nowAccount.FrozenStocks - preAccount.Stocks; + + if (orders.length != order_count || Math.abs(diff) >= minStock) { + StripOrders(exchange); + nowAccount = GetAccount(exchange, true); + //Log(nowAccount); + var diffAmount = nowAccount.Stocks - initAccount.Stocks; + var diffMoney = nowAccount.Balance - initAccount.Balance; + if (Math.abs(diffAmount) < minStock) { + AllProfit= _N(AllProfit + (holdAmount * ProfitGoal), 4); + LogProfit(AllProfit, "平仓完成, 达到目标盈利点, 单次盈利", _N(holdAmount * ProfitGoal, 4)); + initAccount = nowAccount; + isFinished = true; + if (!canOpen) { + Counter.f++; + } + break; + } + var newHoldPrice = 0; + var newHoldAmount = 0; + if (TradeType == ORDER_TYPE_BUY) { + newHoldAmount = _N(diffAmount, 4); + newHoldPrice = _N((-diffMoney) / diffAmount, 4); + } else { + newHoldAmount = _N(-diffAmount, 4); + newHoldPrice = _N(diffMoney / (-diffAmount), 4); + } + // if open again, we need adjust hold positions's price + var isAdd = false; + if (newHoldAmount > holdAmount) { + holdPrice = newHoldPrice; + isAdd = true; + } + holdAmount = newHoldAmount; + if (!isAdd) { + // reset initAccount + initAccount = { + Stocks : nowAccount.Stocks, + Balance : nowAccount.Balance, + FrozenBalance : nowAccount.FrozenBalance, + FrozenStocks : nowAccount.FrozenStocks, + }; + if (TradeType == ORDER_TYPE_BUY) { + initAccount.Stocks -= holdAmount; + initAccount.Balance += holdAmount * holdPrice; + } else { + initAccount.Stocks += holdAmount; + initAccount.Balance -= holdAmount * holdPrice; + } + initAccount.Stocks = _N(initAccount.Stocks, 4); + initAccount.Balance = _N(initAccount.Balance, 4); + Log("持仓前账户调整为: ", initAccount); + } + Log((TradeType == ORDER_TYPE_BUY ? "多仓" : "空仓"), (isAdd ? "加仓后" : "平仓后"), "重新调整持仓, 均价: ", holdPrice, "数量", holdAmount); + Log("买一:", ticker.Buy, "卖一:", ticker.Sell, "上次成交价:", ticker.Last); + Log(nowAccount); + break; + } + } + } + return 0; +} + +function onexit() { + StripOrders(exchange); + Log("Exit"); +} + +function main() { + if (AddLine > AddGoal || AddLine <= 0) { + throw "加仓均价目标错误"; + } + if (exchange.GetName().indexOf("Future") != -1) { + throw "只支持现货, 期货容易爆仓, 暂不支持"; + } + if (exchange.GetRate() != 1) { + Log("已禁用汇率转换"); + exchange.SetRate(1); + } + EnableLogLocal(SaveLocal); + Interval *= 1000; + SetErrorFilter("502:|503:|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF"); + StripOrders(exchange); + OrgAccount = GetAccount(exchange); + var isFirst = true; + LogStatus("启动成功"); + while (true) { + var ret = loop(isFirst); + isFirst = false; + if (ret != 0) { + Counter.f++; + if (TradeType == ORDER_TYPE_BUY) { + TradeType = ORDER_TYPE_SELL; + Log("开始反手做空"); + } else { + TradeType = ORDER_TYPE_BUY; + Log("开始反手做多"); + } + } else { + Counter.s++; + } + Sleep(Interval); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/164256 + +> 更新时间 + +2019-08-29 23:09:02 diff --git "a/\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).md" "b/\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).md" index 44706ff1..b8316f7d 100644 --- "a/\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).md" +++ "b/\345\215\225\347\213\254\350\256\241\347\256\227\346\224\266\347\233\212\357\274\210\344\273\243\347\240\201\346\235\245\350\207\252zero).md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/\345\215\225\350\264\247\345\270\201\345\212\250\346\200\201\345\235\207\350\241\241V1.0_\345\214\272\347\217\255\344\270\273.md" "b/\345\215\225\350\264\247\345\270\201\345\212\250\346\200\201\345\235\207\350\241\241V1.0_\345\214\272\347\217\255\344\270\273.md" new file mode 100644 index 00000000..20513218 --- /dev/null +++ "b/\345\215\225\350\264\247\345\270\201\345\212\250\346\200\201\345\235\207\350\241\241V1.0_\345\214\272\347\217\255\344\270\273.md" @@ -0,0 +1,95 @@ + +> 策略名称 + +单货币动态均衡V1.0_区班主 + +> 策略作者 + +tomjava + +> 策略描述 + +"Talk is cheap. Show me the code" + +教学性质, 实盘慎用. + + +注: ` 策略使用了交易模板类库` + +`希望新手从此策略入门, 一步步学习编写策略, 并体验到模拟与真实环境对交易系统的影响` + +https://dn-filebox.qbox.me/fb4d0c7d773ca83e9d0230927705d419dc0bbeaa.png + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Interval|60|轮询周期(秒)| +|changeRatio|0.1|切换预警比率| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2019-01-01 00:00:00 +end: 2019-10-10 00:00:00 +period: 1d +exchanges: [{"eid":"OKEX","currency":"BTC_USDT","stocks":0}] +*/ +//非常简单的单货币动态均衡策略,低于50%的一定比例就买入,高于就卖出 +//注册币乎后https://m.bihu.com/signup?i=1ewtKO&s=4&c=4 +//搜索 物联网区块链 可以联系到作者区班主 +function main() { + var STATE_IDLE = -1; + var state = STATE_IDLE; //表示空仓 + var entryPrice = 0; + var initAccount = _C(exchange.GetAccount); + var obj; + var allAmount; + var cashRatio; + Log(initAccount); + while (true) { + var account = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + if (state === STATE_IDLE) { //初始化状态为默认仓;默认为空仓,只买入 + obj = $.Buy(_N(account.Balance * 0.5 / ticker.Sell, 3)); + if (obj) { //如果购买成功,就标志开仓 + opAmount = obj.amount; + entryPrice = obj.price; + state = PD_LONG; + account = _C(exchange.GetAccount); + Log("开仓买入",obj.amount,"价格",obj.price,"目前持币数", account.Stocks); + } + } else { //state为非空闲状态;处理动态平衡检测 + allAmount=account.Balance+account.Stocks*ticker.Sell; //计算出总金额 + cashRatio=parseFloat((account.Balance/allAmount).toFixed(3)); + //Log("现金",account.Balance,"总资产",allAmount,"比例",cashRatio); + if (cashRatio>0.5+changeRatio) { //现金多了,需要买入货币 + obj = $.Buy(_N(allAmount*(cashRatio-0.5)/ticker.Sell/2.0, 3)); //把多出来的一半买掉,这样才能均衡 + if(obj){ + Log("开仓买入",obj.amount,"价格",obj.price); + Log("目前资金",allAmount, "盈利",allAmount - initAccount.Balance); + } + }else if(cashRatio<0.5-changeRatio){ //现金少了,需要抛币 + obj = $.Sell(_N(allAmount*(0.5-cashRatio)/ticker.Sell/2.0, 3)); //把多出来的部分买掉 + if(obj){ + Log("平仓买出",obj.amount,"价格",obj.price); + Log("目前资金",allAmount, "盈利",allAmount - initAccount.Balance); + } + } + } + Sleep(Interval*1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/169701 + +> 更新时间 + +2019-10-12 16:48:48 diff --git "a/\345\215\225\350\276\271\347\275\221\346\240\274 (Copy).md" "b/\345\215\225\350\276\271\347\275\221\346\240\274 (Copy).md" deleted file mode 100644 index 26c3df4b..00000000 --- "a/\345\215\225\350\276\271\347\275\221\346\240\274 (Copy).md" +++ /dev/null @@ -1,190 +0,0 @@ - -> 策略名称 - -单边网格 (Copy) - -> 策略作者 - -xd123456 - -> 策略描述 - -测试的时候填写起始价格来测试是否正常 -起始价格不填写为现价买入+价格区间买入 -微信173970984 - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|buyjingdu|2|下单价格精度| -|buymount|3|下单数量精度| -|buypersent|true|下单百分比| -|buylimit|0.01|最小交易量| -|reffertime|3000|刷新时间间隔| -|moneybt|100|网格的价格间距| -|startpricex|false|起始价格| -|liruncha|0.1|利润差价| - - -> 源码 (javascript) - -``` javascript -//获取账户余额 -var startPrice= 0; -function getBalancex(){ - var balance = exchange.GetAccount(); - Log("余额:", balance.Balance,"币余额:", balance.Stocks); - return balance; -} - - -//获取币种现价 -function getPrice(typex){ - var NowPrice =exchange.GetTicker(); - if(typex=='buy'){ - - Log("当前买入价格:"+(NowPrice.Buy)) - return NowPrice.Buy; - } - if(typex=='sell'){ - Log("当前卖出价格:"+(NowPrice.Sell)) - return NowPrice.Sell; - } -} - -//取消所有买单操作重新下单 -function cancelOrders(){ - //获取所有未成交订单 - var orders = _C(exchange.GetOrders); - for(var z in orders){ - //# Log("当前订单类型:",orders[z].Type,"订单Id:",orders[z].Id); - if(orders[z].Type==0){ - exchange.CancelOrder(orders[z].Id) - Log("取消之前的挂单成功,id:",orders[z].Id); - } - } - /* - for(var i=0;i0){ - price=startpricex-moneybt; - }else{ - price=price-moneybt; //实际价格为当前价格减去区间价格 - } - startPrice=price; - var balancex = getBalancex(); - balanceAmount = balancex.Balance; - - //需要购买的数量 - doAmount = (balanceAmount*(buypersent/100))/price - - - - var id = 0; - if(doAmount>buylimit){ - saveBuyId=id= exchange.Buy(price, doAmount); - Log("下单成功id:", id," 价格:", price," 数量:", doAmount); - }else{ - Log("可买数量低于最小交易量:", buylimit," 数量:", doAmount); - } -} - - -//根据上次的ID来检查订单状态 然后出售 -function doSellTrading2(){ - //获取订单状态 - Log("上一订单ID:", saveBuyId); - if(saveBuyId!=0){ - var order = exchange.GetOrder(saveBuyId); - if(order){ - if(order.Status==ORDER_STATE_CLOSED){ - leftStocks=leftStocks-orderList[i].Amount - var sellPrice = order.Price+liruncha; - var sellAmount = order.Amount; - var id=exchange.Sell(sellPrice, sellAmount); - Log("出售成功id:", id," 价格:", sellPrice," 数量:", sellAmount); - } - } - } - -} - - - - - - - - - -//定时扫描是否有买单成交 并出售对应数量 -function doSellTrading(){ - //如果余额大于零 - balan = getBalancex() - leftStocks=balan.Stocks; - if(balan.Stocks>0){ - var orderList = exchange.GetTrades() - //理论检测前20条数据即可 - if(orderList){ - for(i=0;i<=100;i++){ - //Log("查看订单信息:",orderList); - if(orderList[i].Type==0 && leftStocks>orderList[i].Amount){ - leftStocks=leftStocks-orderList[i].Amount - var sellPrice = orderList[i].Price+liruncha; - var sellAmount = orderList[i].Amount; - var id=exchange.Sell(sellPrice, sellAmount); - Log("出售成功id:", id," 价格:", sellPrice," 数量:", sellAmount); - } - } - } - } -} - - -function onTick(){ - //在这里写策略逻辑,将会不断调用exchange - doSellTrading2() - doTradingBuy() -} -/* -function main(){ - var id = exchange.Sell(99999, 1); - var order = exchange.GetOrder(id);//参数id为订单号码,需填入你想要查询的订单的号码 - Log("Id", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:", - order.DealAmount, "Status:", order.Status, "Type:", order.Type); -} -*/ -function main(){ - exchange.SetPrecision(buyjingdu, buymount); - while(true){ - onTick(); - Sleep(reffertime); - } -} -``` - -> 策略出处 - -https://www.fmz.com/strategy/144679 - -> 更新时间 - -2019-04-19 14:36:15 diff --git "a/\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).md" "b/\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).md" new file mode 100644 index 00000000..260ae991 --- /dev/null +++ "b/\345\215\225\350\276\271\347\275\221\346\240\274 (OK\346\234\237\350\264\247).md" @@ -0,0 +1,499 @@ + +> 策略名称 + +单边网格 (OK期货) + +> 策略作者 + +威尔士发 + +> 策略描述 + +网格可以自定义方向 +先买后卖: +网格会从首价格开始向下挂买单, 每个买单间隔 "价格间隔" 这个参数, 挂单数量为"单笔数量", 挂够 "总数量" 个买单, 有任意买单成交以后, 程序会在买价基础上加 "价差(元)" 这个参数的的值的价格挂出卖单, 卖出, 卖出以后,重新按原来这个网格的价格挂买入单 +先卖后买: +操作刚好相反 + +策略最大的风险就是单边行情, 价格波动超出网格范围. + +网格带有自动止损和移动功能 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|ContractTypeIdx|0|合约品种: 当周|次周|季度| +|OpType|0|网格方向: 先买后卖|先卖后买| +|FirstPriceAuto|false|首价格自动| +|FirstPrice|100|首价格| +|AllNum|10|总数量| +|PriceGrid|true|价格间隔| +|PriceDiff|2|价差(元)| +|AmountType|0|订单大小: 买卖同量|自定义量| +|AmountOnce|true|单笔数量| +|BAmountOnce|true|买单大小| +|SAmountOnce|true|卖单大小| +|MarginLevelIdx|0|杠杆大小: 10|20| +|EnableProtectDiff|false|开启价差保护| +|ProtectDiff|20|入市价差保护| +|CancelAllWS|true|停止时取消取有挂单| +|CheckInterval|2000|轮询间隔| +|Interval|1300|失败重试间隔| +|RestoreProfit|false|恢复上次盈利| +|LastProfit|false|上次盈利| +|ProfitAsOrg|false|上次盈利算入均价| +|EnableStopLoss|false|开启止损| +|StopLoss|0.1|最大浮动亏损| +|StopLossMode|0|止损后操作: 回收并退出|回收再撒网| +|AutoMove|false|自动移动| +|MaxDistance|20|最大距离(元)| +|MaxIdle|7200|最大空闲(秒)| + + + + +|按钮|默认值|描述| +|----|----|----| +|收网|__button__|停止并平衡到初始状态| + + +> 源码 (javascript) + +``` javascript +var isFuture = false; + +function hasOrder(orders, orderId) { + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == orderId) { + return true; + } + } + return false; +} + + +function cancelPending() { + var ret = false; + while (true) { + if (ret) { + Sleep(Interval); + } + var orders = _C(exchange.GetOrders); + if (orders.length == 0) { + break; + } + + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]); + ret = true; + } + } + return ret; +} + + +function balanceAccount(orgAccount, initAccount) { + if (isFuture) { + while (true) { + cancelPending(); + var positions = _C(exchange.GetPosition); + if (positions.length === 0 ) { + var accountNow = _C(exchange.GetAccount); + LogProfit(_N(accountNow.Stocks - orgAccount.Stocks), "可用保证金:", accountNow.Stocks); + return; + } + for (var i = 0; i < positions.length; i++) { + if (positions[i].Type == PD_LONG) { + exchange.SetDirection("closebuy"); + exchange.Sell(positions[i].Amount); + } else { + exchange.SetDirection("closesell"); + exchange.Buy(positions[i].Amount); + } + } + Sleep(Interval); + } + } + var account = _C(exchange.GetAccount); + while (true) { + var diff = _N(account.Stocks - initAccount.Stocks); + if (Math.abs(diff) < exchange.GetMinStock()) { + break; + } + var depth = _C(exchange.GetDepth); + var books = diff > 0 ? depth.Bids : depth.Asks; + var n = 0; + var price = 0; + for (var i = 0; i < books.length; i++) { + n += books[i].Amount; + if (n >= Math.abs(diff)) { + price = books[i].Price; + break; + } + } + Log("开始平衡", (diff > 0 ? "卖出" : "买入"), Math.abs(diff), "个币"); + if (diff > 0) { + exchange.Sell(price - 0.2, diff); + } else { + exchange.Buy(price + 0.2, -diff); + } + Sleep(1000); + cancelPending(); + account = _C(exchange.GetAccount); + } + Log("平衡完成", account); +} + +var STATE_WAIT_OPEN = 0; +var STATE_WAIT_COVER = 1; +var STATE_WAIT_CLOSE = 2; +var ProfitCount = 0; +var BuyFirst = (OpType == 0); +var IsSupportGetOrder = true; +var LastBusy = 0; +var LastFloatProfit = 0; + +function setBusy() { + LastBusy = new Date(); +} + +function isTimeout() { + if (MaxIdle <= 0) { + return false; + } + var now = new Date(); + if (((now.getTime() - LastBusy.getTime()) / 1000) >= MaxIdle) { + LastBusy = now; + return true; + } + return false; +} + +function onexit() { + if (CancelAllWS) { + Log("正在退出, 尝试取消所有挂单"); + cancelPending(); + } + Log("策略成功停止"); + Log(_C(exchange.GetAccount)); +} + + +function fishing(orgAccount, fishCount) { + setBusy(); + var account = _C(exchange.GetAccount); + Log(account); + var InitAccount = account; + var ticker = _C(exchange.GetTicker); + var amount = _N(AmountOnce); + var amountB = amount; + var amountS = amount; + if (typeof(AmountType) !== 'undefined' && AmountType == 1) { + amountB = BAmountOnce; + amountS = SAmountOnce; + } + if (FirstPriceAuto) { + FirstPrice = BuyFirst ? _N(ticker.Buy - PriceGrid) : _N(ticker.Sell + PriceGrid); + } + // Initialize fish table + var fishTable = {}; + var uuidTable = {}; + var needStocks = 0; + var needMoney = 0; + var actualNeedMoney = 0; + var actualNeedStocks = 0; + var notEnough = false; + var canNum = 0; + var marginLevel = [10,20][MarginLevelIdx]; + exchange.SetMarginLevel(marginLevel); + for (var idx = 0; idx < AllNum; idx++) { + var price = _N(BuyFirst ? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)); + if (isFuture) { + needStocks += ((100 * amountB) / price) / marginLevel; + if (_N(needStocks) <= _N(account.Stocks)) { + actualNeedStocks = needStocks; + canNum++; + } else { + notEnough = true; + } + } else { + needStocks += amountS; + needMoney += price * amountB; + if (BuyFirst) { + if (_N(needMoney) <= _N(account.Balance)) { + actualNeedMondy = needMoney; + actualNeedStocks = needStocks; + canNum++; + } else { + notEnough = true; + } + } else { + if (_N(needStocks) <= _N(account.Stocks)) { + actualNeedMondy = needMoney; + actualNeedStocks = needStocks; + canNum++; + } else { + notEnough = true; + } + } + } + fishTable[idx] = STATE_WAIT_OPEN; + uuidTable[idx] = -1; + } + if (EnableProtectDiff) { + if (BuyFirst && (FirstPrice - ticker.Sell) > ProtectDiff) { + throw "首次买入价比市场卖1价高" + _N(FirstPrice - ticker.Sell) + ' 元'; + } else if (!BuyFirst && (ticker.Buy - FirstPrice) > ProtectDiff) { + throw "首次卖出价比市场买1价高 " + _N(ticker.Buy - FirstPrice) + ' 元'; + } + } + if (BuyFirst && !isFuture) { + if (account.Balance < _N(needMoney)) { + if (fishCount == 1) { + throw "资金不足, 需要"+ _N(needMoney) + "元"; + } else { + Log("资金不足, 需要", _N(needMoney), "元, 程序只做", canNum, "个网格 #ff0000"); + } + } else { + Log('预计动用资金: ', _N(needMoney), "元"); + } + } else { + if (account.Stocks < _N(needStocks)) { + if (fishCount == 1) { + throw "币数不足, 需要 "+ _N(needStocks) + " 个币"; + } else { + Log("资金不足, 需要", _N(needStocks), "个币, 程序只做", canNum, "个网格 #ff0000"); + } + } else { + Log('预计动用币数: ', _N(needStocks), "个"); + } + } + + var OpenFunc = BuyFirst ? exchange.Buy : exchange.Sell; + var CoverFunc = BuyFirst ? exchange.Sell : exchange.Buy; + var ts = new Date(); + var preMsg = ""; + var profitMax = 0; + while (true) { + var now = new Date(); + if (now.getTime() - ts.getTime() > 5000) { + if (typeof(GetCommand) == 'function' && GetCommand() == "收网") { + Log("开始执行命令进行收网操作"); + balanceAccount(orgAccount, InitAccount); + return false; + } + ts = now; + var msg = ""; + var positions, isHold; + var ticker = _C(exchange.GetTicker); + var nowAccount = _C(exchange.GetAccount); + if (isFuture) { + positions = _C(exchange.GetPosition); + isHold = positions.length > 0; + if (isHold) { + msg += "持仓: " + positions[0].Amount + " 持仓均价: " + _N(positions[0].Price) + " 浮动盈亏: " + _N(positions[0].Profit); + if (EnableStopLoss && -positions[0].Profit >= StopLoss) { + Log("当前浮动盈亏", positions[0].Profit, "开始止损"); + balanceAccount(orgAccount, InitAccount); + if (StopLossMode === 0) { + throw "止损退出"; + } else { + return true; + } + } + } else { + msg += "空仓"; + } + msg += " 可用保证金: " + nowAccount.Stocks; + + } else { + isHold = Math.abs(amount_diff) >= exchange.GetMinStock(); + + var amount_diff = (nowAccount.Stocks + nowAccount.FrozenStocks) - (InitAccount.Stocks + InitAccount.FrozenStocks); + var money_diff = (nowAccount.Balance + nowAccount.FrozenBalance) - (InitAccount.Balance + InitAccount.FrozenBalance); + var floatProfit = _N(money_diff + (amount_diff * ticker.Last)); + var floatProfitAll = _N((nowAccount.Balance + nowAccount.FrozenBalance - orgAccount.Balance - orgAccount.FrozenBalance) + ((nowAccount.Stocks + nowAccount.FrozenStocks - orgAccount.Stocks - orgAccount.FrozenStocks) * ticker.Last)); + LastFloatProfit = floatProfitAll; + profitMax = Math.max(floatProfit, profitMax); + if (EnableStopLoss) { + if ((profitMax - floatProfit) >= StopLoss) { + Log("当前浮动盈亏", floatProfit, "利润最高点: ", profitMax, "开始止损"); + balanceAccount(orgAccount, InitAccount); + if (StopLossMode === 0) { + throw "止损退出"; + } else { + return true; + } + } + } + if (isHold) { + if (RestoreProfit && ProfitAsOrg) { + if (BuyFirst) { + money_diff += LastProfit; + } else { + money_diff -= LastProfit; + } + } + var hold_amount = amount_diff; + var hold_price = (-money_diff) / amount_diff; + if (!BuyFirst) { + hold_amount = -amount_diff; + hold_price = (money_diff) / -amount_diff; + } + msg = (BuyFirst ? "做多: " : "做空: ") + _N(hold_amount, 4) + " 个币, 均价: " + _N(hold_price); + } else { + msg += "空仓"; + } + msg += " 当前网格浮动盈亏: " + floatProfit + " 总浮动盈亏: " + floatProfitAll + " 第 " + fishCount + " 次撒网 最新币价: " + _N(ticker.Last); + } + if (isHold) { + setBusy(); + } + + var distance = 0; + if (AutoMove) { + if (BuyFirst) { + distance = ticker.Last - FirstPrice; + } else { + distance = FirstPrice - ticker.Last; + } + var refish = false; + if (!isHold && isTimeout()) { + Log("空仓过久, 开始移动网格"); + refish = true; + } + if (distance > MaxDistance) { + Log("价格超出网格区间过多, 开始移动网格, 当前距离: ", _N(distance), "当前价格:", ticker.Last); + refish = true; + } + if (refish) { + balanceAccount(orgAccount, InitAccount); + return true; + } + } + + if (AutoMove && distance > 0) { + msg += " (离网格" + (BuyFirst ? "向上" : "向下") + "偏离: " + _N(distance) + " 元)"; + } + if (msg != preMsg) { + LogStatus(msg); + preMsg = msg; + } + + } + var orders = _C(exchange.GetOrders); + for (var idx = 0; idx < canNum; idx++) { + var openPrice = _N(BuyFirst ? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)); + var coverPrice = _N(BuyFirst ? openPrice + PriceDiff : openPrice - PriceDiff); + var state = fishTable[idx]; + var fishId = uuidTable[idx]; + if (hasOrder(orders, fishId)) { + continue; + } + + if (fishId != -1 && IsSupportGetOrder) { + var order = exchange.GetOrder(fishId); + if (!order) { + Log("获取订单信息失败, ID: ", fishId); + continue; + } + if (order.Status == ORDER_STATE_PENDING) { + Log("订单状态为未完成, ID: ", fishId); + continue; + } + } + + if (state == STATE_WAIT_COVER) { + if (isFuture) { + exchange.SetDirection(BuyFirst ? "closebuy" : "closesell"); + } + var coverId = CoverFunc(coverPrice, BuyFirst ? amountS : amountB, BuyFirst ? '完成买单:' : '完成卖单:', openPrice); + if (coverId > 0) { + fishTable[idx] = STATE_WAIT_CLOSE; + uuidTable[idx] = coverId; + } + } else if (state == STATE_WAIT_OPEN || state == STATE_WAIT_CLOSE) { + if (isFuture) { + exchange.SetDirection(BuyFirst ? "buy" : "sell"); + } + var openId = OpenFunc(openPrice, BuyFirst ? amountB : amountS); + if (openId > 0) { + fishTable[idx] = STATE_WAIT_COVER; + uuidTable[idx] = openId; + if (state == STATE_WAIT_CLOSE) { + ProfitCount++; + if (AmountType === 0) { + Log((BuyFirst ? '完成卖单: ' : '完成买单: ') + coverPrice); + } else { + Log((BuyFirst ? '完成卖单: ' : '完成买单: ') + coverPrice); + } + if (!isFuture) { + var account = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + var initNet = _N(((InitAccount.Stocks + InitAccount.FrozenStocks) * ticker.Buy) + InitAccount.Balance + InitAccount.FrozenBalance, 8); + var nowNet = _N(((account.Stocks + account.FrozenStocks) * ticker.Buy) + account.Balance + account.FrozenBalance, 8); + var actualProfit = _N(((nowNet - initNet)) * 100 / initNet, 8); + LogProfit(LastFloatProfit, "总浮动盈亏率:", _N(LastFloatProfit * 100 / actualNeedMondy, 4), '%'); + } + } + } + } + } + Sleep(CheckInterval); + } + return true; +} + +function main() { + if (typeof(AmountType) === 'undefined') { + AmountType = 0; + } + IsSupportGetOrder = exchange.GetName().indexOf('itstamp') == -1; + if (!IsSupportGetOrder) { + Log(exchange.GetName(), "不支持GetOrder, 可能影响策略稳定性."); + } + + isFuture = exchange.GetName().indexOf("Future") != -1; + if (AmountType === 0) { + BAmountOnce = AmountOnce; + SAmountOnce = AmountOnce; + } + if (exchange.GetName() == "Futures_OKCoin" && (AmountOnce.toString().indexOf(".") != -1 || BAmountOnce.toString().indexOf(".") != -1 || SAmountOnce.toString().indexOf(".") != -1)) { + throw "OKCoin期货下单数必须为整数"; + } + + SetErrorFilter("502:|503:|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|refused|EOF|When"); + + exchange.SetRate(1); + Log('已经禁用汇率转换, 当前货币为', exchange.GetBaseCurrency()); + + if (!RestoreProfit) { + LastProfit = 0; + } + exchange.SetContractType(["this_week", "next_week", "quarter"][ContractTypeIdx]); + var orgAccount = _C(exchange.GetAccount); + var fishCount = 1; + while (true) { + if (!fishing(orgAccount, fishCount)) { + break; + } + fishCount++; + Log("第", fishCount, "次重新撒网..."); + FirstPriceAuto = true; + Sleep(1000); + } +} + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/164252 + +> 更新时间 + +2019-08-29 23:06:31 diff --git "a/\345\215\225\350\276\271\347\275\221\346\240\274x\347\216\260\350\264\247.md" "b/\345\215\225\350\276\271\347\275\221\346\240\274x\347\216\260\350\264\247.md" new file mode 100644 index 00000000..024d98d8 --- /dev/null +++ "b/\345\215\225\350\276\271\347\275\221\346\240\274x\347\216\260\350\264\247.md" @@ -0,0 +1,675 @@ + +> 策略名称 + +单边网格x现货 + +> 策略作者 + +威尔士发 + +> 策略描述 + +网格可以自定义方向 +先买后卖: +网格会从首价格开始向下挂买单, 每个买单间隔 "价格间隔" 这个参数, 挂单数量为"单笔数量", 挂够 "总数量" 个买单, 有任意买单成交以后, 程序会在买价基础上加 "价差(元)" 这个参数的的值的价格挂出卖单, 卖出, 卖出以后,重新按原来这个网格的价格挂买入单 +先卖后买: +操作刚好相反 + +策略最大的风险就是单边行情, 价格波动超出网格范围. + +网格带有自动止损和移动功能 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|OpType|0|网格方向: 先买后卖|先卖后买| +|FirstPriceAuto|true|首价格自动| +|FirstPrice|100|首价格| +|AllNum|10|总数量| +|PriceGrid|true|价格间隔| +|PriceDiff|2|价差(元)| +|AmountType|0|订单大小: 买卖同量|自定义量| +|AmountOnce|0.1|单笔数量| +|BAmountOnce|0.1|买单大小| +|SAmountOnce|0.1|卖单大小| +|AmountCoefficient|*1|量差| +|AmountDot|3|量小数点最长位数| +|EnableProtectDiff|false|开启价差保护| +|ProtectDiff|20|入市价差保护| +|CancelAllWS|true|停止时取消所有挂单| +|CheckInterval|2000|轮询间隔| +|Interval|1300|失败重试间隔| +|RestoreProfit|false|恢复上次盈利| +|LastProfit|false|上次盈利| +|ProfitAsOrg|false|上次盈利算入均价| +|EnableAccountCheck|true|启用资金检验| +|EnableStopLoss|false|开启止损| +|StopLoss|100|最大浮动亏损(元)| +|StopLossMode|0|止损后操作: 回收并退出|回收再撒网| +|EnableStopWin|false|开启止盈| +|StopWin|120|最大浮动盈利(元)| +|StopWinMode|0|止盈后操作: 回收并退出|回收再撒网| +|AutoMove|false|自动移动| +|MaxDistance|20|最大距离(元)| +|MaxIdle|7200|最大空闲(秒)| +|EnableDynamic|false|开启动态挂单| +|DynamicMax|30|订单失效距离(元)| +|ResetData|true|启动时清空所有数据| +|Precision|5|价格小数位长度| +|XPrecision|5|下单量小数位长度| +|MinStock|0.001|最小交易量| + + + + +|按钮|默认值|描述| +|----|----|----| +|收网|__button__|停止并平衡到初始状态| + + +> 源码 (javascript) + +``` javascript +function hasOrder(orders, orderId) { + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == orderId) { + return true; + } + } + return false; +} + + +function cancelPending() { + var ret = false; + while (true) { + if (ret) { + Sleep(Interval); + } + var orders = _C(exchange.GetOrders); + if (orders.length == 0) { + break; + } + + for (var j = 0; j < orders.length; j++) { + exchange.CancelOrder(orders[j].Id, orders[j]); + ret = true; + } + } + return ret; +} + +function valuesToString(values, pos) { + var result = ''; + if (typeof(pos) === 'undefined') { + pos = 0; + } + for (var i = pos; i < values.length; i++) { + if (i > pos) { + result += ' '; + } + if (values[i] === null) { + result += 'null'; + } else if (typeof(values[i]) == 'undefined') { + result += 'undefined'; + } else { + switch (values[i].constructor.name) { + case 'Date': + case 'Number': + case 'String': + case 'Function': + result += values[i].toString(); + break; + default: + result += JSON.stringify(values[i]); + break; + } + } + } + return result; +} + +function Trader() { + var vId = 0; + var orderBooks = []; + var hisBooks = []; + var orderBooksLen = 0; + this.Buy = function(price, amount, extra) { + if (typeof(extra) === 'undefined') { + extra = ''; + } else { + extra = valuesToString(arguments, 2); + } + vId++; + var orderId = "V" + vId; + orderBooks[orderId] = { + Type: ORDER_TYPE_BUY, + Status: ORDER_STATE_PENDING, + Id: 0, + Price: price, + Amount: amount, + Extra: extra + }; + orderBooksLen++; + return orderId; + }; + this.Sell = function(price, amount, extra) { + if (typeof(extra) === 'undefined') { + extra = ''; + } else { + extra = valuesToString(arguments, 2); + } + vId++; + var orderId = "V" + vId; + orderBooks[orderId] = { + Type: ORDER_TYPE_SELL, + Status: ORDER_STATE_PENDING, + Id: 0, + Price: price, + Amount: amount, + Extra: extra + }; + orderBooksLen++; + return orderId; + }; + this.GetOrders = function() { + var orders = _C(exchange.GetOrders); + for (orderId in orderBooks) { + var order = orderBooks[orderId]; + if (order.Status !== ORDER_STATE_PENDING) { + continue; + } + var found = false; + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == order.Id) { + found = true; + break; + } + } + if (!found) { + orders.push(orderBooks[orderId]); + } + } + return orders; + } + this.GetOrder = function(orderId) { + if (typeof(orderId) === 'number') { + return exchange.GetOrder(orderId); + } + if (typeof(hisBooks[orderId]) !== 'undefined') { + return hisBooks[orderId]; + } + if (typeof(orderBooks[orderId]) !== 'undefined') { + return orderBooks[orderId]; + } + return null; + }; + this.Len = function() { + return orderBooksLen; + }; + this.RealLen = function() { + var n = 0; + for (orderId in orderBooks) { + if (orderBooks[orderId].Id > 0) { + n++; + } + } + return n; + }; + this.Poll = function(ticker, priceDiff) { + var orders = _C(exchange.GetOrders); + for (orderId in orderBooks) { + var order = orderBooks[orderId]; + if (order.Id > 0) { + var found = false; + for (var i = 0; i < orders.length; i++) { + if (order.Id == orders[i].Id) { + found = true; + } + } + if (!found) { + order.Status = ORDER_STATE_CLOSED; + hisBooks[orderId] = order; + delete(orderBooks[orderId]); + orderBooksLen--; + continue; + } + } + var diff = _N(order.Type == ORDER_TYPE_BUY ? (ticker.Buy - order.Price) : (order.Price - ticker.Sell)); + var pfn = order.Type == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell; + if (order.Id == 0 && diff <= priceDiff) { + var realId = pfn(order.Price, order.Amount, order.Extra + "(距离: " + diff + (order.Type == ORDER_TYPE_BUY ? (" 买一: " + ticker.Buy) : (" 卖一: " + ticker.Sell))+")"); + if (typeof(realId) === 'number') { + order.Id = realId; + } + } else if (order.Id > 0 && diff > (priceDiff + 1)) { + var ok = true; + do { + ok = true; + exchange.CancelOrder(order.Id, "不必要的" + (order.Type == ORDER_TYPE_BUY ? "买单" : "卖单"), "委托价:", order.Price, "量:", order.Amount, ", 距离:", diff, order.Type == ORDER_TYPE_BUY ? ("买一: " + ticker.Buy) : ("卖一: " + ticker.Sell)); + Sleep(200); + orders = _C(exchange.GetOrders); + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == order.Id) { + ok = false; + } + } + } while (!ok); + order.Id = 0; + } + } + }; +} + +function balanceAccount(orgAccount, initAccount) { + cancelPending(); + var nowAccount = _C(exchange.GetAccount); + var slidePrice = 0.2; + var ok = true; + while (true) { + var diff = _N(nowAccount.Stocks - initAccount.Stocks); + if (Math.abs(diff) < MinStock) { + break; + } + var depth = _C(exchange.GetDepth); + var books = diff > 0 ? depth.Bids : depth.Asks; + var n = 0; + var price = 0; + for (var i = 0; i < books.length; i++) { + n += books[i].Amount; + if (n >= Math.abs(diff)) { + price = books[i].Price; + break; + } + } + var pfn = diff > 0 ? exchange.Sell : exchange.Buy; + var amount = Math.abs(diff); + var price = diff > 0 ? (price - slidePrice) : (price + slidePrice); + Log("开始平衡", (diff > 0 ? "卖出" : "买入"), amount, "个币"); + if (diff > 0) { + amount = Math.min(nowAccount.Stocks, amount); + } else { + amount = Math.min(nowAccount.Balance / price, amount); + } + if (amount < MinStock) { + Log("资金不足, 无法平衡到初始状态"); + ok = false; + break; + } + pfn(price, amount); + Sleep(1000); + cancelPending(); + nowAccount = _C(exchange.GetAccount); + } + if (ok) { + LogProfit(_N(nowAccount.Balance - orgAccount.Balance)); + Log("平衡完成", nowAccount); + } +} + +var STATE_WAIT_OPEN = 0; +var STATE_WAIT_COVER = 1; +var STATE_WAIT_CLOSE = 2; +var ProfitCount = 0; +var BuyFirst = true; +var IsSupportGetOrder = true; +var LastBusy = 0; + +function setBusy() { + LastBusy = new Date(); +} + +function isTimeout() { + if (MaxIdle <= 0) { + return false; + } + var now = new Date(); + if (((now.getTime() - LastBusy.getTime()) / 1000) >= MaxIdle) { + LastBusy = now; + return true; + } + return false; +} + +function onexit() { + if (CancelAllWS) { + Log("正在退出, 尝试取消所有挂单"); + cancelPending(); + } + Log("策略成功停止"); + Log(_C(exchange.GetAccount)); +} + + +function fishing(orgAccount, fishCount) { + setBusy(); + var account = _C(exchange.GetAccount); + Log(account); + var InitAccount = account; + var ticker = _C(exchange.GetTicker); + var amount = _N(AmountOnce); + var amountB = [amount]; + var amountS = [amount]; + if (typeof(AmountType) !== 'undefined' && AmountType == 1) { + for (var idx = 0; idx < AllNum; idx++) { + amountB[idx] = BAmountOnce; + amountS[idx] = SAmountOnce; + } + } else { + for (var idx = 1; idx < AllNum; idx++) { + switch (AmountCoefficient[0]) { + case '+': + amountB[idx] = amountB[idx - 1] + parseFloat(AmountCoefficient.substring(1)); + break; + case '-': + amountB[idx] = amountB[idx - 1] - parseFloat(AmountCoefficient.substring(1)); + break; + case '*': + amountB[idx] = amountB[idx - 1] * parseFloat(AmountCoefficient.substring(1)); + break; + case '/': + amountB[idx] = amountB[idx - 1] / parseFloat(AmountCoefficient.substring(1)); + break; + } + amountB[idx] = _N(amountB[idx], AmountDot); + amountS[idx] = amountB[idx]; + } + } + if (FirstPriceAuto) { + FirstPrice = BuyFirst ? _N(ticker.Buy - PriceGrid, Precision) : _N(ticker.Sell + PriceGrid, Precision); + } + // Initialize fish table + var fishTable = {}; + var uuidTable = {}; + var needStocks = 0; + var needMoney = 0; + var actualNeedMoney = 0; + var actualNeedStocks = 0; + var notEnough = false; + var canNum = 0; + for (var idx = 0; idx < AllNum; idx++) { + var price = _N((BuyFirst ? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)), Precision); + needStocks += amountS[idx]; + needMoney += price * amountB[idx]; + if (BuyFirst) { + if (_N(needMoney) <= _N(account.Balance)) { + actualNeedMondy = needMoney; + actualNeedStocks = needStocks; + canNum++; + } else { + notEnough = true; + } + } else { + if (_N(needStocks) <= _N(account.Stocks)) { + actualNeedMondy = needMoney; + actualNeedStocks = needStocks; + canNum++; + } else { + notEnough = true; + } + } + fishTable[idx] = STATE_WAIT_OPEN; + uuidTable[idx] = -1; + } + if (!EnableAccountCheck && (canNum < AllNum)) { + Log("警告, 当前资金只可做", canNum, "个网格, 全网共需", (BuyFirst ? needMoney : needStocks), "请保持资金充足"); + canNum = AllNum; + } + if (BuyFirst) { + if (EnableProtectDiff && (FirstPrice - ticker.Sell) > ProtectDiff) { + throw "首次买入价比市场卖1价高" + _N(FirstPrice - ticker.Sell, Precision) + ' 元'; + } else if (EnableAccountCheck && account.Balance < _N(needMoney)) { + if (fishCount == 1) { + throw "资金不足, 需要" + _N(needMoney) + "元"; + } else { + Log("资金不足, 需要", _N(needMoney), "元, 程序只做", canNum, "个网格 #ff0000"); + } + } else { + Log('预计动用资金: ', _N(needMoney), "元"); + } + } else { + if (EnableProtectDiff && (ticker.Buy - FirstPrice) > ProtectDiff) { + throw "首次卖出价比市场买1价高 " + _N(ticker.Buy - FirstPrice, Precision) + ' 元'; + } else if (EnableAccountCheck && account.Stocks < _N(needStocks)) { + if (fishCount == 1) { + throw "币数不足, 需要 " + _N(needStocks) + " 个币"; + } else { + Log("资金不足, 需要", _N(needStocks), "个币, 程序只做", canNum, "个网格 #ff0000"); + } + } else { + Log('预计动用币数: ', _N(needStocks), "个, 约", _N(needMoney), "元"); + } + } + + var trader = new Trader(); + var OpenFunc = BuyFirst ? exchange.Buy : exchange.Sell; + var CoverFunc = BuyFirst ? exchange.Sell : exchange.Buy; + if (EnableDynamic) { + OpenFunc = BuyFirst ? trader.Buy : trader.Sell; + CoverFunc = BuyFirst ? trader.Sell : trader.Buy; + } + var ts = new Date(); + var preMsg = ""; + var profitMax = 0; + while (true) { + var now = new Date(); + var table = null; + if (now.getTime() - ts.getTime() > 5000) { + if (typeof(GetCommand) == 'function' && GetCommand() == "收网") { + Log("开始执行命令进行收网操作"); + balanceAccount(orgAccount, InitAccount); + return false; + } + ts = now; + var nowAccount = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + if (EnableDynamic) { + trader.Poll(ticker, DynamicMax); + } + var amount_diff = (nowAccount.Stocks + nowAccount.FrozenStocks) - (InitAccount.Stocks + InitAccount.FrozenStocks); + var money_diff = (nowAccount.Balance + nowAccount.FrozenBalance) - (InitAccount.Balance + InitAccount.FrozenBalance); + var floatProfit = _N(money_diff + (amount_diff * ticker.Last)); + var floatProfitAll = _N((nowAccount.Balance + nowAccount.FrozenBalance - orgAccount.Balance - orgAccount.FrozenBalance) + ((nowAccount.Stocks + nowAccount.FrozenStocks - orgAccount.Stocks - orgAccount.FrozenStocks) * ticker.Last)); + var isHold = Math.abs(amount_diff) >= MinStock; + if (isHold) { + setBusy(); + } + + profitMax = Math.max(floatProfit, profitMax); + if (EnableAccountCheck && EnableStopLoss) { + if ((profitMax - floatProfit) >= StopLoss) { + Log("当前浮动盈亏", floatProfit, "利润最高点: ", profitMax, "开始止损"); + balanceAccount(orgAccount, InitAccount); + if (StopLossMode == 0) { + throw "止损退出"; + } else { + return true; + } + } + } + if (EnableAccountCheck && EnableStopWin) { + if (floatProfit > StopWin) { + Log("当前浮动盈亏", floatProfit, "开始止盈"); + balanceAccount(orgAccount, InitAccount); + if (StopWinMode == 0) { + throw "止盈退出"; + } else { + return true; + } + } + } + var distance = 0; + if (EnableAccountCheck && AutoMove) { + if (BuyFirst) { + distance = ticker.Last - FirstPrice; + } else { + distance = FirstPrice - ticker.Last; + } + var refish = false; + if (!isHold && isTimeout()) { + Log("空仓过久, 开始移动网格"); + refish = true; + } + if (distance > MaxDistance) { + Log("价格超出网格区间过多, 开始移动网格, 当前距离: ", _N(distance, Precision), "当前价格:", ticker.Last); + refish = true; + } + if (refish) { + balanceAccount(orgAccount, InitAccount); + return true; + } + } + + var holdDirection, holdAmount = "--", + holdPrice = "--"; + if (isHold) { + if (RestoreProfit && ProfitAsOrg) { + if (BuyFirst) { + money_diff += LastProfit; + } else { + money_diff -= LastProfit; + } + } + holdAmount = amount_diff; + holdPrice = (-money_diff) / amount_diff; + if (!BuyFirst) { + holdAmount = -amount_diff; + holdPrice = (money_diff) / -amount_diff; + } + holdAmount = _N(holdAmount, 4); + holdPrice = _N(holdPrice, Precision); + holdDirection = BuyFirst ? "多" : "空"; + } else { + holdDirection = "--"; + } + table = { + type: 'table', + title: '运行状态', + cols: ['动用资金', '持有仓位', '持仓大小', '持仓均价', '总浮动盈亏', '当前网格盈亏', '撒网次数', '网格偏移', '真实委托', '最新币价'], + rows: [ + [_N(actualNeedMondy, 4), holdDirection, holdAmount, holdPrice, _N(floatProfitAll, 4) + ' ( ' + _N(floatProfitAll * 100 / actualNeedMondy, 4) + ' % )', floatProfit, fishCount, (AutoMove && distance > 0) ? ((BuyFirst ? "向上" : "向下") + "偏离: " + _N(distance) + " 元") : "--", trader.RealLen(), ticker.Last] + ] + }; + + } + var orders = _C(trader.GetOrders); + if (table) { + if (!EnableDynamic) { + table.rows[0][8] = orders.length; + } + LogStatus('`' + JSON.stringify(table) + '`'); + } + for (var idx = 0; idx < canNum; idx++) { + var openPrice = _N((BuyFirst ? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)), Precision); + var coverPrice = _N((BuyFirst ? openPrice + PriceDiff : openPrice - PriceDiff), Precision); + var state = fishTable[idx]; + var fishId = uuidTable[idx]; + if (hasOrder(orders, fishId)) { + continue; + } + + if (fishId != -1 && IsSupportGetOrder) { + var order = trader.GetOrder(fishId); + if (!order) { + Log("获取订单信息失败, ID: ", fishId); + continue; + } + if (order.Status == ORDER_STATE_PENDING) { + //Log("订单状态为未完成, ID: ", fishId); + continue; + } + } + + if (state == STATE_WAIT_COVER) { + var coverId = CoverFunc(coverPrice, (BuyFirst ? amountS[idx] : amountB[idx]), (BuyFirst ? '完成买单:' : '完成卖单:'), openPrice, '量:', (BuyFirst ? amountB[idx] : amountS[idx])); + if (typeof(coverId) === 'number' || typeof(coverId) === 'string') { + fishTable[idx] = STATE_WAIT_CLOSE; + uuidTable[idx] = coverId; + } + } else if (state == STATE_WAIT_OPEN || state == STATE_WAIT_CLOSE) { + var openId = OpenFunc(openPrice, BuyFirst ? amountB[idx] : amountS[idx]); + if (typeof(openId) === 'number' || typeof(openId) === 'string') { + fishTable[idx] = STATE_WAIT_COVER; + uuidTable[idx] = openId; + if (state == STATE_WAIT_CLOSE) { + ProfitCount++; + var account = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + var initNet = _N(((InitAccount.Stocks + InitAccount.FrozenStocks) * ticker.Buy) + InitAccount.Balance + InitAccount.FrozenBalance, 8); + var nowNet = _N(((account.Stocks + account.FrozenStocks) * ticker.Buy) + account.Balance + account.FrozenBalance, 8); + var actualProfit = _N(((nowNet - initNet)) * 100 / initNet, 8); + if (AmountType == 0) { + var profit = _N((ProfitCount * amount * PriceDiff) + LastProfit, 8); + Log((BuyFirst ? '完成卖单:' : '完成买单:'), coverPrice, '量:', (BuyFirst ? amountS[idx] : amountB[idx]), '平仓收益', profit); + } else { + Log((BuyFirst ? '完成卖单:' : '完成买单:'), coverPrice, '量:', (BuyFirst ? amountS[idx] : amountB[idx])); + } + } + } + } + } + Sleep(CheckInterval); + } + return true; +} + +function main() { + if (ResetData) { + LogProfitReset(); + LogReset(); + } + exchange.SetPrecision(Precision, XPrecision) + if (typeof(AmountType) === 'undefined') { + AmountType = 0; + } + if (typeof(AmountDot) === 'undefined') { + AmountDot = 3; + } + if (typeof(EnableDynamic) === 'undefined') { + EnableDynamic = false; + } + if (typeof(AmountCoefficient) === 'undefined') { + AmountCoefficient = "*1"; + } + if (typeof(EnableAccountCheck) === 'undefined') { + EnableAccountCheck = true; + } + BuyFirst = (OpType == 0); + IsSupportGetOrder = exchange.GetName().indexOf('itstamp') == -1; + if (!IsSupportGetOrder) { + Log(exchange.GetName(), "不支持GetOrder, 可能影响策略稳定性."); + } + + SetErrorFilter("502:|503:|S_U_001|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|refused|EOF|When"); + + exchange.SetRate(1); + Log('已经禁用汇率转换, 当前货币为', exchange.GetBaseCurrency()); + + if (!RestoreProfit) { + LastProfit = 0; + } + + var orgAccount = _C(exchange.GetAccount); + var fishCount = 1; + while (true) { + if (!fishing(orgAccount, fishCount)) { + break; + } + fishCount++; + Log("第", fishCount, "次重新撒网..."); + FirstPriceAuto = true; + Sleep(1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/164251 + +> 更新时间 + +2019-08-29 23:06:51 diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\345\270\203\346\236\227\346\214\207\346\240\207\347\252\201\347\240\264\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" "b/\345\225\206\345\223\201\346\234\237\350\264\247\345\270\203\346\236\227\346\214\207\346\240\207\347\252\201\347\240\264\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" new file mode 100644 index 00000000..4756cec4 --- /dev/null +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\345\270\203\346\236\227\346\214\207\346\240\207\347\252\201\347\240\264\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" @@ -0,0 +1,97 @@ + +> 策略名称 + +商品期货布林指标突破策略(教学) + +> 策略作者 + +小小梦 + +> 策略描述 + +https://www.fmz.com/bbs-topic/4751 + + + +> 源码 (python) + +``` python +'''backtest +start: 2019-07-01 00:00:00 +end: 2019-11-26 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' +IDLE = 0 # 定义一个 标记量,表示空闲状态 +LONG = 1 # 定义一个 标记量,表示持多仓状态 +SHORT = 2 # 定义一个 标记量,表示持空仓状态 + +def CancelAll(): # 实现一个取消所有挂单的功能函数 + while True: # 循环执行 + orders = _C(exchange.GetOrders) # 读取当前所有挂单,orders 是一个数组 + if len(orders) == 0 : # 判断这个数组长度是不是为0,如果为0表示这个数组中没有挂单了 + break # 跳出while循环,没有挂单说明不需要取消了 + for order in orders : # 通过上面的if检测,执行到这里,说明orders数组的长度不为0,有挂单,遍历orders数组 + exchange.CancelOrder(order.Id) # 根据遍历时订单信息中的Id,取消该Id的订单 + Sleep(1000) # 控制一下取消频率,每次取消时暂停1秒 + +def main(): # 策略主函数,策略启动后从这里开始执行 + state = IDLE # 给策略定义一个状态变量,初始化为空闲状态 + direction = "" # 给策略定义一个下单方向变量,初始化为空字符串 + while True: # 执行策略逻辑循环 + if exchange.IO("status"): # 检测是否与期货公司服务器连接,登录成功 + LogStatus(_D(), "已经连接") + exchange.SetContractType("rb2001") # 设置要操作的合约,这里设置为rb2001,也可以做成参数,由策略参数上进行设置 + records = _C(exchange.GetRecords) # 获取K线数据,策略参数界面上设置K线周期1小时,这里获取的就是1小时K线数据 + + if len(records) < 21: # 使用BOLL指标的默认参数,所以K线数据的Bar数量要足够21才能计算出有效的BOLL指标 + continue # 不满足条件的情况下,continue跳过后面的代码,重复循环 + + boll = TA.BOLL(records) # 当符合 len(records) >= 21 时,执行到这里,使用TA.BOLL计算布林指标数据,boll是一个二维列表,boll[0]是上轨,boll[1]是中线,boll[2]是下轨 + ext.PlotRecords(records, "K") # 使用画线类库接口,画K线,画线类库代码可以在策略广场找到 + ext.PlotLine("up", boll[0][-2], records[-2].Time) # 使用画线类库接口,画上轨 + ext.PlotLine("mid", boll[1][-2], records[-2].Time) # 画中线 + ext.PlotLine("down", boll[2][-2], records[-2].Time) # 画下轨 + pos = _C(exchange.GetPosition) # 读取当前账户持仓信息 + + if len(pos) == 1 : # 如果当前账户有持仓,无持仓时,len(pos) 等于0 + if pos[0].Type == PD_LONG or pos[0].Type == PD_LONG_YD: # 根据持仓数据中的持仓方向,设置策略状态变量state + state = LONG # 设置为持有多仓状态 + elif pos[0].Type == PD_SHORT or pos[0].Type == PD_SHORT_YD: + state = SHORT # 设置为持有空仓状态 + elif len(pos) == 0 : # 无持仓时 + state = IDLE # 持仓状态设置为空闲 + else : + raise "error len(pos) > 1" # 如果检测到多个仓位,报错,单独跑这个策略,是不会有多个仓位的,如果出现说明异常 + + if records[-2].Close > boll[0][-2] and (state == IDLE or state == SHORT): # 如果当前是空闲状态或者持有空仓状态,K线BAR完成时确定价格突破上轨进行下一步判断 + # 平空仓(如果是持有空仓的状态),开多仓(如果是空闲状态),设置direction交易方向变量 + if state == IDLE: + direction = "buy" # 设置交易方向变量为开多仓 + else : + direction = "closesell" # 设置交易方向变量为平空仓 + exchange.SetDirection(direction) # 调用交易方向设置函数,设置方向 + exchange.Buy(records[-1].Close + 2, 1) # 根据当前价格,加两跳(对于rb这个品种来说)吃单,下单量为1手,exchange.Buy 下单函数,第一个参数为价格,第二个参数为下单量 + CancelAll() # 下单后尝试取消所有挂单(未成交) + elif records[-2].Close < boll[2][-2] and (state == IDLE or state == LONG): # 判断突破下轨 + # 平多仓(如果是持有多仓的状态),开空仓(如果是空闲状态),设置direction交易方向变量 + if state == IDLE: + direction = "sell" + else : + direction = "closebuy" + exchange.SetDirection(direction) + exchange.Sell(records[-1].Close - 2, 1) + CancelAll() + + else : + LogStatus(_D(), "未连接") # 如果未连接上期货公司服务器,在机器人状态栏上显示时间,和未连接信息 + Sleep(500) +``` + +> 策略出处 + +https://www.fmz.com/strategy/177584 + +> 更新时间 + +2019-12-07 10:40:43 diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\350\256\241\345\210\222\345\247\224\346\211\230\345\267\245\345\205\267\357\274\210\346\225\231\345\255\246\357\274\211.md" "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\256\241\345\210\222\345\247\224\346\211\230\345\267\245\345\205\267\357\274\210\346\225\231\345\255\246\357\274\211.md" new file mode 100644 index 00000000..ef191a04 --- /dev/null +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\350\256\241\345\210\222\345\247\224\346\211\230\345\267\245\345\205\267\357\274\210\346\225\231\345\255\246\357\274\211.md" @@ -0,0 +1,202 @@ + +> 策略名称 + +商品期货计划委托工具(教学) + +> 策略作者 + +小小梦 + +> 策略描述 + +策略相关文章: https://www.fmz.com/bbs-topic/4654 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|_EntrustSymbol|null|委托合约代码| +|_EntrustMode|0|委托类型: 开多|开空| +|_EntrustPrice|-1|委托价格| +|_EntrustAmount|-1|委托数量| +|_EntrustTriggerType|0|触发方式: 大于时触发|小于时触发| +|_EntrustStopLossPrice|-1|委托止损价格| +|_EntrustStopProfitPrice|-1|委托止盈价格| +|_EntrustStopLossBackhandPrice|-1|委托止损后反手价格| +|_IsRecovery|false|恢复任务数据| + + +> 源码 (javascript) + +``` javascript +// 全局变量 +var _TaskQueue = [] +var ENTRUST = 0 +var STOPLOSS = 1 +var STOPPROFIT = 2 +var BACKHAND = 3 +var dictTaskType = ["委托任务", "止损任务", "止盈任务", "反手任务"] + +var q = $.NewTaskQueue() + + +function closeTask (taskType) { + for (var i = 0; i < _TaskQueue.length; i++) { + if (taskType == _TaskQueue[i].taskType) { + _TaskQueue[i].taskFinished = true + Log("关闭任务:", dictTaskType[taskType]) + } + } +} + +// 任务处理对象 +function TaskQueueProcess () { + // 获取行情 + exchange.SetContractType(_EntrustSymbol) + var ticker = _C(exchange.GetTicker) + + for (var i = 0; i < _TaskQueue.length; i++) { + var task = _TaskQueue[i] + if (task.taskFinished == false && task.taskType == ENTRUST && task.taskTrigger * ticker.Last >= task.taskTrigger * task.taskPrice) { + q.pushTask(exchange, task.taskSymbol, task.taskDirection, task.taskAmount, function(tradeTask, ret) { + Log(tradeTask.desc, ret, "委托完成") + if (ret) { + // 回调,创建后续任务 + if (_EntrustStopLossPrice != -1) { // 创建止损任务 + var newTask = { + taskType : STOPLOSS, + taskSymbol : task.taskSymbol, + taskPrice : _EntrustStopLossPrice, + taskAmount : task.taskAmount, + taskDirection : task.taskDirection == "buy" ? "closebuy" : "closesell", + taskTrigger : -1, // 低于 价格触发 + taskFinished : false + } + _TaskQueue.push(newTask) + Log("创建止损任务", newTask, "#FF0000") + } + if (_EntrustStopProfitPrice != -1) { // 创建止盈任务 + var newTask = { + taskType : STOPPROFIT, + taskSymbol : task.taskSymbol, + taskPrice : _EntrustStopProfitPrice, + taskAmount : task.taskAmount, + taskDirection : task.taskDirection == "buy" ? "closebuy" : "closesell", + taskTrigger : 1, // 高于 价格触发 + taskFinished : false + } + _TaskQueue.push(newTask) + Log("创建止盈任务", newTask, "#FF0000") + } + } + }) + task.taskFinished = true + break + } else if (task.taskFinished == false && task.taskType == STOPLOSS && ticker.Last * task.taskTrigger >= task.taskPrice * task.taskTrigger) { + q.pushTask(exchange, task.taskSymbol, task.taskDirection, task.taskAmount, function(tradeTask, ret) { + Log(tradeTask.desc, ret, "止损完成") + // 关闭止盈任务 + closeTask(STOPPROFIT) + if (ret) { + // 回调,创建后续任务 + if (_EntrustStopLossBackhandPrice != -1) { + var newTask = { + taskType : BACKHAND, + taskSymbol : task.taskSymbol, + taskPrice : _EntrustStopLossBackhandPrice, + taskAmount : task.taskAmount, + taskDirection : task.taskDirection == "closebuy" ? "sell" : "buy", + taskTrigger : task.taskDirection == "closebuy" ? -1 : 1, // -1 小于时触发, 1大于时触发 + taskFinished : false + } + _TaskQueue.push(newTask) + Log("创建反手任务", newTask, "#FF0000") + } + } + }) + task.taskFinished = true + break + } else if (task.taskFinished == false && task.taskType == STOPPROFIT && ticker.Last * task.taskTrigger >= task.taskPrice * task.taskTrigger) { + q.pushTask(exchange, task.taskSymbol, task.taskDirection, task.taskAmount, function(tradeTask, ret) { + Log(tradeTask.desc, ret, "止盈完成") + // 关闭止损任务 + closeTask(STOPLOSS) + }) + task.taskFinished = true + break + } else if (task.taskFinished == false && task.taskType == BACKHAND && ticker.Last * task.taskTrigger >= task.taskPrice * task.taskTrigger) { + q.pushTask(exchange, task.taskSymbol, task.taskDirection, task.taskAmount, function(tradeTask, ret) { + Log(tradeTask.desc, ret, "反手完成") + }) + task.taskFinished = true + break + } + } + q.poll() +} + +function main() { + if (_IsRecovery) { + recoveryData = _G("_TaskQueue") + if (!recoveryData) { + _TaskQueue = recoveryData + } else { + Log("没有可用于恢复的数据") + } + } + + // 根据参数生成任务 + if (_EntrustSymbol == "null" || _EntrustPrice <= 0 || _EntrustAmount <= 0) { + throw "没有设置委托合约或者委托价格无效或者委托数量无效" + } else { + var task = { + taskType : ENTRUST, + taskSymbol : _EntrustSymbol, + taskPrice : _EntrustPrice, + taskAmount : _EntrustAmount, + taskDirection : _EntrustMode == 0 ? "buy" : "sell", + taskTrigger : _EntrustTriggerType == 0 ? 1 : -1, + taskFinished : false + } + + Log("请注意,创建委托任务", task, "#FF0000") + _TaskQueue.push(task) + } + + + while (true) { + if (exchange.IO("status")) { + TaskQueueProcess() + // 状态栏显示 + LogStatus(_D(), "已连接") + } else { + LogStatus(_D(), "未连接") + } + Sleep(500) + } +} + +// 扫尾取消所有挂单 +function onexit(){ + Log("策略停止,保存数据:", _TaskQueue) + _G("_TaskQueue", _TaskQueue) +} + +function onerror(){ + Log("策略异常停止,保存数据:", _TaskQueue) + _G("_TaskQueue", _TaskQueue) +} + + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/175150 + +> 更新时间 + +2019-11-19 16:22:41 diff --git "a/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.md" "b/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.md" index a9ad7d32..d96161fb 100644 --- "a/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.md" +++ "b/\345\233\236\346\265\213\344\277\235\345\255\230K\347\272\277\345\210\260\346\234\254\345\234\260CSV.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 diff --git "a/\345\237\272\344\272\216\345\233\236\345\275\222\345\271\205\345\272\246\347\232\204\345\217\215\350\275\254\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/\345\237\272\344\272\216\345\233\236\345\275\222\345\271\205\345\272\246\347\232\204\345\217\215\350\275\254\344\272\244\346\230\223\347\255\226\347\225\245.md" deleted file mode 100644 index 05234505..00000000 --- "a/\345\237\272\344\272\216\345\233\236\345\275\222\345\271\205\345\272\246\347\232\204\345\217\215\350\275\254\344\272\244\346\230\223\347\255\226\347\225\245.md" +++ /dev/null @@ -1,101 +0,0 @@ - -> 策略名称 - -基于回归幅度的反转交易策略 - -> 策略作者 - -Hukybo - - - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|cycleLength|50|周期长度| -|backRatio|true|回撤比率| -|contractType|rb000/rb888,ru000/ru888|合约类型| -|unit|true|单位| - - -> 源码 (javascript) - -``` javascript -/*backtest -start: 2010-01-11 09:00:00 -end: 2018-01-03 15:00:00 -period: 1h -exchanges: [{"eid":"Futures_CTP","currency":"FUTURES","minfee":10,"fee":[0,0]}] -*/ - -function main() { - var contractType_Dic = {}; - var contractType_Array1 = contractType.split(","); - var contractType_Array2 = []; - for (var i = 0; i < contractType_Array1.length; i++) { - contractType_Array2.push(contractType_Array1[i].split('/')[1]); - } - contractType_Array2.toString(); - for (var key in contractType_Array2) { - contractType_Dic[contractType_Array2[key]] = { - falsePosition: 0 - } - } - $.CTA(contractType, function(st) { - var bars = st.records; //获取K线数组 - var j = bars[bars.length - 2].Close; - //计算N日内的最高价 - var high = TA.Highest(bars, cycleLength, 'High'); - - //计算N日内的最低价 - var low = TA.Lowest(bars, cycleLength, 'Low'); - - //计算N日内的最高价的回撤1%的值 - var highBack = high * (1 - backRatio / 100); - - //计算N日内的最低价的回撤1%的值 - var lowBack = low * (1 + backRatio / 100); - - if (!bars || bars.length < cycleLength + 1) { - return; - } - - - //多头平仓 - if (contractType_Dic[st.symbol].falsePosition > 0 && j < (lowBack + highBack) / 2) { - contractType_Dic[st.symbol].falsePosition = 0; - return -unit; - } - - //空头平仓 - if (contractType_Dic[st.symbol].falsePosition < 0 && j > (lowBack + highBack) / 2) { - contractType_Dic[st.symbol].falsePosition = 0; - return unit; - } - - //多头开仓 - if (contractType_Dic[st.symbol].falsePosition == 0 && j > lowBack && j > highBack) { - contractType_Dic[st.symbol].falsePosition = 1; - return unit; - } - - //空头开仓 - if (contractType_Dic[st.symbol].falsePosition == 0 && j < lowBack && j < highBack) { - contractType_Dic[st.symbol].falsePosition = -1; - return -unit; - } - - }); -} -``` - -> 策略出处 - -https://www.fmz.com/strategy/69937 - -> 更新时间 - -2018-05-02 20:56:31 diff --git "a/\345\237\272\344\272\216\346\234\237\350\264\247\345\237\272\346\234\254\351\235\242\345\210\206\346\236\220\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/\345\237\272\344\272\216\346\234\237\350\264\247\345\237\272\346\234\254\351\235\242\345\210\206\346\236\220\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" index 5f5aa288..9914581c 100644 --- "a/\345\237\272\344\272\216\346\234\237\350\264\247\345\237\272\346\234\254\351\235\242\345\210\206\346\236\220\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" +++ "b/\345\237\272\344\272\216\346\234\237\350\264\247\345\237\272\346\234\254\351\235\242\345\210\206\346\236\220\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -253,4 +253,4 @@ https://www.fmz.com/strategy/161412 > 更新时间 -2019-08-17 11:40:22 +2019-08-31 16:32:29 diff --git "a/\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211|Multiple charts example.md" "b/\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211|Multiple charts example.md" index 355a0604..c8e86fbf 100644 --- "a/\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211|Multiple charts example.md" +++ "b/\345\244\232\345\233\276\350\241\250\344\276\213\345\255\220\357\274\210\346\225\260\346\215\256\345\217\257\344\270\213\350\275\275\344\270\272csv\347\255\211\350\241\250\346\240\274\357\274\211|Multiple charts example.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/\345\244\232\347\272\247\347\231\276\345\210\206\346\257\224\346\255\242\347\233\210\347\255\226\347\225\245.md" "b/\345\244\232\347\272\247\347\231\276\345\210\206\346\257\224\346\255\242\347\233\210\347\255\226\347\225\245.md" new file mode 100644 index 00000000..0ce92016 --- /dev/null +++ "b/\345\244\232\347\272\247\347\231\276\345\210\206\346\257\224\346\255\242\347\233\210\347\255\226\347\225\245.md" @@ -0,0 +1,91 @@ + +> 策略名称 + +多级百分比止盈策略 + +> 策略作者 + +Hukybo + +> 策略描述 + +斯坦利·克罗在《克罗谈投资策略》书中提到过他的止盈分为三部分:当达到止盈目标的时候主动平掉三分之一,突破长期阻力位和支撑位的时候再主动平掉三分之一,剩下的三分之一跟随趋势直到止损。本篇文章分享的策略也正是根据这个原理,利用均线作为趋势方向的判断,以收盘价、最高价与最低价的相互关系作为开平仓信号,在价格走势没有明显转向的前提下,提前按照百分比主动分批止盈。 +[点击阅读更多内容](https://www.fmz.com/digest-topic/4301) + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2015-02-22 00:00:00 +end: 2019-09-18 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["SlideTick",2,126961],["ContractType","rb000",126961]] +*) + +// 定义参数 +LENGTH := 100; // 均线参数 +STOP_LOSS := 3; // 止损幅度 + +// 定义止盈参数 +STARTPER1 := 5; // 1级跟踪止盈,盈利5%启动 +STOPPER1 := 100; // 1级跟踪止盈,盈利回撤100%触发 +STARTPER2 := 10; // 2级跟踪止盈,盈利10%启动 +STOPPER2 := 50; // 2级跟踪止盈,盈利回撤50%触发 +STARTPER3 := 20; // 3级跟踪止盈,盈利20%启动 +STOPPER3 := 20; // 3级跟踪止盈,盈利回撤20%触发 + +// 定义上下区间 +NN := BARSLAST(DATE <> REF(DATE, 1)) + 1; // 当天开盘到当前周期数 +TODAY_OPEN := VALUEWHEN(NN = 1, O); // 当天开盘价 +TODAY_HIGH := HHV(H, NN); // 当天最高价 +TODAY_LOW := LLV(L, NN); // 当天最低价 +YESTERDAY_HIGH := REF(TODAY_HIGH, NN); // 昨天最高价 +YESTERDAY_LOW := REF(TODAY_LOW, NN); // 昨天最低价 +BAND := YESTERDAY_HIGH - YESTERDAY_LOW; // 昨天振幅 +UPPERLINE : TODAY_OPEN + BAND; // 上线 +LOWERLINE : TODAY_OPEN - BAND; // 下线 +MYMA:MA(CLOSE, LENGTH); // 均线 + +// 开仓 +C > UPPERLINE AND UPPERLINE > MYMA, BK; // 开多 +C < LOWERLINE AND LOWERLINE < MYMA, SK; // 开空 + +// 平仓 +C < LOWERLINE OR C < MYMA, SP; // 平多 +C > UPPERLINE OR C > MYMA, BP; // 平空 + +// 多单止盈 +BKHIGH >= BKPRICE * (1 + 0.01 * STARTPER1) AND LOW <= BKHIGH - (BKHIGH - BKPRICE) * 0.01 * STOPPER1, SP; // 一级 +BKHIGH >= BKPRICE * (1 + 0.01 * STARTPER2) AND LOW <= BKHIGH - (BKHIGH - BKPRICE) * 0.01 * STOPPER2, SP; // 二级 +BKHIGH >= BKPRICE * (1 + 0.01 * STARTPER3) AND LOW <= BKHIGH - (BKHIGH - BKPRICE) * 0.01 * STOPPER3, SP; // 三级 + +// 空单止盈 +SKLOW <= SKPRICE * (1 - 0.01 * STARTPER1) AND HIGH >= SKLOW + (SKPRICE - SKLOW) * 0.01 * STOPPER1, BP; // 一级 +SKLOW <= SKPRICE * (1 - 0.01 * STARTPER2) AND HIGH >= SKLOW + (SKPRICE - SKLOW) * 0.01 * STOPPER2, BP; // 二级 +SKLOW <= SKPRICE * (1 - 0.01 * STARTPER3) AND HIGH >= SKLOW + (SKPRICE - SKLOW) * 0.01 * STOPPER3, BP; // 三级 + + +//止损 +C <= BKPRICE * (1 - STOP_LOSS * 0.01), SP; // 多头 +C >= SKPRICE * (1 + STOP_LOSS * 0.01), BP; // 空头 + +// 设置下单委托方式 +SETSIGPRICETYPE(BK,NEW_ORDER); +SETSIGPRICETYPE(SK,NEW_ORDER); +SETSIGPRICETYPE(BP,NEW_ORDER); +SETSIGPRICETYPE(SP,NEW_ORDER); + +// 设置信号过滤方式 +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/166753 + +> 更新时间 + +2019-09-19 15:08:53 diff --git "a/\345\244\232\347\272\277\347\250\213\346\211\271\351\207\217\344\273\273\345\212\241.md" "b/\345\244\232\347\272\277\347\250\213\346\211\271\351\207\217\344\273\273\345\212\241.md" index 0bcdf72f..0cae834d 100644 --- "a/\345\244\232\347\272\277\347\250\213\346\211\271\351\207\217\344\273\273\345\212\241.md" +++ "b/\345\244\232\347\272\277\347\250\213\346\211\271\351\207\217\344\273\273\345\212\241.md" @@ -5,7 +5,7 @@ > 策略作者 -jason47 +一拳男孩 > 策略描述 @@ -98,7 +98,7 @@ $.wait = function(cmdList, maxConcurrent, retry) { return cmd.result }) if (currentPage + 1 < total) { - Sleep(500) + Sleep(1000) } return beforeResultList.concat(newResultList) }, []) @@ -111,4 +111,4 @@ https://www.fmz.com/strategy/159978 > 更新时间 -2019-08-24 04:51:11 +2019-08-24 16:02:33 diff --git "a/\345\261\261\345\257\250\345\270\201\346\214\207\346\225\260\357\274\2102018.02.22\345\237\272\347\202\2711000\357\274\211.md" "b/\345\261\261\345\257\250\345\270\201\346\214\207\346\225\260\357\274\2102018.02.22\345\237\272\347\202\2711000\357\274\211.md" index 79d1c0e6..396f6219 100644 --- "a/\345\261\261\345\257\250\345\270\201\346\214\207\346\225\260\357\274\2102018.02.22\345\237\272\347\202\2711000\357\274\211.md" +++ "b/\345\261\261\345\257\250\345\270\201\346\214\207\346\225\260\357\274\2102018.02.22\345\237\272\347\202\2711000\357\274\211.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/\345\270\201\345\256\211\345\217\226\346\266\210\346\211\200\346\234\211\344\272\244\346\230\223\345\257\271\346\234\252\345\256\214\346\210\220\350\256\242\345\215\225\357\274\210IO\346\211\251\345\261\225\347\244\272\350\214\203\357\274\211|Cancel ALL Binance Orders.md" "b/\345\270\201\345\256\211\345\217\226\346\266\210\346\211\200\346\234\211\344\272\244\346\230\223\345\257\271\346\234\252\345\256\214\346\210\220\350\256\242\345\215\225\357\274\210IO\346\211\251\345\261\225\347\244\272\350\214\203\357\274\211|Cancel ALL Binance Orders.md" index 1f17723c..ae074b12 100644 --- "a/\345\270\201\345\256\211\345\217\226\346\266\210\346\211\200\346\234\211\344\272\244\346\230\223\345\257\271\346\234\252\345\256\214\346\210\220\350\256\242\345\215\225\357\274\210IO\346\211\251\345\261\225\347\244\272\350\214\203\357\274\211|Cancel ALL Binance Orders.md" +++ "b/\345\270\201\345\256\211\345\217\226\346\266\210\346\211\200\346\234\211\344\272\244\346\230\223\345\257\271\346\234\252\345\256\214\346\210\220\350\256\242\345\215\225\357\274\210IO\346\211\251\345\261\225\347\244\272\350\214\203\357\274\211|Cancel ALL Binance Orders.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/\346\201\222\346\270\251\345\231\250 Thermostat \346\213\251\346\227\266\347\255\226\347\225\245\347\240\224\347\251\266.md" "b/\346\201\222\346\270\251\345\231\250 Thermostat \346\213\251\346\227\266\347\255\226\347\225\245\347\240\224\347\251\266.md" index 30805ea0..7de72443 100644 --- "a/\346\201\222\346\270\251\345\231\250 Thermostat \346\213\251\346\227\266\347\255\226\347\225\245\347\240\224\347\251\266.md" +++ "b/\346\201\222\346\270\251\345\231\250 Thermostat \346\213\251\346\227\266\347\255\226\347\225\245\347\240\224\347\251\266.md" @@ -44,8 +44,8 @@ AVG3LO:=MA(L,3); // 计算震荡市的进场价格 LEP:=IFELSE(C>KOD,O+ATR10*0.5,O+ATR10*0.75); SEP:=IFELSE(C>KOD,O-ATR10*0.75,O-ATR10*0.5); -LEP1:=MAX(LEP,AVG3LO); -SEP1:=MIN(SEP,AVG3HI); +LEP1:=MAX(LEP,AVG3HI); +SEP1:=MIN(SEP,AVG3LO); // 计算趋势市的进场价格 UPBAND:=MA(C,50)+STD(C,50)*2; @@ -74,4 +74,4 @@ https://www.fmz.com/strategy/127033 > 更新时间 -2019-03-26 16:17:52 +2019-12-21 12:09:02 diff --git "a/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" "b/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" new file mode 100644 index 00000000..c12a7abd --- /dev/null +++ "b/\346\212\233\347\211\251\347\272\277\350\275\254\345\220\221SAR\344\270\216\344\273\267\346\240\274\351\253\230\344\275\216\347\202\271\347\255\226\347\225\245.md" @@ -0,0 +1,53 @@ + +> 策略名称 + +抛物线转向SAR与价格高低点策略 + +> 策略作者 + +Hukybo + +> 策略描述 + +抛物线转向是一个很奇特的技术分析指标,由美国威尔斯·威尔德(Welles Wilder)发明,英文名字叫“Stop and Reverse”,简称“SAR”。这是一种使用非常简单,同时也非常流行的中低频趋势性技术分析工具。本篇文章的策略根据这个技术指标,并结合价格高低点的相对位置关系来开发策略。 +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4340) + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2015-02-22 00:00:00 +end: 2019-09-27 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["ContractType","rb000",126961]] +*) + +N:=30; // 最高/低价参数 +SLOSS:=1; // 止盈止损系数 +FUND:=100000; // 初始资金 + +LOTS:=MAX(1,INTPART(FUND/(O*UNIT*0.1))); // 计算下单量 +SARLINE:=SAR(4,2,20); // 计算抛物线转向指标 +B1:=SARLINE>0; // 判断是否上涨趋势 +S1:=SARLINE<0; // 判断是否下跌趋势 +B2:=HIGH>=HHV(CLOSE,N); // 判断最高价是否大于前期高点 +S2:=LOW<=LLV(CLOSE,N); // 判断最低价是否小于前期低点 + +BARPOS>N AND B1 AND B2,BK(LOTS); // 开多单 +BARPOS>N AND S1 AND S2,SK(LOTS); // 开空单 +S1 AND S2 AND BKHIGH>BKPRICE*(1+0.01*SLOSS),SP(BKVOL); // 多单止盈 +B1 AND B2 AND SKLOWSKPRICE*(1+SLOSS*0.01),BP(SKVOL); // 空单止损 +``` + +> 策略出处 + +https://www.fmz.com/strategy/168073 + +> 更新时间 + +2019-09-28 17:34:44 diff --git "a/\346\214\207\346\225\260\345\271\263\350\241\241\347\255\226\347\225\245|Index Balance Bot.md" "b/\346\214\207\346\225\260\345\271\263\350\241\241\347\255\226\347\225\245|Index Balance Bot.md" index 3062a155..17af6d51 100644 --- "a/\346\214\207\346\225\260\345\271\263\350\241\241\347\255\226\347\225\245|Index Balance Bot.md" +++ "b/\346\214\207\346\225\260\345\271\263\350\241\241\347\255\226\347\225\245|Index Balance Bot.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/\346\225\231\345\255\246\347\255\226\347\225\245TCI\347\255\226\347\225\245\357\274\210\351\272\246\350\257\255\350\250\200\347\247\273\346\244\215\357\274\211.md" "b/\346\225\231\345\255\246\347\255\226\347\225\245TCI\347\255\226\347\225\245\357\274\210\351\272\246\350\257\255\350\250\200\347\247\273\346\244\215\357\274\211.md" new file mode 100644 index 00000000..2634bf79 --- /dev/null +++ "b/\346\225\231\345\255\246\347\255\226\347\225\245TCI\347\255\226\347\225\245\357\274\210\351\272\246\350\257\255\350\250\200\347\247\273\346\244\215\357\274\211.md" @@ -0,0 +1,381 @@ + +> 策略名称 + +教学策略TCI策略(麦语言移植) + +> 策略作者 + +小小梦 + + + + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2019-05-01 00:00:00 +end: 2019-11-12 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}] +*/ + +/* 原版麦语言策略 +N1:=10; +N2:=21; +AP:=(HIGH+LOW+CLOSE)/3; +ESA:=EMA(AP,N1); +D:=EMA(ABS(AP-ESA),N1); +CI:=(AP-ESA)/(0.015*D); +TCI:=EMA(CI,N2); +WT1:TCI; +WT2:SMA(WT1,4,1); +AA:=CROSS(WT1,WT2); +BB:=CROSSDOWN(WT1,WT2); +REF(AA,1),BPK; +REF(BB,1),SPK; +*/ + +// 全局变量 +var IDLE = 0 +var LONG = 1 +var SHORT = 2 +var OPENLONG = 3 +var OPENSHORT = 4 +var COVERLONG = 5 +var COVERSHORT = 6 + +var BREAK = 9 +var SHOCK = 10 + +var _State = IDLE +var Amount = 1 // 记录持仓数量 +var TradeInterval = 500 // 轮询间隔 +var PriceTick = 1 // 价格一跳 +var Point = 5 // 滑价点数 +var Symbol = "quarter" + +// 临时参数 +var N1 = 10 +var N2 = 21 + +function CalcAP (r) { // AP:=(HIGH+LOW+CLOSE)/3; + var arrAP = [] + + for (var i = 0; i < r.length; i++) { + v = (r[i].High + r[i].Low + r[i].Close) / 3 + arrAP.push(v) + } + + return arrAP +} + +function CalcESA (ap, n1) { // ESA:=EMA(AP,N1); + if (ap.length <= n1) { + return false + } + + return TA.EMA(ap, n1) +} + +function CalcD (ap, esa, n1) { // D:=EMA(ABS(AP-ESA),N1); + var arrABS_APminusESA = [] + if (ap.length != esa.length) { + throw "ap.length != esa.length" + } + + for (var i = 0; i < ap.length; i++) { + if (ap[i] && esa[i] && !isNaN(ap[i]) && !isNaN(esa[i])) { + v = Math.abs(ap[i] - esa[i]) + arrABS_APminusESA.push(v) + } else { + arrABS_APminusESA.push(NaN) + } + } + + if (arrABS_APminusESA.length <= n1) { + return false + } + + return TA.EMA(arrABS_APminusESA, n1) +} + +function CalcCI (ap, esa, d) { // CI:=(AP-ESA)/(0.015*D); + var arrCI = [] + if (ap.length != esa.length || ap.length != d.length) { + throw "ap.length != esa.length || ap.length != d.length" + } + for (var i = 0; i < ap.length; i++) { + if (ap[i] && esa[i] && d[i] && !isNaN(ap[i]) && !isNaN(esa[i]) && !isNaN(d[i])) { + v = (ap[i] - esa[i]) / (0.015 * d[i]) + arrCI.push(v) + } else { + arrCI.push(NaN) + } + } + + if (arrCI.length == 0) { + return false + } + + return arrCI +} + +function CalcTCI (ci, n2) { // TCI:=EMA(CI,N2); + if (ci.length <= n2) { + return false + } + + return TA.EMA(ci, n2) +} + +function SMA (arr, n, m) { + var sma = [] + var currSMA = null + for (var i = 0; i < arr.length; i++) { + if (arr[i] && !isNaN(arr[i])) { + if (!currSMA) { + currSMA = arr[i] + sma.push(currSMA) + continue + } + + // [M*C2+(N-M)*S1]/N + currSMA = (m * arr[i] + (n - m) * currSMA) / n + sma.push(currSMA) + } else { + sma.push(NaN) + } + } + + return sma +} + +function CalcWT2 (wt1) { // WT2:SMA(WT1,4,1); + if (wt1.length <= 4) { + return false + } + + return SMA(wt1, 4, 1) +} + +var isOK = true +var preTime = 0 +function OnTick(){ + // 驱动策略的行情处理部分 + var records = _C(exchange.GetRecords) + if (records[records.length - 1].Time == preTime) { + if (isOK) { + Sleep(500) + return + } + } else { + preTime = records[records.length - 1].Time + } + + // 计算指标 + // AP + var ap = CalcAP(records) + + // ESA + var esa = CalcESA(ap, N1) + if (!esa) { + return + } + + // D + var d = CalcD(ap, esa, N1) + if (!d) { + return + } + + // CI + var ci = CalcCI(ap, esa, d) + if (!ci) { + return + } + + // TCI + var tci = CalcTCI(ci, N2) + if (!tci) { + return + } + + // WT1 + var wt1 = tci + + // WT2 + var wt2 = CalcWT2(wt1) + if (!wt2) { + return + } + + // 交易信号触发处理部分 + /* + AA:=CROSS(WT1,WT2); + BB:=CROSSDOWN(WT1,WT2); + REF(AA,1),BPK; + REF(BB,1),SPK; + */ + if (wt1.length < 3 || wt2.length < 3) { + return + } + + $.PlotLine("wt1", wt1[wt1.length - 2], records[records.length - 2].Time) + $.PlotLine("wt2", wt2[wt2.length - 2], records[records.length - 2].Time) + + if ((_State == IDLE || _State == SHORT) && wt1[wt1.length - 4] < wt2[wt2.length - 4] && wt1[wt1.length - 3] > wt2[wt2.length - 3]) { + if (_State == IDLE) { + _State = OPENLONG + Log("OPENLONG") // 测试 + } + if (_State == SHORT) { + _State = COVERSHORT + Log("COVERSHORT") // 测试 + } + isOK = false + } + + if ((_State == IDLE || _State == LONG) && wt1[wt1.length - 4] > wt2[wt2.length - 4] && wt1[wt1.length - 3] < wt2[wt2.length - 3]) { + if (_State == IDLE) { + _State = OPENSHORT + Log("OPENSHORT") // 测试 + } + if (_State == LONG) { + _State = COVERLONG + Log("COVERLONG") // 测试 + } + isOK = false + } + + // 执行交易逻辑 + var pos = null + var price = null + var currBar = records[records.length - 1] + if(_State == OPENLONG){ + pos = GetPosition(PD_LONG) + // 判断是不是 满足状态,如果满足 修改状态 + if(pos[1] >= Amount){ + _State = LONG + Amount = pos[1] // 更新实际量 + isOK = true + return + } + price = currBar.Close - (currBar.Close % PriceTick) + PriceTick * Point + Trade(OPENLONG, price, Amount - pos[1], pos, PriceTick) // (Type, Price, Amount, CurrPos, PriceTick) + } + + if(_State == OPENSHORT){ + pos = GetPosition(PD_SHORT) + if(pos[1] >= Amount){ + _State = SHORT + Amount = pos[1] // 更新实际量 + isOK = true + return + } + price = currBar.Close - (currBar.Close % PriceTick) - PriceTick * Point + Trade(OPENSHORT, price, Amount - pos[1], pos, PriceTick) + } + + if(_State == COVERLONG){ + pos = GetPosition(PD_LONG) + if(pos[1] == 0){ + _State = IDLE + return + } + price = currBar.Close - (currBar.Close % PriceTick) - PriceTick * Point + Trade(COVERLONG, price, pos[1], pos, PriceTick) + } + + if(_State == COVERSHORT){ + pos = GetPosition(PD_SHORT) + if(pos[1] == 0){ + _State = IDLE + return + } + price = currBar.Close - (currBar.Close % PriceTick) + PriceTick * Point + Trade(COVERSHORT, price, pos[1], pos, PriceTick) + } +} + +// 交易逻辑部分 +function GetPosition(posType) { + var positions = _C(exchange.GetPosition) + var count = 0 + for(var j = 0; j < positions.length; j++){ + if(positions[j].ContractType == Symbol){ + count++ + } + } + + if(count > 1){ + throw "positions error:" + JSON.stringify(positions) + } + + for (var i = 0; i < positions.length; i++) { + if (positions[i].ContractType == Symbol && positions[i].Type === posType) { + return [positions[i].Price, positions[i].Amount]; + } + } + Sleep(TradeInterval); + return [0, 0]; +} + +function CancelPendingOrders() { + while (true) { + var orders = _C(exchange.GetOrders) + for (var i = 0; i < orders.length; i++) { + exchange.CancelOrder(orders[i].Id); + Sleep(TradeInterval); + } + if (orders.length === 0) { + break; + } + } +} + +function Trade(Type, Price, Amount, CurrPos, OnePriceTick){ // 处理交易 + if(Type == OPENLONG || Type == OPENSHORT){ // 处理开仓 + exchange.SetDirection(Type == OPENLONG ? "buy" : "sell") + var pfnOpen = Type == OPENLONG ? exchange.Buy : exchange.Sell + var idOpen = pfnOpen(Price, Amount, CurrPos, OnePriceTick, Type) + Sleep(TradeInterval) + if(idOpen) { + exchange.CancelOrder(idOpen) + } else { + CancelPendingOrders() + } + } else if(Type == COVERLONG || Type == COVERSHORT){ // 处理平仓 + exchange.SetDirection(Type == COVERLONG ? "closebuy" : "closesell") + var pfnCover = Type == COVERLONG ? exchange.Sell : exchange.Buy + var idCover = pfnCover(Price, Amount, CurrPos, OnePriceTick, Type) + Sleep(TradeInterval) + if(idCover){ + exchange.CancelOrder(idCover) + } else { + CancelPendingOrders() + } + } else { + throw "Type error:" + Type + } +} + +function main() { + // 设置合约 + exchange.SetContractType(Symbol) + + while(1){ + OnTick() + Sleep(1000) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/174457 + +> 更新时间 + +2019-11-13 18:13:06 diff --git "a/\346\225\260\345\255\227\350\264\247\345\270\201\346\234\237\350\264\247\347\216\260\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247.md" "b/\346\225\260\345\255\227\350\264\247\345\270\201\346\234\237\350\264\247\347\216\260\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247.md" new file mode 100644 index 00000000..899caba1 --- /dev/null +++ "b/\346\225\260\345\255\227\350\264\247\345\270\201\346\234\237\350\264\247\347\216\260\350\264\247\345\267\256\344\273\267\347\233\221\346\216\247.md" @@ -0,0 +1,79 @@ + +> 策略名称 + +数字货币期货现货差价监控 + +> 策略作者 + +小小梦 + +> 策略描述 + +## 数字货币期货现货差价监控 + +本策略为一个期货交易所和现货交易所之间差价监控的策略。 +画图以10秒钟一次统计差价,画在图表上。 +第一个添加的交易所为期货交易所。 +第二个添加的交易所为现货交易所。 + +测试可以使用 BTC_USDT 交易对,进行测试。 +默认期货交易所用火币DM合约的 季度合约,代码为: ```quarter``` 。 +现货测试交易所用BIT-Z,交易对设置BTC_USDT。 + +测试演示、教学使用。 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|ContractType|quarter|期货合约| + + + + +|按钮|默认值|描述| +|----|----|----| +|CMD_1|__button__|命令1| +|CMD_2|命令2的字符串|命令2| + + +> 源码 (javascript) + +``` javascript +function main () { + LogReset(1) + + exchanges[0].SetContractType(ContractType) + + var lastPlotTime = 0 + while(true) { + var ticker_futures = exchanges[0].GetTicker() + var ticker_spot = exchanges[1].GetTicker() + var diff = ticker_futures.Last - ticker_spot.Last + + LogStatus(_D(), "期货-现货,差价:", diff) + var cmd = GetCommand() + if (cmd) { + Log("接收到命令:", cmd, "可以对该命令内容解析,触发自定义的函数执行!#FF0000") + } + + var ts = new Date().getTime() + if (ts - lastPlotTime > 1000 * 10) { + $.PlotLine("差价(期货-现货)", diff) + lastPlotTime = ts + } + + Sleep(500) + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/164680 + +> 更新时间 + +2019-09-02 14:57:48 diff --git "a/\346\232\264\351\233\252\347\275\221\346\240\274-7*24\345\260\217\346\227\266\344\272\244\346\230\223\346\234\272\345\231\250\344\272\272.md" "b/\346\232\264\351\233\252\347\275\221\346\240\274-7*24\345\260\217\346\227\266\344\272\244\346\230\223\346\234\272\345\231\250\344\272\272.md" new file mode 100644 index 00000000..fc6a20cb --- /dev/null +++ "b/\346\232\264\351\233\252\347\275\221\346\240\274-7*24\345\260\217\346\227\266\344\272\244\346\230\223\346\234\272\345\231\250\344\272\272.md" @@ -0,0 +1,190 @@ + +> 策略名称 + +暴雪网格-7*24小时交易机器人 + +> 策略作者 + +红色的雪 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|base_price|3|基础价格-中线价格| +|sale_buy_diff|0.03|买卖差价,卖出的价格- 买入的价格| +|two_distance|0.01|递增、递减的时候,每个格子的距离| +|trade_amount|2|每次交易的数量| +|sale_price_max|5|卖出的上限价格| +|buy_price_min|true|买入的上限价格| + + +> 源码 (python) + +``` python +#!python2 +# -*- coding:utf-8 -*- +''' +主要是使用发明者量化API进行网格买卖,当前只支持单品网格买卖 +''' +from time import sleep +import datetime,copy + +sale_price_list = [] #卖出的价格列表 +buy_price_list = [] #买入的价格列表 + +class fmz_market(): + def get_data_depth(self): + data_depth = exchange.GetDepth() + return data_depth + + + + #检查当前是否可以进行买卖操作 + def make_trade_check(self,symbol): + trade_infor = {'price':0,'trade_type':''} + #进行买卖列表判断,先更新交易记录列表 + trade_price_list = self.get_trade_price_list(symbol) + sale_price_list = trade_price_list[0] + buy_price_list = trade_price_list[1] + #获取深度数据 + data_depth = self.get_data_depth() + #买单列表: + data_depth_bids = data_depth.Bids[0] + #卖单列表: + data_depth_asks = data_depth.Asks[0] + #如果买入记录不为空 + sale_buy_diff_now = two_distance*len(sale_price_list) if len(sale_price_list) >0 else sale_buy_diff + sale_buy_diff_sale = two_distance if len(sale_price_list) > 0 else sale_buy_diff + # sale_price_last = float(sale_price_list[len(sale_price_list)-1]) if len(sale_price_list) >0 else base_price + # buy_price_last = float(buy_price_list[len(buy_price_list)-1]) if len(buy_price_list) >0 else base_price + sale_price_last = float(sale_price_list[0]) if len(sale_price_list) > 0 and float(sale_price_list[0]) > base_price else base_price + buy_price_last = float(buy_price_list[0]) if len(buy_price_list) > 0 and float(buy_price_list[0]) < base_price else base_price + #判断当前价格是否满足 卖出的价格请求 + if float(data_depth_bids.Price) - sale_price_last > sale_buy_diff_sale and float(data_depth_bids.Amount) > trade_amount * 1.5: + Log("当前卖价:",str(data_depth_bids.Price),"订单中最高卖价:",str(sale_price_last),"生成卖单") + trade_infor['price'] = float(data_depth_bids.Price) + trade_infor['trade_type'] = 'sale' + #判断当前价格是否满足 买入的价格请求 + if buy_price_last - float(data_depth_asks.Price) > sale_buy_diff_now and float(data_depth_bids.Amount) > trade_amount * 1.5: + #Log("当前买价:", str(data_depth_asks.Price), "订单中最高买价:", str(sale_price_last),"生成买单") + trade_infor['price'] = float(data_depth_bids.Price) + trade_infor['trade_type'] = 'buy' + #判断当前价格是否破格,破格则置空买卖信息 + if float(data_depth_bids.Price) - sale_price_max > 0 or buy_price_min - float(data_depth_asks.Price) > 0: + trade_infor['price'] = 0 + trade_infor['trade_type'] = '' + timestr = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S') + Log(trade_infor,"...time:",timestr) + if trade_infor['price'] != 0: + #Log(trade_infor,"...time:",timestr) + pass + return trade_infor + + #根据委托信息生成买卖价格列表 + def get_trade_price_list(self,symbol): + sale_list = [] + buy_list = [] + #获取所有的交易记录,根据不同的类型 分配到 买卖列表中 + orders = exchange.GetOrders() + for i in range(len(orders)): + if orders[i].Type == 1: + sale_price = float(orders[i].Price) + sale_price_bak = copy.deepcopy(sale_price) + sale_list.append(sale_price_bak) + if orders[i].Type == 0: + buy_price = float(orders[i].Price) + buy_price_bak = copy.deepcopy(buy_price) + buy_list.append(buy_price_bak) + #判断为0的数组进处理 + if len(sale_list) == 0: + for i in range(len(buy_list)): + sale_list.append(float('%.6f' % (buy_list[i] + sale_buy_diff))) + if len(buy_list) == 0: + for i in range(len(sale_list)): + buy_list.append(float('%.6f' % (sale_list[i] - sale_buy_diff))) + trade_price_list = [sale_list,buy_list] + return trade_price_list + + #网格交易入口: + def grid_trade_start(self,symbol): + #进行状态获取,上涨/下跌 + # trend_status = self.kline_trend_check(symbol) + + #获取可否进行交易 + trade_infor = self.make_trade_check(symbol) + #进行判断是否交易,判断是否可以卖出 + # if trend_status == 'is_up' and trade_infor['price'] > 0 and trade_infor['trade_type'] == 'sale': + if trade_infor['price'] > 0 and trade_infor['trade_type'] == 'sale': + buy_price = float('%.6f' % (trade_infor['price'] - sale_buy_diff)) + #调用下单功能,先调用卖,再调用买 + order_id = exchange.Sell(trade_infor['price'], trade_amount) + #Log('order_id:',order_id) + #检查下单是否成功,不成功,则直接返回 + if order_id is None: + Log("下单失败,等待600s继续.........") + sleep(600) + return 0 + #检查主交易是否成功:判断卖单单是否交易成功,交易成功则进行买单下单 + for i in range(100): + sale_orders = exchange.GetOrder(order_id) + #Log('sale_orders:',sale_orders) + if sale_orders.Status == 1: + #如果卖单已成交,则进行买单提交 + exchange.Buy(buy_price, trade_amount) + return 0 + sleep(10) + #如果循环1000次还未成交,则取消订单 + exchange.CancelOrder(order_id) + # 进行判断是否交易,判断是否可以买入 + if trade_infor['price'] > 0 and trade_infor['trade_type'] == 'buy': + sale_price = float('%.6f' % (trade_infor['price'] + sale_buy_diff)) + # 调用下单功能,先调用买入,再调用卖出 + order_id = exchange.Buy(trade_infor['price'], trade_amount) + # 检查下单是否成功,不成功,则直接返回 + if order_id is None: + #Log("下单失败,等待600s继续.........") + sleep(600) + return 0 + # 检查主交易是否成功:判断买单是否交易成功,交易成功则进行卖单下单 + for i in range(100): + buy_orders = exchange.GetOrder(order_id) + if buy_orders.Status == 1: + # 如果买单已成交,则进行卖单提交 + exchange.Sell(sale_price, trade_amount) + return 0 + sleep(10) + # 如果循环1000次还未成交,则取消订单 + exchange.CancelOrder(order_id) + + #进行循环调用 + def grid_trade_cycle(self,symbol): + cycle_num = 0 + while(True): + timestr = (datetime.datetime.now()).strftime('%H%M%S') + self.grid_trade_start(symbol) + sleep(10) + cycle_num = cycle_num + 1 + if cycle_num % 100 == 0: + account_infor = exchange.GetAccount() + Log("当前用户的账号信息:%s,....当前已循环检查次数:%s"%(account_infor,str(cycle_num))) + +def main(): + Log(exchange.GetAccount()) + Log("测试") + fmz_market_instances = fmz_market() + fmz_market_instances.grid_trade_cycle(100) + #order_id = exchange.Sell(10000,1) +``` + +> 策略出处 + +https://www.fmz.com/strategy/175807 + +> 更新时间 + +2019-12-06 14:54:19 diff --git "a/\346\234\237\350\264\247\347\234\213\347\251\277\345\274\217\346\265\213\350\257\225.md" "b/\346\234\237\350\264\247\347\234\213\347\251\277\345\274\217\346\265\213\350\257\225.md" index a4c5a9d6..16b67fe3 100644 --- "a/\346\234\237\350\264\247\347\234\213\347\251\277\345\274\217\346\265\213\350\257\225.md" +++ "b/\346\234\237\350\264\247\347\234\213\347\251\277\345\274\217\346\265\213\350\257\225.md" @@ -18,7 +18,7 @@ num = 0 function onTick() { if (num < 1) { - _C(exchange.SetContractType, "rb1910") + _C(exchange.SetContractType, "rb2001") account = _C(exchange.GetAccount).Info.AccountID Log("账号:", account); Log("AppID:", "client_fmz_1.0"); @@ -73,4 +73,4 @@ https://www.fmz.com/strategy/152670 > 更新时间 -2019-07-29 10:30:46 +2019-09-09 16:12:19 diff --git "a/\346\240\271\346\215\256\345\225\206\345\223\201\346\234\237\350\264\247\350\256\241\345\210\222\345\247\224\346\211\230\345\267\245\345\205\267\345\256\236\347\216\260\344\270\200\344\270\252\347\237\255\347\272\277\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" "b/\346\240\271\346\215\256\345\225\206\345\223\201\346\234\237\350\264\247\350\256\241\345\210\222\345\247\224\346\211\230\345\267\245\345\205\267\345\256\236\347\216\260\344\270\200\344\270\252\347\237\255\347\272\277\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" new file mode 100644 index 00000000..ef02f14f --- /dev/null +++ "b/\346\240\271\346\215\256\345\225\206\345\223\201\346\234\237\350\264\247\350\256\241\345\210\222\345\247\224\346\211\230\345\267\245\345\205\267\345\256\236\347\216\260\344\270\200\344\270\252\347\237\255\347\272\277\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" @@ -0,0 +1,235 @@ + +> 策略名称 + +根据商品期货计划委托工具实现一个短线策略(教学) + +> 策略作者 + +小小梦 + +> 策略描述 + +策略相关文章: +https://www.fmz.com/bbs-topic/4654 +https://www.fmz.com/bbs-topic/4697 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|_EntrustSymbol|null|委托合约代码| +|_StopLossDiffPrice|5|止损差价| +|_StopWinDiffPrice|5|止盈差价| +|_BackhandDiffPrice|5|反手距离| +|_EntrustAmount|true|委托数量| +|_IsBackHand|false|是否反手| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2019-03-01 00:00:00 +end: 2019-11-23 21:09:00 +period: 1m +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["_EntrustSymbol","rb2001"],["_StopLossDiffPrice",10],["_StopWinDiffPrice",10],["_BackhandDiffPrice",10],["_IsBackHand",true]] +*/ + +// 全局变量 +var _TaskQueue = [] +var ENTRUST = 0 +var STOPLOSS = 1 +var STOPPROFIT = 2 +var BACKHAND = 3 +var dictTaskType = ["委托任务", "止损任务", "止盈任务", "反手任务"] + +var q = $.NewTaskQueue() +var p = $.NewPositionManager() +var IsEntrust = false + +function closeTask (taskType) { + for (var i = 0; i < _TaskQueue.length; i++) { + if (taskType == _TaskQueue[i].taskType) { + _TaskQueue[i].taskFinished = true + Log("关闭任务:", dictTaskType[taskType]) + } + } +} + +// 任务处理对象 +var oneDayBeginTS = 0 +function TaskQueueProcess () { + // 获取行情 + exchange.SetContractType(_EntrustSymbol) + var ticker = _C(exchange.GetTicker) + var records = _C(exchange.GetRecords) + $.PlotRecords(records, "K") + var nowTs = new Date().getTime() + + // 寻找每日的第一根bar + for (var j = records.length - 1; j > -1; j--) { + var ts = records[j].Time + if (ts % (1000 * 60 * 60 * 24) == 3600000) { // 60 * 60 * 1000 + if (oneDayBeginTS != ts) { + oneDayBeginTS = ts + Log("新的一天开始!") + // 清空任务队列 + IsEntrust = false + } + break + } + } + + // 检测收盘,重置 + if (nowTs + 1000 * 60 > oneDayBeginTS + 1000 * 60 * 60 * 6) { + p.CoverAll() + _TaskQueue = [] + } + + var sum = 0 + var count = 0 + var avg = 0 + for (var n = 0 ; n < records.length; n++) { + if (records[n].Time >= oneDayBeginTS) { + sum += records[n].Close + count++ + if (n == records.length - 1) { + avg = sum / count + $.PlotLine("avg", avg, records[n].Time) + } + } + } + + // 计算ATR + var records_Day = _C(exchange.GetRecords, PERIOD_D1) + if (records_Day.length <= 5) { + LogStatus("收集K线") + Sleep(2000) + return + } + var atr = TA.ATR(records_Day, 5) + var _Dis = atr[atr.length - 2] * 0.5 + + if (Math.abs(records[records.length - 1].Close - avg) > _Dis && !IsEntrust) { + var task = { + taskType : ENTRUST, + taskSymbol : _EntrustSymbol, + taskPrice : records[records.length - 1].Close, + taskAmount : _EntrustAmount, + taskDirection : records[records.length - 1].Close - avg > 0 ? "sell" : "buy", + taskTrigger : records[records.length - 1].Close - avg > 0 ? 1 : -1, // 大于触发 + taskFinished : false + } + + Log("请注意,创建委托任务", task, "#FF0000") + _TaskQueue.push(task) + IsEntrust = true + } + + for (var i = 0; i < _TaskQueue.length; i++) { + var task = _TaskQueue[i] + if (task.taskFinished == false && task.taskType == ENTRUST && task.taskTrigger * ticker.Last >= task.taskTrigger * task.taskPrice) { + q.pushTask(exchange, task.taskSymbol, task.taskDirection, task.taskAmount, function(tradeTask, ret) { + Log(tradeTask.desc, ret, "委托完成") + if (ret) { + // 回调,创建后续任务 + if (task.taskPrice != -1) { // 创建止损任务 + var newTask = { + taskType : STOPLOSS, + taskSymbol : task.taskSymbol, + taskPrice : task.taskDirection == "buy" ? task.taskPrice - _StopLossDiffPrice : task.taskPrice + _StopLossDiffPrice, + taskAmount : task.taskAmount, + taskDirection : task.taskDirection == "buy" ? "closebuy" : "closesell", + taskTrigger : task.taskDirection == "buy" ? -1 : 1, // -1低于 价格触发 + taskFinished : false + } + _TaskQueue.push(newTask) + Log("创建止损任务", newTask, "#FF0000") + } + if (task.taskPrice != -1) { // 创建止盈任务 + var newTask = { + taskType : STOPPROFIT, + taskSymbol : task.taskSymbol, + taskPrice : task.taskDirection == "buy" ? task.taskPrice + _StopWinDiffPrice : task.taskPrice - _StopWinDiffPrice, + taskAmount : task.taskAmount, + taskDirection : task.taskDirection == "buy" ? "closebuy" : "closesell", + taskTrigger : task.taskDirection == "buy" ? 1 : -1, // 1高于 价格触发 + taskFinished : false + } + _TaskQueue.push(newTask) + Log("创建止盈任务", newTask, "#FF0000") + } + } + }) + task.taskFinished = true + break + } else if (task.taskFinished == false && task.taskType == STOPLOSS && ticker.Last * task.taskTrigger >= task.taskPrice * task.taskTrigger) { + q.pushTask(exchange, task.taskSymbol, task.taskDirection, task.taskAmount, function(tradeTask, ret) { + Log(tradeTask.desc, ret, "止损完成") + // 关闭止盈任务 + closeTask(STOPPROFIT) + if (ret) { + // 回调,创建后续任务 + if (task.taskPrice != -1 && _IsBackHand) { + var newTask = { + taskType : BACKHAND, + taskSymbol : task.taskSymbol, + taskPrice : task.taskDirection == "closebuy" ? task.taskPrice - _BackhandDiffPrice : task.taskPrice + _BackhandDiffPrice, + taskAmount : task.taskAmount, + taskDirection : task.taskDirection == "closebuy" ? "sell" : "buy", + taskTrigger : task.taskDirection == "closebuy" ? -1 : 1, // -1 小于时触发, 1大于时触发 + taskFinished : false + } + _TaskQueue.push(newTask) + Log("创建反手任务", newTask, "#FF0000") + } + } + }) + task.taskFinished = true + break + } else if (task.taskFinished == false && task.taskType == STOPPROFIT && ticker.Last * task.taskTrigger >= task.taskPrice * task.taskTrigger) { + q.pushTask(exchange, task.taskSymbol, task.taskDirection, task.taskAmount, function(tradeTask, ret) { + Log(tradeTask.desc, ret, "止盈完成") + // 关闭止损任务 + closeTask(STOPLOSS) + }) + task.taskFinished = true + break + } else if (task.taskFinished == false && task.taskType == BACKHAND && ticker.Last * task.taskTrigger >= task.taskPrice * task.taskTrigger) { + q.pushTask(exchange, task.taskSymbol, task.taskDirection, task.taskAmount, function(tradeTask, ret) { + Log(tradeTask.desc, ret, "反手完成") + }) + task.taskFinished = true + break + } + } + q.poll() +} + +function main() { + while (true) { + if (exchange.IO("status")) { + TaskQueueProcess() + // 状态栏显示 + LogStatus(_D(), "已连接") + } else { + LogStatus(_D(), "未连接") + } + Sleep(500) + } +} + + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/176022 + +> 更新时间 + +2019-11-26 10:47:02 diff --git "a/\346\243\200\346\237\245https:--quant.la-Argus-\346\230\257\345\220\246\346\255\243\345\270\270.md" "b/\346\243\200\346\237\245https:--quant.la-Argus-\346\230\257\345\220\246\346\255\243\345\270\270.md" index a8a46344..1d34ffce 100644 --- "a/\346\243\200\346\237\245https:--quant.la-Argus-\346\230\257\345\220\246\346\255\243\345\270\270.md" +++ "b/\346\243\200\346\237\245https:--quant.la-Argus-\346\230\257\345\220\246\346\255\243\345\270\270.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 diff --git "a/\346\265\213\350\257\225\345\233\276\350\241\250.md" "b/\346\265\213\350\257\225\345\233\276\350\241\250.md" deleted file mode 100644 index ef9d86e1..00000000 --- "a/\346\265\213\350\257\225\345\233\276\350\241\250.md" +++ /dev/null @@ -1,183 +0,0 @@ - -> 策略名称 - -测试图表 - -> 策略作者 - -Hukybo - - - - - -> 源码 (python) - -``` python -'''backtest -start: 2019-01-01 00:00:00 -end: 2019-08-09 00:00:00 -period: 1d -exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] -''' - - -import requests -import re -from bs4 import BeautifulSoup -import time -import datetime -import random -import json -import threading - - -# 请求头文件 -request_headers = { - 'Connection': 'keep-alive', - 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3', - 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', - 'accept-encoding': 'gzip, deflate', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36' -} - - -# ip代理 -proxies = { - 'http': 'http://182.35.82.128:9999', 'https': 'https://182.35.82.128:9999' -} - - -diff_old_data = 0 - - -# 日期转时间戳 -def to_timestamp(date_str): - times = date_str + " 00:00:00" - time_array = time.strptime(times, "%Y-%m-%d %H:%M:%S") - return int(round(time.mktime(time_array))) - - -# 返回日期数组 -def date_arr(year, month, day): - begin = datetime.date(year, month, day) - end = datetime.date.today() - arr = [] - for i in range((end - begin).days + 1): - day = begin + datetime.timedelta(days=i) - arr.append([str(day).replace('-', ''), str(day), day.weekday() + 1, to_timestamp(str(day))]) - return arr - - -def spot_futures_diff_data(date, futures_name): - global diff_old_data - url = f"http://www.100ppi.com/sf2/day-{date}.html" - try: - url_text = requests.get(url, headers=request_headers).text # , proxies=proxies - except BaseException: - print('由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。') - return int(diff_old_data) - soup = BeautifulSoup(url_text, "html5lib") - results = soup.select("#fdata")[0] - for i in results.find_all('tr'): - if len(i.find_all('td', text=futures_name)) > 0: - data = i.find_all('font')[0].text - if data is not None: - diff_old_data = data - return int(data) - return int(diff_old_data) - - -def main(): - # threading.Thread(target=spot_futures_diff_arr, args=('天然橡胶',)).start() - # threading.Thread(target=commodity_inventory_arr, args=('天然橡胶',)).start() - # threading.Thread(target=commodity_warehouse_receipt_arr, args=('天然橡胶',)).start() - - cfgA = { - "extension": { - "layout": 'single', - "col": 6, - "height": "500px", - }, - "title" : { - "text" : "基差图表" - }, - "xAxis" : { - "type" : "datetime" - }, - "series" : [{ - "name" : "基差", - "data" : [], - }] - } - cfgB = { - "extension": { - "layout": 'single', - "col": 6, - "height": "500px", - }, - "title" : { - "text" : "库存图表" - }, - "xAxis" : { - "type" : "datetime" - }, - "series" : [{ - "name" : "库存", - "data" : [], - }] - } - cfgC = { - "extension": { - "layout": 'single', - "col": 6, - "height": "500px", - }, - "title" : { - "text" : "仓单图表" - }, - "xAxis" : { - "type" : "datetime" - }, - "series" : [{ - "name" : "仓单", - "data" : [], - }] - } - cfgD = { - "extension": { - "layout": 'single', - "col": 6, - "height": "500px", - }, - "title" : { - "text" : "利润图表" - }, - "xAxis" : { - "type" : "datetime" - }, - "series" : [{ - "name" : "利润", - "data" : [], - }] - } - chart = Chart([cfgA, cfgB, cfgC, cfgD]) - for i in date_arr(2018, 1, 1): - diff = spot_futures_diff_data(i[1], '天然橡胶') - chart.add(0, [i[3], diff]) - chart.add(1, [i[3], diff]) - chart.add(2, [i[3], diff]) - chart.add(3, [i[3], diff]) - Log('时间戳', i[3], type(i[3])) - Log('数据', diff, type(diff)) - #chart.update([cfgA, cfgB, cfgC, cfgD]) - time.sleep(1) -``` - -> 策略出处 - -https://www.fmz.com/strategy/162093 - -> 更新时间 - -2019-08-15 16:55:35 diff --git "a/\346\267\261\345\272\246\345\201\232\345\270\202.md" "b/\346\267\261\345\272\246\345\201\232\345\270\202 \347\233\230\345\217\243\346\216\247\345\210\266 \346\223\215\347\233\230\346\234\272\345\231\250\344\272\272 \345\201\232\345\270\202\345\267\245\345\205\267.md" similarity index 95% rename from "\346\267\261\345\272\246\345\201\232\345\270\202.md" rename to "\346\267\261\345\272\246\345\201\232\345\270\202 \347\233\230\345\217\243\346\216\247\345\210\266 \346\223\215\347\233\230\346\234\272\345\231\250\344\272\272 \345\201\232\345\270\202\345\267\245\345\205\267.md" index 4945665b..cbfd0326 100644 --- "a/\346\267\261\345\272\246\345\201\232\345\270\202.md" +++ "b/\346\267\261\345\272\246\345\201\232\345\270\202 \347\233\230\345\217\243\346\216\247\345\210\266 \346\223\215\347\233\230\346\234\272\345\231\250\344\272\272 \345\201\232\345\270\202\345\267\245\345\205\267.md" @@ -1,7 +1,7 @@ > 策略名称 -深度做市 +深度做市 盘口控制 操盘机器人 做市工具 > 策略作者 @@ -23,7 +23,7 @@ import random import hashlib import sys import threading -from openapi import * +from api import * symbol = sys.argv[1] gap= float(sys.argv[2]) #密度/价差 @@ -47,6 +47,7 @@ requests.packages.urllib3.disable_warnings() def GetTicker(): +def GetPV(): def GetDepth(): @@ -57,37 +58,27 @@ def GetOrders(): def create_order(side,price,amount): - def CancelOrder(order_id): def Buy(price,amount): - def Sell(price,amount): def GetRecords(symbol,period): - def GetPrecision(): def getrr(): - def ordersend_shortperoid(): - - def ordersend_longperoid(): - def send_big_order(): - def cancel(): - - if __name__ == '__main__': precision = GetPrecision() print(precision) @@ -128,4 +119,4 @@ https://www.fmz.com/strategy/146238 > 更新时间 -2019-05-02 21:02:21 +2019-12-10 13:39:07 diff --git "a/\347\201\253\345\270\201\347\202\271\345\215\241.md" "b/\347\201\253\345\270\201\347\202\271\345\215\241.md" index b43d04b6..28c3ddea 100644 --- "a/\347\201\253\345\270\201\347\202\271\345\215\241.md" +++ "b/\347\201\253\345\270\201\347\202\271\345\215\241.md" @@ -5,7 +5,7 @@ > 策略作者 -jason47 +一拳男孩 > 策略描述 diff --git "a/\347\201\253\345\270\201\347\262\276\345\272\246.md" "b/\347\201\253\345\270\201\347\262\276\345\272\246.md" index 3391b096..4ea8c7c1 100644 --- "a/\347\201\253\345\270\201\347\262\276\345\272\246.md" +++ "b/\347\201\253\345\270\201\347\262\276\345\272\246.md" @@ -5,7 +5,7 @@ > 策略作者 -jason47 +一拳男孩 > 策略描述 diff --git "a/\347\210\254\345\217\226\345\270\201\345\256\211\345\205\254\345\221\212\350\207\252\345\212\250\345\207\272\345\224\256\345\260\206\350\246\201\344\270\213\346\236\266\345\270\201|crawl Binance announcements and sell Delist coin.md" "b/\347\210\254\345\217\226\345\270\201\345\256\211\345\205\254\345\221\212\350\207\252\345\212\250\345\207\272\345\224\256\345\260\206\350\246\201\344\270\213\346\236\266\345\270\201|crawl Binance announcements and sell Delist coin.md" index ec8e0ac7..3279b8c6 100644 --- "a/\347\210\254\345\217\226\345\270\201\345\256\211\345\205\254\345\221\212\350\207\252\345\212\250\345\207\272\345\224\256\345\260\206\350\246\201\344\270\213\346\236\266\345\270\201|crawl Binance announcements and sell Delist coin.md" +++ "b/\347\210\254\345\217\226\345\270\201\345\256\211\345\205\254\345\221\212\350\207\252\345\212\250\345\207\272\345\224\256\345\260\206\350\246\201\344\270\213\346\236\266\345\270\201|crawl Binance announcements and sell Delist coin.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/\347\211\233\347\206\212\345\260\217\345\215\226\351\203\250\347\255\226\347\225\245V1.0_OKex\345\220\210\347\272\246.md" "b/\347\211\233\347\206\212\345\260\217\345\215\226\351\203\250\347\255\226\347\225\245V1.0_OKex\345\220\210\347\272\246.md" new file mode 100644 index 00000000..3523e33f --- /dev/null +++ "b/\347\211\233\347\206\212\345\260\217\345\215\226\351\203\250\347\255\226\347\225\245V1.0_OKex\345\220\210\347\272\246.md" @@ -0,0 +1,266 @@ + +> 策略名称 + +牛熊小卖部策略V1.0_OKex合约 + +> 策略作者 + +tomjava + +> 策略描述 + +前面文章讨论过,小卖部策略在特定情况下,可以做到130%的年化收益。不过这是在特定情况下,就是该商品的月度均线,从长期看是上升的,且经过了很长一段时间。如果在进入市场的短期3个月里,都处于下跌市里,那可能遭到重大打击。 +究其原因,最重要的是,该策略没引入做空机制。犹如在A股市场里,只能做多,那下跌来时,只能空仓或者被动挨揍。还好数字货币是提供做空机制的,通过合约交易,我们就可以把下跌风险规避掉。 +今天区班主做的策略是牛熊小卖部策略。主要思想是牛市来了,就做多,同时抬高公允价格的预期;熊市来了,就做空,同时降低公允价格的预期。猴市来了则高抛低吸。牛熊猴的判断参考之前的文章,就是以短期高低点和长期高低点的关系,决定当前市场状态。 +本策略应用于ETH,这里需要指出两个坑:1、本策略基于ETH,ETH在OKex期货里,是10刀一张的;需要BTC的朋友请自己修改一下除数;2、合约下单后,如果是相同多单,会合并成一个Position,所以Position的长度最多为2,这也是导致区班主当时反复调试的地方,还好最后解决了。 +注册币乎后https://m.bihu.com/signup?i=1ewtKO&s=4&c=4 +搜索 物联网区块链 可以联系到作者区班主 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Interval|10|轮询周期(秒)| +|mnum|20|30分钟线周期| +|initRatio|0.5|初始仓位比例| +|dnum|5|日线周期| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2019-01-01 00:00:00 +end: 2019-10-10 00:00:00 +period: 1d +exchanges: [{"eid":"OKEX","currency":"ETH_USDT","stocks":0}] +args: [["OpMode",1,10989],["MaxAmount",1,10989],["TradeFee",0.001,10989]] +*/ +//注册币乎后https://m.bihu.com/signup?i=1ewtKO&s=4&c=4 +//搜索 物联网区块链 可以联系到作者区班主 +var status = 10; //10表示猴市初始化,11表示猴市继续;20表示牛市初始化,21表示牛市继续;30表示熊市初始化,31表示熊市继续 +var dhigh; +var dlow; +var mlow; +var mhigh; + +var operPrice; +function monkeyOper(){ + var i; + var position; + var account = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + var nowPrice=ticker.Sell; + var pAmount; + + /* if(status==10){ //进入猴市初始化,设定公允价格 + operPrice=mlow+mhigh; + }else{ + if(nowPriceoperPrice*1.03){ //值得卖 + //卖平所有多单 + position = _C(exchange.GetPosition); + for (i = 0; i < position.length; i++) { + if(position[i].Type==PD_LONG){ //卖平多单 + exchange.SetDirection("closebuy"); + exchange.Sell(nowPrice,position[i].Amount); + }else{ + pAmount=position[i].Amount; + } + } + + if(pAmount*10operPrice*1.03){ //最多挂两单,大力做多 + exchange.SetDirection("sell"); + if(pAmount*10dhigh&&mlow(dhigh+dlow)*1.03){ + if(status==20){ + status=21; + }else{ + status=20; + } + bullOper(); + }else{ + if(status==10){ + status=11; + }else{ + status=10; + } + monkeyOper(); + } + }else if(mhigh>dhigh){ //分钟低点突破日高点,牛开始 + if(status==20){ + status=21; + }else{ + status=20; + } + bullOper(); + }else if(mlow 策略出处 + +https://www.fmz.com/strategy/171038 + +> 更新时间 + +2019-10-24 13:44:56 diff --git "a/\347\211\233\347\206\212\347\214\264\345\270\202\345\210\244\346\226\255V1.0_\345\214\272\347\217\255\344\270\273.md" "b/\347\211\233\347\206\212\347\214\264\345\270\202\345\210\244\346\226\255V1.0_\345\214\272\347\217\255\344\270\273.md" new file mode 100644 index 00000000..0474795d --- /dev/null +++ "b/\347\211\233\347\206\212\347\214\264\345\270\202\345\210\244\346\226\255V1.0_\345\214\272\347\217\255\344\270\273.md" @@ -0,0 +1,111 @@ + +> 策略名称 + +牛熊猴市判断V1.0_区班主 + +> 策略作者 + +tomjava + +> 策略描述 + +我们发现,量化投资最重要的还是择时,就是判断当前市场是熊市还是牛市还是猴市。区班主这篇来讨论一下择时策略怎么做。 + + 择时有很多种做法,均线判断、布林线、成交量和周期高低点。 + + 均线判断就是通过均线的倾角,判断当前市场是上升还是下降。通过判断是否站上5日均线判断是否小牛,判断是否跌破120日均线判断是否进入熊市。几个因素综合起来决定当前市场强弱。 + + 布林线是一个很好的判断方式,根据布林线中线的倾角,判断市场是上升还是下降。根据布林线的高点和低点来高抛低吸,是猴市里很好的做法。布林线如果开口加大,则是市场波动的前兆。 + + 成交量一般是个辅助手段,一般底部和顶部都会放量。数字货币有一个好处就是,交易深度很容易获得。通过分析挂单情况,结合成交量,也能判断当前市场热度。 + + 以上策略实现起来有一些难度,而且需要慢慢调优。周期高低点是本文讨论的重点策略,具有实现简单,效果直接的优点。周期高低点的思路很简单,就是结合短周期高低点和长周期高低点,判断当前市场是大牛,小牛还是大熊,小熊还是猴市。有了这个择时判断,我们在市场转向时,可以配合一定的策略。比如从小牛到大牛,可以加仓。大牛到猴市,可以平仓。猴市到小熊,可以初步建立空仓。进入大熊,则做空。 + + 我们先贴部分代码,主要思想都在注释里了,有缘人自然可以看懂。长周期选择日线,5日为周期。短周期选30分钟线,10个为周期,即5小时。可以结合相关数字货币的波动率和仓位调整参数。 +![![IMG](https://www.fmz.com/upload/asset/131028f566a19a2df8d71.png) ](https://www.fmz.com![IMG](https://www.fmz.com/upload/asset/131028f566a19a2df8d71.png)) +![![IMG](https://www.fmz.com/upload/asset/1311782042b83c9281493.png) ](https://www.fmz.com![IMG](https://www.fmz.com/upload/asset/1311782042b83c9281493.png)) + + 我们再贴一下执行结果。可见9月24日-9月25日的小熊转大熊,9月26日到10月7日的震荡猴市加小熊,以及10月9日出现小牛信号,都有正确提示。可见周期高低点策略,简约不简单。 +![ ![IMG](https://www.fmz.com/upload/asset/130e0870276675121b757.png) ](https://www.fmz.com![IMG](https://www.fmz.com/upload/asset/130e0870276675121b757.png)) +![ ![IMG](https://www.fmz.com/upload/asset/130dd6af2327f75a3e071.png) ](https://www.fmz.com![IMG](https://www.fmz.com/upload/asset/130dd6af2327f75a3e071.png)) + + 结合数字货币选型策略和对冲策略,还可以有更多玩法。如果把前20名市值的数字货币牛熊态排列出来,每次挑选2个数字货币大熊和大牛做对冲,基本可以做到低风险套利,这将是后面可以完善的策略。 + + 感兴趣的朋友也可以[在币乎找到我](https://m.bihu.com/signup?i=1ewtKO&c=4&s=4)。币乎是一个写文章可以赚到数字货币的地方。 +![![IMG](https://www.fmz.com/upload/asset/1314562ca57eb3ea873e1.jpg)](https://www.fmz.com![IMG](https://www.fmz.com/upload/asset/1314562ca57eb3ea873e1.jpg)) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Interval|60|轮询周期(秒)| +|dnum|5|日线周期| +|mnum|10|30分钟线周期| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2019-01-01 00:00:00 +end: 2019-10-10 00:00:00 +period: 1d +exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] +*/ +//通过快慢周期的高低点判断当前处于什么市场 +//注册币乎后https://m.bihu.com/signup?i=1ewtKO&s=4&c=4 +//搜索 物联网区块链 可以联系到作者区班主 +function main() { + var dhigh; + var dlow; + var mhigh; + var mlow; + var status_name=["猴市","大牛","小牛","大熊","小熊"]; //定义并赋值 + var before_status=0; + var now_status=0; + while (true) { + var drecords = exchange.GetRecords(PERIOD_D1); + var mrecords = exchange.GetRecords(PERIOD_M30); + //日线5天内的高低点(不包含当前Bar) + dhigh=TA.Highest(drecords, dnum, 'High'); + dlow=TA.Lowest(drecords, dnum, 'Low'); + + //30分钟线10个周期内的高低点(不包含当前Bar) + mhigh=TA.Highest(mrecords, mnum, 'High'); + mlow=TA.Lowest(mrecords, mnum, 'Low'); + + if(mlow>dhigh){ //分钟低点突破日高点,大牛开始 + now_status=1; + //Log("大牛"); + }else if(mhigh>dhigh&&mlow<=dhigh){ //分钟高点突破日高点,但是分钟低点还没突破日高点,小牛开始 + now_status=2; + //Log("小牛"); + }else if(mhighdlow){ //分钟低点跌破日低点,但是分钟高点还没跌破日低点,小熊开始 + now_status=4; + //Log("小熊"); + }else{ //没有方向,猴市 + now_status=0; + //Log("猴市"); + } + if(now_status!=before_status){ + Log("日线高点",dhigh," 日线低点",dlow,"30分钟线高点",mhigh," 30分钟线低点",mlow); + Log(status_name[before_status],"转",status_name[now_status]); + before_status=now_status; + } + Sleep(Interval*1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/170014 + +> 更新时间 + +2019-11-15 15:48:27 diff --git "a/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.md" "b/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.md" index a171061e..9d0f1b0b 100644 --- "a/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.md" +++ "b/\347\247\273\346\244\215 OKCoin \351\237\255\350\217\234\346\224\266\345\211\262\346\234\272.md" @@ -12,7 +12,7 @@ Zero 移植自: https://github.com/richox/okcoin-leeks-reaper 原作者说收手续费以后就失效了, 我只做了移植, 没有实盘测试, 有兴趣可以学习 -因为策略使用了GetTrades 这个函数在回测系统中是被模拟出来的, 所以回测没有什么意义, 只能直接上实盘测试 ! +发明者量化Tick级回测支持Depth与Trades的回放, 可以直接进行回测学习策略逻辑 以下为原说明 @@ -59,6 +59,14 @@ BTC: 3QFn1qfZMhMQ4FhgENR7fha3T8ZVw1bEeU > 源码 (javascript) ``` javascript +/*backtest +start: 2019-09-05 00:00:00 +end: 2019-09-05 22:00:00 +period: 1h +exchanges: [{"eid":"Binance","currency":"BTC_USDT","fee":[0,0]}] +mode: 1 +*/ + function LeeksReaper() { var self = {} self.numTick = 0 @@ -251,4 +259,4 @@ https://www.fmz.com/strategy/34388 > 更新时间 -2017-02-16 09:33:13 +2019-09-05 21:48:36 diff --git "a/\347\256\200\345\215\225\345\233\272\345\256\232\344\273\267\346\240\274\346\255\242\346\215\237\346\234\272\345\231\250\344\272\272|Stop Loss Below Fixed Price.md" "b/\347\256\200\345\215\225\345\233\272\345\256\232\344\273\267\346\240\274\346\255\242\346\215\237\346\234\272\345\231\250\344\272\272|Stop Loss Below Fixed Price.md" index c51020bb..7b95fbba 100644 --- "a/\347\256\200\345\215\225\345\233\272\345\256\232\344\273\267\346\240\274\346\255\242\346\215\237\346\234\272\345\231\250\344\272\272|Stop Loss Below Fixed Price.md" +++ "b/\347\256\200\345\215\225\345\233\272\345\256\232\344\273\267\346\240\274\346\255\242\346\215\237\346\234\272\345\231\250\344\272\272|Stop Loss Below Fixed Price.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/\347\256\200\345\215\225\345\235\207\347\272\277\347\255\226\347\225\245|Moving Average Bot 30 lines.md" "b/\347\256\200\345\215\225\345\235\207\347\272\277\347\255\226\347\225\245|Moving Average Bot 30 lines.md" index 62fff3bf..245d98cb 100644 --- "a/\347\256\200\345\215\225\345\235\207\347\272\277\347\255\226\347\225\245|Moving Average Bot 30 lines.md" +++ "b/\347\256\200\345\215\225\345\235\207\347\272\277\347\255\226\347\225\245|Moving Average Bot 30 lines.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245 (Copy).md" "b/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245 (Copy).md" deleted file mode 100644 index 37f1a978..00000000 --- "a/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245 (Copy).md" +++ /dev/null @@ -1,72 +0,0 @@ - -> 策略名称 - -简单多品种商品期货均线策略 (Copy) - -> 策略作者 - -ktz - -> 策略描述 - -商品期货类库实现了$.CTA函数的策略框架,借助该策略框架, 可以短短几十行实现一个并发稳定可实盘的多品种策略 - - https://dn-filebox.qbox.me/21384f4e53937bc1dd252ff478ff08e5b4d52e71.png - -> 策略参数 - - - -|参数|默认值|描述| -|----|----|----| -|Symbols|rb000,MA000|操作品种| -|FastPeriod|5|快线周期| -|SlowPeriod|20|慢线周期| -|ConfirmPeriod|2|确认周期| -|Lots|true|开仓手数| - - -> 源码 (javascript) - -``` javascript -/*backtest -start: 2017-06-01 00:00:00 -end: 2017-10-01 00:00:00 -period: 1d -*/ -function main() { - // 使用了商品期货类库的CTA策略框架 - $.CTA(Symbols, function(st) { - var r = st.records - var mp = st.position.amount - var symbol = st.symbol - /* - r为K线, mp为当前品种持仓数量, 正数指多仓, 负数指空仓, 0则不持仓, symbol指品种名称 - 返回值如为n: - n = 0 : 指全部平仓(不管当前持多持空) - n > 0 : 如果当前持多仓,则加n个多仓, 如果当前为空仓则平n个空仓,如果n大于当前持仓, 则反手开多仓 - n < 0 : 如果当前持空仓,则加n个空仓, 如果当前为多仓则平n个多仓,如果-n大于当前持仓, 则反手开空仓 - 无返回值表示什么也不做 - */ - if (r.length < SlowPeriod) { - return - } - var cross = _Cross(TA.EMA(r, FastPeriod), TA.EMA(r, SlowPeriod)); - if (mp <= 0 && cross > ConfirmPeriod) { - Log(symbol, "金叉周期", cross, "当前持仓", mp); - return Lots * (mp < 0 ? 2 : 1) - } else if (mp >= 0 && cross < -ConfirmPeriod) { - Log(symbol, "死叉周期", cross, "当前持仓", mp); - return -Lots * (mp > 0 ? 2 : 1) - } - }); -} -``` - -> 策略出处 - -https://www.fmz.com/strategy/159506 - -> 更新时间 - -2019-07-30 22:26:44 diff --git "a/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.md" "b/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.md" index ab2d75e9..0063764e 100644 --- "a/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.md" +++ "b/\347\256\200\345\215\225\345\244\232\345\223\201\347\247\215\345\225\206\345\223\201\346\234\237\350\264\247\345\235\207\347\272\277\347\255\226\347\225\245.md" @@ -33,6 +33,7 @@ Zero start: 2017-06-01 00:00:00 end: 2017-10-01 00:00:00 period: 1d +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] */ function main() { // 使用了商品期货类库的CTA策略框架 @@ -69,4 +70,4 @@ https://www.fmz.com/strategy/57029 > 更新时间 -2017-11-29 12:08:58 +2019-10-06 18:01:54 diff --git "a/\347\256\200\345\215\225\347\232\204\345\201\232\345\270\202\345\257\271\345\206\262\345\212\237\350\203\275.md" "b/\347\256\200\345\215\225\347\232\204\345\201\232\345\270\202\345\257\271\345\206\262\345\212\237\350\203\275.md" new file mode 100644 index 00000000..6c7c5099 --- /dev/null +++ "b/\347\256\200\345\215\225\347\232\204\345\201\232\345\270\202\345\257\271\345\206\262\345\212\237\350\203\275.md" @@ -0,0 +1,135 @@ + +> 策略名称 + +简单的做市对冲功能 + +> 策略作者 + +3piggy + +> 策略描述 + +小平台自己做市,降低风险,对冲到大交易所 +策略思想: +死循环轮询账户资产余额,将变动的币对冲到火币 +同时发送钉钉与微信通知给管理员 +使用sqlite保存历史账户余额,为其余策略服务,方便财务管理 + + + +> 源码 (python) + +``` python +# -*- coding: UTF-8 -*- +import time +from api import * +from Huobiapi import * +import sqlite3 + +def wechatmsg(text,desp): + server = 'https://sc.ftqq.com/xxxxxx.send' + payload = {'text':text,'desp':desp} + requests.post(server,params = payload) + +def dingmsg(title,msg): + url = 'https://oapi.dingtalk.com/robot/send?access_token=xxxxxx' + data = { + "msgtype": "markdown", + "markdown": { + "title":title+msg, + "text": "#### " + title + "\n" + "> " + msg + }} + header = {'Content-Type':'application/json'} + r = requests.post(url = url ,headers=header,data = json.dumps(data)).json() + return r + +def check(): + try: + pre_balance = {} + conn = sqlite3.connect("/root/bot/hedge.db") + cursor = conn.cursor() + sql = 'select * from balance order by id desc limit 20;' + result = list(cursor.execute(sql)) + for a in result: + if a[1] in list(pre_balance.keys()): + break + else: + pre_balance[a[1]] = a[2] #读取之前balance + coinname = list(pre_balance.keys()) + print(pre_balance,coinname) + + balance = GetBalance() + t = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) + for x in balance: + sql = "insert into balance (coin,balance,time) values(?,?,?);" + b = x['balance']+x['frozenBalance'] + if b != 0: + v = (x['coin']['unit'],b,t) + print(v) + cursor.execute(sql,v) + for n in coinname: + if n == x['coin']['unit']: + d = round(b - pre_balance[n],5) #数量差 + if d > 0: + Sell(n,d) + msg = '对冲卖出'+n+'数量:'+str(d) + print(msg) + wechatmsg('对冲',msg) + dingmsg('对冲',msg) + sql = "insert into hedge (coin,hedge_amount,status,time) values(?,?,?,?);" + v = (n,d,0,t) + cursor.execute(sql,v) + elif d < 0: + Buy(n,d) + msg = '对冲买入:'+n+'数量:'+str(d) + print(msg) + wechatmsg('对冲',msg) + dingmsg('对冲',msg) + sql = "insert into hedge (coin,hedge_amount,status,time) values(?,?,?,?);" + v = (n,d,0,t) + cursor.execute(sql,v) + else: + print('no hedge') + + conn.commit() + conn.close() + except Exception as e: + raise e + +def insert_balance(): + try: + conn = sqlite3.connect("hedge.db") + cursor = conn.cursor() + balance = GetBalance() + t = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) + for x in balance: + sql = "insert into balance (coin,balance,time) values(?,?,?);" + b = x['balance']+x['frozenBalance'] + if b != 0: + v = (x['coin']['unit'],b,t) + cursor.execute(sql,v) + conn.commit() + conn.close() + print('finish') + except Exception as e: + print('err',e) + +if __name__ == '__main__': + while 1: + try: + check() + except Exception as e: + print(e) + time.sleep(30) + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/178194 + +> 更新时间 + +2019-12-12 14:39:05 diff --git "a/\347\256\200\345\215\225\351\242\204\345\256\232\344\271\260\345\205\245\345\220\216\345\215\226\345\207\272\346\234\272\345\231\250\344\272\272|Buy then Sell (ping-pong strategy).md" "b/\347\256\200\345\215\225\351\242\204\345\256\232\344\271\260\345\205\245\345\220\216\345\215\226\345\207\272\346\234\272\345\231\250\344\272\272|Buy then Sell (ping-pong strategy).md" index 013b7b8a..7034aeb8 100644 --- "a/\347\256\200\345\215\225\351\242\204\345\256\232\344\271\260\345\205\245\345\220\216\345\215\226\345\207\272\346\234\272\345\231\250\344\272\272|Buy then Sell (ping-pong strategy).md" +++ "b/\347\256\200\345\215\225\351\242\204\345\256\232\344\271\260\345\205\245\345\220\216\345\215\226\345\207\272\346\234\272\345\231\250\344\272\272|Buy then Sell (ping-pong strategy).md" @@ -5,9 +5,11 @@ > 策略作者 -botvsing +小草 +> 策略描述 +如题,可设定买入价格,买入成功后自动挂卖出价格卖出, > 策略参数 @@ -37,6 +39,7 @@ function main() { } CancelPendingOrders() var account = _C(exchange.GetAccount) + var init_account = account Log('account: ', account.Balance); if(account.Balance > BUYPRICE*BUYAMOUNT){ exchange.Buy(BUYPRICE, BUYAMOUNT); @@ -45,8 +48,8 @@ function main() { } while(true){ account = _C(exchange.GetAccount) - if(account.Stocks >= 0.1*BUYAMOUNT){ - exchange.Sell(SELLPRICE, account.Stocks) + if(account.Stocks >= init_account.Stocks + 0.01){ + exchange.Sell(SELLPRICE, account.Stocks - init_account.Stocks) } Sleep(Intervel*1000) } @@ -60,4 +63,4 @@ https://www.fmz.com/strategy/121228 > 更新时间 -2018-10-16 10:56:26 +2019-10-22 14:57:26 diff --git "a/\347\273\217\345\205\270\345\235\207\347\272\277\347\255\226\347\225\245.md" "b/\347\273\217\345\205\270\345\235\207\347\272\277\347\255\226\347\225\245.md" index c45dd1e3..2472cbcc 100644 --- "a/\347\273\217\345\205\270\345\235\207\347\272\277\347\255\226\347\225\245.md" +++ "b/\347\273\217\345\205\270\345\235\207\347\272\277\347\255\226\347\225\245.md" @@ -40,6 +40,13 @@ https://dn-filebox.qbox.me/fb4d0c7d773ca83e9d0230927705d419dc0bbeaa.png > 源码 (javascript) ``` javascript +/*backtest +start: 2019-01-01 00:00:00 +end: 2019-07-01 00:00:00 +period: 1d +exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] +*/ + function main() { var STATE_IDLE = -1; var state = STATE_IDLE; @@ -98,4 +105,4 @@ https://www.fmz.com/strategy/12348 > 更新时间 -2018-10-13 12:05:55 +2019-10-08 17:00:12 diff --git "a/\347\273\217\345\205\270\345\235\207\347\272\277\347\255\226\347\225\245V1.0_\345\214\272\347\217\255\344\270\273\346\263\250\351\207\212\347\256\200\345\214\226.md" "b/\347\273\217\345\205\270\345\235\207\347\272\277\347\255\226\347\225\245V1.0_\345\214\272\347\217\255\344\270\273\346\263\250\351\207\212\347\256\200\345\214\226.md" new file mode 100644 index 00000000..eef33c6c --- /dev/null +++ "b/\347\273\217\345\205\270\345\235\207\347\272\277\347\255\226\347\225\245V1.0_\345\214\272\347\217\255\344\270\273\346\263\250\351\207\212\347\256\200\345\214\226.md" @@ -0,0 +1,108 @@ + +> 策略名称 + +经典均线策略V1.0_区班主注释简化 + +> 策略作者 + +tomjava + +> 策略描述 + +"Talk is cheap. Show me the code" + +教学性质, 实盘慎用. + + +注: ` 策略使用了交易模板类库` + +`希望新手从此策略入门, 一步步学习编写策略, 并体验到模拟与真实环境对交易系统的影响` + +https://dn-filebox.qbox.me/fb4d0c7d773ca83e9d0230927705d419dc0bbeaa.png + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|FastPeriod|5|入市快线周期| +|SlowPeriod|15|入市慢线周期| +|EnterPeriod|2|入市观察期| +|ExitFastPeriod|7|离市快线周期| +|ExitSlowPeriod|15|离市慢线周期| +|ExitPeriod|true|离市观察期| +|PositionRatio|0.8|仓位比例| +|StopLossRatio|0.05|止损比率| +|Interval|10|轮询周期(秒)| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2019-01-01 00:00:00 +end: 2019-10-10 00:00:00 +period: 1d +exchanges: [{"eid":"OKEX","currency":"ETH_USDT","stocks":0}] +args: [["OpMode",1,10989],["MaxAmount",1,10989],["TradeFee",0.001,10989]] +*/ +//注册币乎后https://m.bihu.com/signup?i=1ewtKO&s=4&c=4 +//搜索 物联网区块链 可以联系到作者区班主 +function main() { + var STATE_IDLE = -1; + var state = STATE_IDLE; //表示状态 + var entryPrice = 0; + var initAccount = _C(exchange.GetAccount); + Log(initAccount); + while (true) { + if (state === STATE_IDLE) { //初始化状态为默认仓;默认为空仓,只买入 + var n = $.Cross(FastPeriod, SlowPeriod);//模板函数返回EMA指标快线、慢线交叉结果 + if (Math.abs(n) >= EnterPeriod) { //EnterPeriod入市观察区,等待上拉一定时,再入场 + var account = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + var obj; + //账户现金乘以比例,除以当前价格,保留小数前3位 + if(n > 0){ + obj = $.Buy(_N(account.Balance * PositionRatio / ticker.Sell, 3)); + if (obj) { //如果购买成功,就标志开仓 + opAmount = obj.amount; + entryPrice = obj.price; + state = PD_LONG; + account = _C(exchange.GetAccount); + Log("开仓:购买量", opAmount); + Log("目前持币数", account.Stocks, "交叉周期", n); + } + } + } + } else { //state为非空闲状态;处理平仓检测 + var n = $.Cross(ExitFastPeriod, ExitSlowPeriod); + //这个判断条件有点长,先看Math.abs(n) >= ExitPeriod,n的绝对值大于等于 离市观察期 这是触发条件1,并且 + //(n > 0)两者中至少有个为真 + //需要离市平仓 + var needCover = Math.abs(n) >= ExitPeriod && (n<0); + if (needCover) { //离市平仓 + var nowAccount = _C(exchange.GetAccount); + var obj = $.Sell(_N(nowAccount.Stocks, 3)); + if(obj){ + state=STATE_IDLE; + Log("平仓:卖出量",nowAccount.Stocks); + nowAccount = _C(exchange.GetAccount); + Log("目前资金",nowAccount.Balance, "交叉周期", n,"盈利",nowAccount.Balance - initAccount.Balance); + } + //打印收益 + //LogProfit(nowAccount.Balance - initAccount.Balance, '钱:', nowAccount.Balance, '币:', nowAccount.Stocks, '平仓详情:', obj, "交叉周期", n); + } + } + Sleep(Interval*1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/169569 + +> 更新时间 + +2019-10-18 17:57:59 diff --git "a/\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.md" "b/\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.md" index dc314bc7..f0a9812a 100644 --- "a/\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.md" +++ "b/\347\273\237\350\256\241K\347\272\277\345\233\236\346\265\213\346\230\257\345\220\246\345\255\230\345\234\250\350\266\213\345\212\277.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/\350\207\252\351\200\202\345\272\224\345\212\250\346\200\201\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245My\350\257\255\350\250\200\347\211\210.md" "b/\350\207\252\351\200\202\345\272\224\345\212\250\346\200\201\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245My\350\257\255\350\250\200\347\211\210.md" new file mode 100644 index 00000000..3c3ce22d --- /dev/null +++ "b/\350\207\252\351\200\202\345\272\224\345\212\250\346\200\201\345\217\214\345\235\207\347\272\277\347\255\226\347\225\245My\350\257\255\350\250\200\347\211\210.md" @@ -0,0 +1,54 @@ + +> 策略名称 + +自适应动态双均线策略My语言版 + +> 策略作者 + +Hukybo + +> 策略描述 + +# 摘要 +我们知道价格变化的速度本身就在变化,传统简单均线受困于固定周期参数,这使得不论市场的走势如何,短期均线灵敏度高,更贴近价格走势,但在市场震荡时期反复转向,造成频繁发出错误开平仓信号;长期均线在趋势判断上更加可靠,但在市场加速上涨或下跌时反应迟钝,造成错过最佳的买卖点。 + +因此虽然传统简单均线可以在一定程度适应行情,但是却很难根据市场变化去进行调整,进而更好的把握趋势。特别在长期震荡行情中,不仅得不到正收益而且付出高额的交易成本,为了解决这个问题,我们引入考夫曼创立的自适应均线。 + +[点击阅读更多内容](https://www.fmz.com/digest-topic/4463) + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2015-02-22 00:00:00 +end: 2019-10-18 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["SlideTick",2,126961],["ContractType","rb000",126961]] +*) + +DIRECTION:=CLOSE-REF(CLOSE,10); +VOLATILITY:=SUM(ABS((CLOSE-REF(CLOSE,1))),10); +ER:=ABS(DIRECTION/VOLATILITY); +FASTSC:=2/(2+1); +SLOWSC:=2/(30+1); +SSC:=ER*(FASTSC-SLOWSC)+SLOWSC; +CONSTANT:SSC*SSC; +AMA1:EMA(MA(CLOSE,CONSTANT),1),COLORGREEN,LINETHICK3; +AMA2:EMA(MA(CLOSE,CONSTANT),10),COLORGREEN,LINETHICK3; +AMA1 > REF(AMA1, 1) && AMA2 > REF(AMA2, 1) && AMA1 > AMA2, BK; +AMA1 < REF(AMA1, 1) && AMA2 < REF(AMA2, 1) && AMA1 < AMA2, SK; +BKVOL > 1 && AMA1 < REF(AMA1, 1) || AMA2 < REF(AMA2, 1) || AMA1 < AMA2, SP; +SKVOL > 1 &&AMA1 > REF(AMA1, 1) || AMA2 > REF(AMA2, 1) || AMA1 > AMA2, BP; +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/170606 + +> 更新时间 + +2019-11-22 14:05:24 diff --git "a/\350\243\270K\344\270\212\344\270\213\345\275\261\347\272\277\345\234\250\344\272\244\346\230\223\347\255\226\347\225\245\344\270\255\347\232\204\345\272\224\347\224\250.md" "b/\350\243\270K\344\270\212\344\270\213\345\275\261\347\272\277\345\234\250\344\272\244\346\230\223\347\255\226\347\225\245\344\270\255\347\232\204\345\272\224\347\224\250.md" new file mode 100644 index 00000000..1d514f19 --- /dev/null +++ "b/\350\243\270K\344\270\212\344\270\213\345\275\261\347\272\277\345\234\250\344\272\244\346\230\223\347\255\226\347\225\245\344\270\255\347\232\204\345\272\224\347\224\250.md" @@ -0,0 +1,53 @@ + +> 策略名称 + +裸K上下影线在交易策略中的应用 + +> 策略作者 + +Hukybo + +> 策略描述 + +K线本身并没有什么价值,它只是一段数据的容器。从最底层的Tick数据流开始,根据时间周期划分成一段一段,每个周期内的第一个价格就是开盘价,最后一个价格就是收盘价,周期内最高的那个价格就是最高价,周期内最低的那个价格就是最低价,每个容器里面都储存着开高低收、成交量、时间等数据。这就是K线的由来,本篇我们将用上下影线战法,试着开发一个交易策略。 +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4259) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|BN|true|BN| +|SN|0.1|SN| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2019-01-16 00:00:00 +end: 2019-09-11 00:00:00 +period: 15m +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["ContractType","rb2001",126961]] +*) + +UP: HIGH - IFELSE(ISUP, CLOSE, OPEN); // 上影线 +MIDDLE: IFELSE(ISUP, CLOSE, OPEN) - IFELSE(ISUP, OPEN, CLOSE); // K线实体 +DOWN: IFELSE(ISUP, OPEN, CLOSE) - LOW; // 下影线 + +DOWN > (MIDDLE + UP) * BN, BK; // 多头开仓 +UP > (MIDDLE + DOWN) * SN, SP; // 空头开仓 +UP > (MIDDLE + DOWN) * SN, SK; // 多头平仓 +DOWN > (MIDDLE + UP) * BN, BP; // 空头平仓 +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/165130 + +> 更新时间 + +2019-09-12 10:36:40 diff --git "a/\350\256\276\345\256\232\346\257\224\347\211\271\345\270\201\344\273\267\346\240\274\345\271\266\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" "b/\350\256\276\345\256\232\346\257\224\347\211\271\345\270\201\344\273\267\346\240\274\345\271\266\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" index 8dd5d148..ce428157 100644 --- "a/\350\256\276\345\256\232\346\257\224\347\211\271\345\270\201\344\273\267\346\240\274\345\271\266\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" +++ "b/\350\256\276\345\256\232\346\257\224\347\211\271\345\270\201\344\273\267\346\240\274\345\271\266\345\276\256\344\277\241\346\216\250\351\200\201(\346\225\231\345\255\246\357\274\211| Push the price information to telegram.md" @@ -5,7 +5,7 @@ > 策略作者 -botvsing +小草 > 策略描述 diff --git "a/\351\222\211\351\222\211\346\216\250\351\200\201.md" "b/\351\222\211\351\222\211\346\216\250\351\200\201.md" index 2822465f..a15fff86 100644 --- "a/\351\222\211\351\222\211\346\216\250\351\200\201.md" +++ "b/\351\222\211\351\222\211\346\216\250\351\200\201.md" @@ -5,7 +5,7 @@ > 策略作者 -jason47 +一拳男孩 > 策略描述 diff --git "a/\351\246\231\345\206\234\347\275\221\346\240\274).md" "b/\351\246\231\345\206\234\347\275\221\346\240\274).md" new file mode 100644 index 00000000..c35bda8c --- /dev/null +++ "b/\351\246\231\345\206\234\347\275\221\346\240\274).md" @@ -0,0 +1,210 @@ + +> 策略名称 + +香农网格) + +> 策略作者 + +威尔士发 + +> 策略描述 + +阅读原文:[区块链量化投资系列课程(4) - 动态平衡策略](https://quantinfo.com/Article/View/1573/[1-4]%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B---%E5%8A%A8%E6%80%81%E5%B9%B3%E8%A1%A1%E7%AD%96%E7%95%A5.html) + +### 前言 +沃伦 · 巴菲特的导师本杰明 · 格雷厄姆曾经在[《聪明的投资者》](https://quantinfo.com/Download/View/2742/%E8%81%AA%E6%98%8E%E7%9A%84%E6%8A%95%E8%B5%84%E8%80%85%EF%BC%88%E7%AC%AC4%E7%89%88%EF%BC%89.html)一书中,曾经提到过一种股票债券动态平衡的交易模式。 +[]( https://dn-filebox.qbox.me/71666050bcdc809d074f5cfa3499650045306c5d.png ) +这种交易模式非常简单: +- 把手中 50% 的资金投资于股票基金,剩下 50% 投资于债券基金。即股票和债券两者各占一半。 +- 根据固定间隔时间或市场变化进行一次资产再平衡,使股票资产和债券资产的比例恢复到初始的 1:1。 +这就是整个策略的全部逻辑,包含了什么时候买卖,以及买卖多少。够简单吧! + +在这个方法中,债券基金的波动率其实很小,远远低于股票波动率,所以债券在这里被当做『 参照锚 』,也就是说,用债券来衡量股票究竟是涨得太多了,还是涨得太少了。如果,股票价格上涨,会使得股票的市值大于债券的市值,当两者市值比率超过设定的阈值时,则对总仓位进行重新调整,卖出股票,并且买入债券,使股债市值比例恢复至初始的 1:1。 + +反之,股票价格下跌,会使得股票的市值小于债券的市值,当两者市值比率超过设定的阈值时,则对总仓位进行重新调整,买入股票,并且卖出债券,使股债市值比例恢复至初始的 1:1。 +[]( https://dn-filebox.qbox.me/0b155ba7a40dfa853174cbc60ea89a40434b2441.jpg ) + +就这样,在动态平衡股票和债券之间的比例,就够享受到股票成长的果实,并且减少了资产波动率。作为价值投资的先驱,格雷厄姆为我们提供了一个很好的思路。 + +既然这是一个完整的策略,为何我们不把它用在数字货币上呢? + +### 区块链资产 BTC 中的动态平衡策略 +#### 策略逻辑 +- 按照当前的 BTC 的价值,账户余额保留¥5000 现金和 0.1个 BTC,即现金和BTC 市值的初始比例是 1:1。 +- 如果 BTC 的价格上涨至¥6000,即 BTC 市值大于账户余额,并且其之间的差超过设定的阈值,就卖掉(6000-5000)/6000/2个币。说明 BTC 升值了,把钱兑换回来。 +- 如果 BTC 的价格下跌至¥4000,即 BTC市值小于账户余额,并且其之间的差超过设定的阈值,就买入(5000-4000)/4000/2个币。说明 BTC 贬值了,把 BTC 买回来。 + +就这样,不管 BTC 是升值还是贬值,始终动态保持账户余额和 BTC 的市值相等。如果 BTC 贬值了就买一些,等再涨回来,就再卖一些,就好像天平一样。 + +### 那么,如何用代码去实现呢? +我们以发明者量化交易平台为例,首先让我们看一下策略框架: +[]( https://dn-filebox.qbox.me/f0b1866a50126e6ffb3670fefc9cc0a0f5677ab6.png ) + +整个策略框架其实很简单,一个 main 主函数、一个 onTick 下单函数、一个 CancelPendingOrders 函数、以及必要参数。 + +### 下单模块 +[]( https://dn-filebox.qbox.me/fa17c458239f19cab2986f0cf7cd097a521eec4b.png ) + +下单交易逻辑条理清晰,所有的注释都已经写到代码里面了,可以点击图片放大查看。 + +#### 主要流程如下: +- 获取账户信息。 +- 获取 Tick 数据。 +- 计算 Tick 数据买卖价差。 +- 计算账户余额和 BTC 市值价差。 +- 计算买卖条件、下单价格、下单量。 +- 下单,并返回 true。 + +### 撤单模块 +[]( https://dn-filebox.qbox.me/6245854ec66a01bb7ea610da75b9ad46422a4f5d.png ) + +撤单模块就更简单了,步骤如下: +- 撤单前先等待 1 秒,个别交易所,你懂的。 +- 持续获取未成交订单数组,如果返回异常,则继续获取。 +- 如果未成交订单数组为空,即时返回撤单状态。 +- 如果有未成交的订单,则遍历整个数组,并依次根据订单号撤单。 + + +### 策略全部源码 +![]( https://dn-filebox.qbox.me/8df49e36426dfdc05c5d496c73f1300afd79af0f.jpg ) + +借助发明者量化交易平台,短短 80 行代码,一个完整的区块链 BTC 动态平衡策略应运而生。但这么简单的策略,究竟有没有价值呢? + +接下来,让我们测试一下这个简单的动态平衡策略,看看到底有没有效果。以下是在 BTC 的历史数据上的回测,仅供大家参考。 + + +### 回测环境 +[]( https://dn-filebox.qbox.me/e9ffd2a1451dc0c2b31a20cd1a54697567d1e561.png ) + + +### 回测绩效 +[]( https://dn-filebox.qbox.me/2a1e1ff7497de19f707add137debc547a93ca4ba.png ) + + +### 回测曲线 +[]( https://dn-filebox.qbox.me/dcbcd9b31ade9b9ce72b0ed86aa82435d5a11ef5.png ) + + +再来一张,同时期 BTC 价格走势图 +[]( https://dn-filebox.qbox.me/ec84ecde879721f515b9db17200b5fded748fc76.png ) + + +有没有震精到你。 + + +BTC 已经持续了长达 8 个月下跌,甚至最大跌幅超过70%,这造成很多投资者对区块链资产失去信心。本篇策略累计收益高达 160%,年化收益风险比超过 5。对于一个这么简单的投资策略,这个投资回报率已经超过绝大多数梭哈的群众了。 + +本篇动态平衡策略,只有一个核心参数(threshold 阈值),是一个很简单的投资方法,追求的不是超额的收益,而是稳健的收益。与趋势策略相反,动态平衡策略却是逆势而动。在市场热的时候减仓降温,市场冷清的时候加仓蛰伏,有点类似宏观经济调控。其实,动态平衡策略正是秉承了价格不可预测的观念,同时又捕捉价格波动的一门手艺。动态平衡策略的关键核心在设定和调整资产配置比例,还有触发阈值。 + +鉴于篇幅原因,一篇文章没办法做到面面俱到,要知道文字之外,存乎一心。动态平衡策略最重要的是投资思想,你甚至可以把本篇中的单个 BTC 资产换成一篮子区块链资产组合。 +[]( https://dn-filebox.qbox.me/a0d2ff01f4f8ed7ad77eeeecb6650129040f792b.jpg ) + +最后,让我们以本杰明 · 格雷厄姆在《聪明的投资者》一书中的名言来结束本篇:股票市场并非一个能精确衡量价值的『 称重计 』,相反它是一个『 投票机 』,不计其数的人所做出的决定是一种理性和感性的掺杂物,有很多时候这些抉择和理性的价值评判相去甚远。投资的秘诀就是在价格远远低于内在价值时投资,并且相信市场趋势会回升。——本杰明 · 格雷厄姆《聪明的投资者》 + + +延伸阅读: +[区块链量化投资系列课程(1) - 简介](https://quantinfo.com/Article/View/818/Empty.html) +[区块链量化投资系列课程(2) - 认识数字货币](https://quantinfo.com/Article/View/819/Empty.html) +[区块链量化投资系列课程(3) - 跨期套利](https://quantinfo.com/Article/View/816/Empty.html) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|threshold|0.005|阀值| +|Interval|2000|出错重试间隔(毫秒)| +|LoopInterval|60|轮询间隔(秒)| +|MinStock|0.001|最小交易量| +|XPrecision|4|量精度| +|ZPrecision|8|价格精度| + + +> 源码 (javascript) + +``` javascript +// 回测环境 +/*backtest +start: 2018-01-01 00:00:00 +end: 2018-08-01 11:00:00 +period: 1m +exchanges: [{"eid":"OKCoin_EN","currency":"BTC"}] +*/ + + + +// 撤单函数 +function CancelPendingOrders() { + Sleep(1000); // 休眠 1秒 + var ret = false; + while (true) { + var orders = null; + // 持续获取未成交订单数组,如果返回异常,则继续获取 + while (!(orders = exchange.GetOrders())) { + Sleep(1000); // 休眠 1秒 + } + if (orders.length == 0) { // 如果订单数组为空 + return ret; // 返回撤单状态 + } + for (var j = 0; j < orders.length; j++) { // 遍历未成交订单数组 + exchange.CancelOrder(orders[j].Id); // 依次取消未成交订单 + ret = true; + if (j < (orders.length - 1)) { + Sleep(1000); // 休眠 1秒 + } + } + } +} + +// 下单函数 +function onTick() { + var acc = _C(exchange.GetAccount); // 获取账户信息 + var ticker = _C(exchange.GetTicker); // 获取 Tick 数据 + var spread = ticker.Sell - ticker.Buy; // 获取 Tick 数据的买卖价差 + // 账户余额与当前持仓价值的差值的 0.5倍 + var diffAsset = (acc.Balance - (acc.Stocks * ticker.Sell)) / 2; + var ratio = diffAsset / acc.Balance; // diffAsset / 账户余额 + LogStatus('ratio:', ratio, _D()); // 打印 ratio和当前时间 + if (Math.abs(ratio) < threshold) { // 如果 ratio的绝对值小于指定阈值 + return false; // 返回 false + } + if (ratio > 0) { // 如果 ratio大于 0 + var buyPrice = _N(ticker.Sell + spread, ZPrecision); // 计算下单价格 + var buyAmount = _N(diffAsset / buyPrice, XPrecision); // 计算下单量 + if (buyAmount < MinStock) { // 如果下单量小于最小交易量 + return false; // 返回 false + } + exchange.Buy(buyPrice, buyAmount, diffAsset, ratio); // 买入下单 + } else { + var sellPrice = _N(ticker.Buy - spread, ZPrecision); // 计算下单价格 + var sellAmount = _N(-diffAsset / sellPrice, XPrecision); // 计算下单量 + if (sellAmount < MinStock) { // 如果下单量小于最小交易量 + return false; // 返回 false + } + exchange.Sell(sellPrice, sellAmount, diffAsset, ratio); // 卖出下单 + } + return true; // 返回 true +} + +// 主函数 +function main() { + // 过滤非重要信息 + SetErrorFilter("GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout"); + while (true) { // 轮询模式 + if (onTick()) { // 执行 onTick 函数 + CancelPendingOrders(); // 取消未成交的挂单 + Log(_C(exchange.GetAccount)); // 打印当前账户信息 + } + Sleep(LoopInterval * 1000); // 休眠 + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/164257 + +> 更新时间 + +2019-08-29 23:09:54 diff --git "a/\351\251\254\344\270\201\346\240\274\345\260\224\347\275\221\346\240\274btc.md" "b/\351\251\254\344\270\201\346\240\274\345\260\224\347\275\221\346\240\274btc.md" new file mode 100644 index 00000000..0f21fc6a --- /dev/null +++ "b/\351\251\254\344\270\201\346\240\274\345\260\224\347\275\221\346\240\274btc.md" @@ -0,0 +1,462 @@ + +> 策略名称 + +马丁格尔网格btc + +> 策略作者 + +威尔士发 + +> 策略描述 + +改自 单点狙击高频加仓自动反手解套算法 V1.2 但是不反手,可以单方向做,加了止损. 效果很好, 识货的拿走,看源码. 不多说了. + +回测时资金设置在10万以上, 币设置在30以上, 这样才能达到理想效果, 资金越大, 策略抗波动能力越强 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|OpType|0|开仓方向: 做多|做空| +|OpAmount|0.1|开仓数量| +|OpMode|0|开仓方式: 吃单|挂单| +|MaxSpace|0.5|挂单失效距离| +|SlidePrice|0.1|下单滑动价(元)| +|MaxAmount|0.3|开仓最大单次下单量| +|AddGoal|true|加仓间距(元)| +|AddLine|0.8|加仓均价目标(元)| +|ProfitGoal|0.5|平仓目标(元)| +|Interval|true|轮询间隔(秒)| +|RestoreIt|false|恢复进度| +|RestoreType|0|持仓方向: 做多|做空| +|RestorePrice|false|持仓均价| +|RestoreAmount|false|持仓数量| +|RestoreProfit|false|上次盈利| +|SaveLocal|false|保存本地日志| +|StopLoss|8|止损(元)| +|MinStock|0.01|最小交易币数| + + +> 源码 (javascript) + +``` javascript +var TradeType = null; +var OrgAccount = null; +var Counter = {s : 0, f: 0, m: 0}; +var LastProfit = 0; +var AllProfit = 0; +var LastTicker = null; +var maxHold = 0; + +function _N(v, precision) { + if (typeof(precision) != 'number') { + precision = 4; + } + var d = parseFloat(v.toFixed(Math.max(10, precision+5))); + s = d.toString().split("."); + if (s.length < 2 || s[1].length <= precision) { + return d; + } + + var b = Math.pow(10, precision); + return Math.floor(d*b)/b; +} + +function EnsureCall(e, method) { + var r; + while (!(r = e[method].apply(this, Array.prototype.slice.call(arguments).slice(2)))) { + Sleep(Interval); + } + return r; +} + +function StripOrders(e, orderId) { + var order = null; + if (typeof(orderId) == 'undefined') { + orderId = null; + } + while (true) { + var dropped = 0; + var orders = EnsureCall(e, 'GetOrders'); + for (var i = 0; i < orders.length; i++) { + if (orders[i].Id == orderId) { + order = orders[i]; + } else { + var extra = ""; + if (orders[i].DealAmount > 0) { + extra = "成交: " + orders[i].DealAmount; + } else { + extra = "未成交"; + } + e.CancelOrder(orders[i].Id, orders[i].Type == ORDER_TYPE_BUY ? "买单" : "卖单", extra); + dropped++; + } + } + if (dropped == 0) { + break; + } + Sleep(300); + } + return order; +} + +function updateProfit(e, account, ticker) { + if (typeof(account) == 'undefined') { + account = GetAccount(e); + } + if (typeof(ticker) == 'undefined') { + ticker = EnsureCall(e, "GetTicker"); + } + var profit = _N(LastProfit + (((account.Stocks + account.FrozenStocks) - (OrgAccount.Stocks + OrgAccount.FrozenStocks)) * ticker.Last) + ((account.Balance + account.FrozenBalance) - (OrgAccount.Balance + OrgAccount.FrozenBalance)), 4); + LogProfit(profit, "币数:", _N(account.Stocks + account.FrozenStocks, 4), "钱数:", _N(account.Balance + account.FrozenBalance, 4)); + return profit; +} + + +var preMsg = ""; +function GetAccount(e, waitFrozen) { + if (typeof(waitFrozen) == 'undefined') { + waitFrozen = false; + } + var account = null; + var alreadyAlert = false; + while (true) { + account = EnsureCall(e, "GetAccount"); + if (!waitFrozen || (account.FrozenStocks < MinStock && account.FrozenBalance < 0.01)) { + break; + } + if (!alreadyAlert) { + alreadyAlert = true; + Log("发现账户有冻结的钱或币", account); + } + Sleep(Interval); + } + // TODO Hack + msg = "成功: " + Counter.s + " 次, 解套: " + Counter.f + " 次, 止损: " + Counter.m + " 次, 最大持仓量: " + _N(maxHold); + //msg = Counter.s + " / " + Counter.f + " / " + Counter.m; + + if (LastTicker != null && OrgAccount != null) { + var profit = (((account.Stocks + account.FrozenStocks) - (OrgAccount.Stocks + OrgAccount.FrozenStocks)) * LastTicker.Last) + ((account.Balance + account.FrozenBalance) - (OrgAccount.Balance + OrgAccount.FrozenBalance)); + msg += "\n盈亏: " + AllProfit + ", 浮动: " + _N(profit, 4); + msg += "\n初始账户 钱: " + OrgAccount.Balance + " 币: " + OrgAccount.Stocks + ", 当前账户 钱: " + _N(account.Balance + account.FrozenBalance) + " 币: " + _N(account.Stocks + account.FrozenStocks); + } + + if (msg != preMsg) { + preMsg = msg; + LogStatus(msg, "#ff0000"); + } + return account; +} + +// mode = 0 : direct buy, 1 : buy as buy1 +function Trade(e, tradeType, tradeAmount, mode, slidePrice, maxAmount, maxSpace, retryDelay) { + var initAccount = GetAccount(e, true); + var nowAccount = initAccount; + var orderId = null; + var prePrice = 0; + var dealAmount = 0; + var diffMoney = 0; + var isFirst = true; + var tradeFunc = tradeType == ORDER_TYPE_BUY ? e.Buy : e.Sell; + var isBuy = tradeType == ORDER_TYPE_BUY; + while (true) { + var ticker = EnsureCall(e, 'GetTicker'); + LastTicker = ticker; + var tradePrice = 0; + if (isBuy) { + tradePrice = _N((mode == 0 ? ticker.Sell : ticker.Buy) + slidePrice, 4); + } else { + tradePrice = _N((mode == 0 ? ticker.Buy : ticker.Sell) - slidePrice, 4); + } + if (orderId == null) { + if (isFirst) { + isFirst = false; + } else { + nowAccount = GetAccount(e, true); + } + var doAmount = 0; + if (isBuy) { + diffMoney = _N(initAccount.Balance - nowAccount.Balance, 4); + dealAmount = _N(nowAccount.Stocks - initAccount.Stocks, 4); + doAmount = Math.min(maxAmount, tradeAmount - dealAmount, _N((nowAccount.Balance-10) / tradePrice, 4)); + } else { + diffMoney = _N(nowAccount.Balance - initAccount.Balance, 4); + dealAmount = _N(initAccount.Stocks - nowAccount.Stocks, 4); + doAmount = Math.min(maxAmount, tradeAmount - dealAmount, nowAccount.Stocks); + } + if (doAmount < MinStock) { + break; + } + prePrice = tradePrice; + orderId = tradeFunc(tradePrice, doAmount); + } else { + if (Math.abs(tradePrice - prePrice) > maxSpace) { + orderId = null; + } + var order = StripOrders(exchange, orderId); + if (order == null) { + orderId = null; + } + } + Sleep(retryDelay); + } + + if (dealAmount <= 0) { + return null; + } + + return {price: _N(diffMoney / dealAmount, 4), amount: dealAmount}; +} + +function loop(isFirst) { + var minStock = MinStock; + var initAccount = GetAccount(exchange, true); + Log(initAccount); + var holdPrice = 0; + var holdAmount = 0; + if (RestoreIt && isFirst) { + LastProfit = RestoreProfit; + TradeType = RestoreType == 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; + holdPrice = RestorePrice; + holdAmount = RestoreAmount; + if (holdAmount != 0) { + initAccount = { + Stocks: initAccount.Stocks, + FrozenStocks: initAccount.FrozenStocks, + Balance: initAccount.Balance, + FrozenBalance: initAccount.FrozenBalance, + }; + if (RestoreType == 0) { + initAccount.Stocks -= holdAmount; + initAccount.Balance += (holdPrice * holdAmount); + } else { + initAccount.Stocks += holdAmount; + initAccount.Balance -= (holdPrice * holdAmount); + } + OrgAccount = initAccount; + Log("恢复持仓状态为:", RestoreType == 0 ? "做多" : "做空", "均价:", holdPrice, "数量:", holdAmount); + if (RestoreType == 0) { + holdAmount = Math.min(initAccount.Stocks, holdAmount); + } + } + if (LastProfit != 0) { + LogProfit(LastProfit, "恢复上次盈利"); + } + } + if (holdAmount == 0) { + var obj = Trade(exchange, TradeType, OpAmount, OpMode, SlidePrice, MaxAmount, MaxSpace, Interval); + if (!obj) { + throw "出师不利, 开仓失败"; + } else { + Log(TradeType == ORDER_TYPE_BUY ? "开多仓完成" : "开空仓完成", "均价:", obj.price, "数量:", obj.amount); + } + Log(GetAccount(exchange, true)); + holdPrice = obj.price; + holdAmount = obj.amount; + } + var openFunc = TradeType == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell; + var coverFunc = TradeType == ORDER_TYPE_BUY ? exchange.Sell : exchange.Buy; + var isFinished = false; + while (!isFinished) { + var account = GetAccount(exchange, true); + var openAmount = 0; + var openPrice = 0; + var coverPrice = 0; + var canOpen = true; + + if (TradeType == ORDER_TYPE_BUY) { + var upLine = AddLine; + openPrice = _N(holdPrice - AddGoal, 4); + openAmount = _N((holdAmount * (holdPrice - openPrice - upLine)) / upLine, 4); + coverPrice = _N(holdPrice + ProfitGoal, 4); + if (_N(account.Balance / openPrice, 4) < openAmount) { + Log("没有钱加多仓, 需要加仓: ", openAmount, "个"); + canOpen = false; + } + } else { + var upLine = -AddLine; + openPrice = _N(holdPrice + AddGoal, 4); + coverPrice = _N(holdPrice - ProfitGoal, 4); + openAmount = _N((holdAmount * (holdPrice - openPrice - upLine) / upLine), 4); + if (account.Stocks < openAmount) { + Log("没有币加空仓, 需要币:", openAmount); + canOpen = false; + } + } + if (holdAmount < minStock) { + Log("剩余币数过小, 放弃操作", holdAmount); + return 0; + } + openAmount = Math.max(minStock, openAmount); + + var order_count = 0; + var openId = null; + var coverId = null; + if (!canOpen) { + openId = -1; + Log("进入等待解套模式"); + } + + for (var i = 0; i < 10; i++) { + if (!openId) { + openId = openFunc(openPrice, openAmount); + } + if (!coverId) { + coverId = coverFunc(coverPrice, holdAmount); + } + if (openId && coverId) { + break; + } + Sleep(Interval); + } + if (!openId || !coverId) { + StripOrders(exchange); + throw "下单失败"; + } + if (openId > 0) { + order_count++; + } + if (coverId > 0) { + order_count++; + } + + var preAccount = account; + var loss = null; + while (true) { + Sleep(Interval); + var ticker = EnsureCall(exchange, "GetTicker"); + LastTicker = ticker; + var floatProfit = Math.abs(ticker.Last - coverPrice) * holdAmount; + var balance = false; + if (loss === null) { + loss = floatProfit; + } else if (floatProfit - loss > StopLoss) { + Log("当前浮动盈亏:", floatProfit, "开始止损"); + StripOrders(exchange); + balance = true; + } + var orders = EnsureCall(exchange, "GetOrders"); + var nowAccount = GetAccount(exchange); + var diff = nowAccount.Stocks + nowAccount.FrozenStocks - preAccount.Stocks; + if (balance) { + diff = nowAccount.Stocks + nowAccount.FrozenStocks - OrgAccount.Stocks; + if (Math.abs(diff) > minStock) { + var obj = Trade(exchange, diff > 0 ? ORDER_TYPE_SELL : ORDER_TYPE_BUY, Math.abs(diff), 0, SlidePrice, MaxAmount, MaxSpace, Interval); + if (!obj) { + throw "止损失败"; + } else { + Log(TradeType == ORDER_TYPE_BUY ? "平空仓完成" : "平多仓完成", "均价:", obj.price, "数量:", obj.amount); + } + } + nowAccount = GetAccount(exchange); + AllProfit = updateProfit(exchange, GetAccount(exchange), ticker); + initAccount = nowAccount; + isFinished = true; + Counter.m++; + break; + } + + if (orders.length != order_count || Math.abs(diff) >= minStock) { + StripOrders(exchange); + nowAccount = GetAccount(exchange, true); + //Log(nowAccount); + var diffAmount = nowAccount.Stocks - initAccount.Stocks; + var diffMoney = nowAccount.Balance - initAccount.Balance; + if (Math.abs(diffAmount) < minStock) { + AllProfit = updateProfit(exchange, nowAccount, ticker); + Log("平仓完成, 达到目标盈利点, 单次盈利", _N(holdAmount * ProfitGoal, 4)); + initAccount = nowAccount; + isFinished = true; + if (!canOpen) { + Counter.f++; + } + break; + } + var newHoldPrice = 0; + var newHoldAmount = 0; + if (TradeType == ORDER_TYPE_BUY) { + newHoldAmount = _N(diffAmount, 4); + newHoldPrice = _N((-diffMoney) / diffAmount, 4); + } else { + newHoldAmount = _N(-diffAmount, 4); + newHoldPrice = _N(diffMoney / (-diffAmount), 4); + } + // if open again, we need adjust hold positions's price + var isAdd = false; + if (newHoldAmount > holdAmount) { + holdPrice = newHoldPrice; + isAdd = true; + } + holdAmount = newHoldAmount; + maxHold = Math.max(holdAmount, maxHold); + if (!isAdd) { + // reset initAccount + initAccount = { + Stocks : nowAccount.Stocks, + Balance : nowAccount.Balance, + FrozenBalance : nowAccount.FrozenBalance, + FrozenStocks : nowAccount.FrozenStocks, + }; + if (TradeType == ORDER_TYPE_BUY) { + initAccount.Stocks -= holdAmount; + initAccount.Balance += holdAmount * holdPrice; + } else { + initAccount.Stocks += holdAmount; + initAccount.Balance -= holdAmount * holdPrice; + } + initAccount.Stocks = _N(initAccount.Stocks, 4); + initAccount.Balance = _N(initAccount.Balance, 4); + Log("持仓前账户调整为: ", initAccount); + } + Log((TradeType == ORDER_TYPE_BUY ? "多仓" : "空仓"), (isAdd ? "加仓后" : "平仓后"), "重新调整持仓, 均价: ", holdPrice, "数量", holdAmount); + Log("买一:", ticker.Buy, "卖一:", ticker.Sell, "上次成交价:", ticker.Last); + Log(nowAccount); + break; + } + } + } + return 0; +} + +function onexit() { + StripOrders(exchange); + Log("Exit"); +} + +function main() { + if (AddLine > AddGoal || AddLine <= 0) { + throw "加仓均价目标错误"; + } + if (exchange.GetName().indexOf("Future") != -1) { + throw "只支持现货, 期货容易爆仓, 暂不支持"; + } + if (exchange.GetRate() != 1) { + Log("已禁用汇率转换"); + exchange.SetRate(1); + } + TradeType = OpType == 0 ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; + EnableLogLocal(SaveLocal); + Interval *= 1000; + SetErrorFilter("502:|503:|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF"); + StripOrders(exchange); + OrgAccount = GetAccount(exchange); + var isFirst = true; + LogStatus("启动成功", TradeType); + while (true) { + var ret = loop(isFirst); + isFirst = false; + Counter.s++; + Sleep(Interval); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/164255 + +> 更新时间 + +2019-08-29 23:08:39 From 87b9aa63c0d3a348ac04ea2262255245d1262683 Mon Sep 17 00:00:00 2001 From: Zero Date: Sat, 7 Mar 2020 20:45:53 +0800 Subject: [PATCH 17/19] update --- ...10\346\225\231\345\255\246\357\274\211.md" | 113 +++++ ...10\346\225\231\345\255\246\357\274\211.md" | 74 ++++ ...01\347\240\264\347\255\226\347\225\245.md" | 120 ++++++ ...\347\225\245OKEX Websocket\347\211\210.md" | 5 +- ...350\264\247 (\346\225\231\345\255\246).md" | 9 +- ...71\347\272\263\351\200\232\351\201\223.md" | 45 ++ ...tc\345\220\210\347\272\246\347\211\210.md" | 169 ++++++++ ...73\345\233\276\350\214\203\344\276\213.md" | 5 +- ...350\257\225for\346\226\260\346\211\213.md" | 4 +- ...73\345\233\276\350\214\203\344\276\213.md" | 101 +++++ ...346\211\230 - \344\271\260\345\205\245.md" | 106 +++++ ...346\211\230 - \345\215\226\345\207\272.md" | 106 +++++ ...10\346\225\231\345\255\246\357\274\211.md" | 98 +++++ ...10\346\225\231\345\255\246\357\274\211.md" | 167 ++++++++ README.md | 56 ++- ...46\347\255\226\347\225\245\357\274\211.md" | 146 +++++++ ...22\344\273\266\350\214\203\344\276\213.md" | 110 +++++ ...32\351\222\261\350\265\232\347\237\277.md" | 13 +- ...32\351\201\223\345\217\230\345\275\242.md" | 48 +++ ...346\211\230 - \344\271\260\345\205\245.md" | 5 +- ...346\211\230 - \345\215\226\345\207\272.md" | 5 +- ...31\350\257\257\350\277\275\350\270\252.md" | 85 ++++ ...50\346\234\237\345\245\227\345\210\251.md" | 141 +------ ...63\350\241\241\347\255\226\347\225\245.md" | 103 +---- ...23\346\234\272\345\231\250\344\272\272.md" | 93 +++++ ...44\346\230\223\347\255\226\347\225\245.md" | 109 ++--- ...347\225\245\357\274\210Bar\357\274\211.md" | 143 +++++++ ...7\225\245V2.0_\347\216\260\350\264\247.md" | 248 +++++++++++ ...12\345\256\207\351\207\217\345\214\226.md" | 47 +++ "\346\227\245\345\277\227|Logger.md" | 2 +- ...36\347\233\230\346\225\210\346\236\234.md" | 190 +++++++++ ...44\345\217\211\347\255\226\347\225\245.md" | 70 ++++ ...tc\347\216\260\350\264\247\347\211\210.md" | 132 ++++++ ...61\345\272\246\345\277\253\347\205\247.md" | 38 ++ ...25\350\276\271\347\275\221\346\240\274.md" | 26 +- ...47\226\253\346\203\205|Fetch nCoV News.md" | 70 ++++ ...33\345\233\276\346\212\200\346\234\257.md" | 51 +++ ...0\267\347\253\257|market center client.md" | 388 ++++++++++++++++++ ...55\345\277\203\345\273\266\346\227\266.md" | 81 ++++ ...344\272\206SSL\351\252\214\350\257\201.md" | 348 ++++++++++++++++ 40 files changed, 3526 insertions(+), 344 deletions(-) create mode 100644 "\bPython\347\211\210\345\244\232\345\223\201\347\247\215\350\277\275\346\266\250\346\235\200\350\267\214\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" create mode 100644 "\bPython\347\211\210\350\277\275\346\266\250\346\235\200\350\267\214\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" create mode 100644 "8.12 hans123\346\227\245\345\206\205\347\252\201\347\240\264\347\255\226\347\225\245.md" create mode 100644 "KRT\345\207\257\345\260\224\347\211\271\347\272\263\351\200\232\351\201\223.md" create mode 100644 "MACD\344\272\244\346\230\223\347\255\226\347\225\245btc\345\220\210\347\272\246\347\211\210.md" create mode 100644 "Python\347\211\210MACD\346\214\207\346\240\207\347\224\273\345\233\276\350\214\203\344\276\213.md" create mode 100644 "Python\347\211\210\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.md" create mode 100644 "Python\347\211\210\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.md" create mode 100644 "Python\347\211\210\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" create mode 100644 "Python\347\211\210\347\256\200\345\215\225\347\275\221\346\240\274\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" create mode 100644 "robotCtrl\357\274\210\346\225\231\345\255\246\347\255\226\347\225\245\357\274\211.md" create mode 100644 "\344\272\244\346\230\223\347\273\210\347\253\257\346\217\222\344\273\266\350\214\203\344\276\213.md" create mode 100644 "\345\205\270\345\236\213\344\273\267\346\240\274\347\231\276\345\210\206\346\257\224\351\200\232\351\201\223-\345\207\257\345\260\224\347\211\271\347\272\263\344\270\216\347\231\276\345\210\206\346\257\224\351\200\232\351\201\223\345\217\230\345\275\242.md" create mode 100644 "\345\210\206\344\272\253\346\250\241\346\235\277\345\274\225\347\224\250\351\224\231\350\257\257\350\277\275\350\270\252.md" create mode 100644 "\345\225\206\345\223\201\346\234\237\350\264\247\351\242\204\345\256\232\345\274\200\344\273\223\345\220\216\345\271\263\344\273\223\346\234\272\345\231\250\344\272\272.md" create mode 100644 "\345\237\272\344\272\216\350\265\204\351\207\221\344\270\273\345\212\250\346\200\247\346\265\201\345\220\221\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245\357\274\210Bar\357\274\211.md" create mode 100644 "\345\244\247\344\270\255\345\260\217\344\270\211\345\221\250\346\234\237\350\267\203\350\277\201\347\255\226\347\225\245V2.0_\347\216\260\350\264\247.md" create mode 100644 "\345\256\232\351\207\217\345\210\206\345\236\213\351\200\237\347\216\207\344\272\244\346\230\223\347\255\226\347\225\245-by:\346\263\212\345\256\207\351\207\217\345\214\226.md" create mode 100644 "\346\232\264\351\233\252\347\275\221\346\240\274-7*24\345\260\217\346\227\266\344\272\244\346\230\223\346\234\272\345\231\250\344\272\272\357\274\214\346\257\217\346\227\245\346\233\264\346\226\260\345\256\236\347\233\230\346\225\210\346\236\234.md" create mode 100644 "\346\240\207\345\256\232\345\200\274\346\210\226\345\235\207\347\272\277\344\272\244\345\217\211\347\255\226\347\225\245.md" create mode 100644 "\346\265\267\351\276\237\347\255\226\347\225\245btc\347\216\260\350\264\247\347\211\210.md" create mode 100644 "\346\267\261\345\272\246\345\277\253\347\205\247.md" create mode 100644 "\350\216\267\345\217\226\346\234\200\346\226\260\347\226\253\346\203\205|Fetch nCoV News.md" create mode 100644 "\350\234\241\347\203\233\345\233\276\346\212\200\346\234\257.md" create mode 100644 "\350\241\214\346\203\205\344\270\255\345\277\203\345\256\242\346\210\267\347\253\257|market center client.md" create mode 100644 "\350\241\214\346\203\205\344\270\255\345\277\203\345\273\266\346\227\266.md" create mode 100644 "\351\200\232\347\224\250\345\215\217\350\256\256\357\274\210Python3.X\347\211\210\357\274\211\342\200\224\342\200\224\346\224\271\347\274\226\350\207\252CoinPark\344\272\244\346\230\223\346\211\200\351\200\232\347\224\250\345\215\217\350\256\256 6.27 16:00 \346\233\264\346\226\260 \345\205\263\351\227\255\344\272\206SSL\351\252\214\350\257\201.md" diff --git "a/\bPython\347\211\210\345\244\232\345\223\201\347\247\215\350\277\275\346\266\250\346\235\200\350\267\214\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" "b/\bPython\347\211\210\345\244\232\345\223\201\347\247\215\350\277\275\346\266\250\346\235\200\350\267\214\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" new file mode 100644 index 00000000..e6a917a4 --- /dev/null +++ "b/\bPython\347\211\210\345\244\232\345\223\201\347\247\215\350\277\275\346\266\250\346\235\200\350\267\214\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" @@ -0,0 +1,113 @@ + +> 策略名称 + +Python版多品种追涨杀跌策略(教学) + +> 策略作者 + +小小梦 + +> 策略描述 + +https://www.fmz.com/bbs-topic/4959 + + + +> 源码 (python) + +``` python +'''backtest +start: 2019-02-20 00:00:00 +end: 2020-01-10 00:00:00 +period: 1m +exchanges: [{"eid":"OKEX","currency":"BTC_USDT"},{"eid":"OKEX","currency":"ETH_USDT","stocks":30},{"eid":"OKEX","currency":"LTC_USDT","stocks":100}] +''' + +import time +import json + +params = { + "arrBasePrice": [-1, -1, -1], # -1 + "arrRatio": [0.05, 0.05, 0.05], # 0.05 + "arrAcc": [], # _C(exchange.GetAccount) + "arrLastCancelAll": [0, 0, 0], # 0 + "arrMinStocks": [0.01, 0.01, 0.01], # 0.01 + "arrPricePrecision": [2, 2, 2], # 2 + "arrAmountPrecision": [3, 2, 2], # 2 + "arrTick":[] +} + +def CancelAll(e): + while True : + orders = _C(e.GetOrders) + for i in range(len(orders)) : + e.CancelOrder(orders[i]["Id"], orders[i]) + if len(orders) == 0 : + break + Sleep(1000) + +def process(e, index): + global params + ticker = _C(e.GetTicker) + params["arrTick"][index] = ticker + if params["arrBasePrice"][index] == -1 : + params["arrBasePrice"][index] = ticker.Last + if ticker.Last - params["arrBasePrice"][index] > 0 and (ticker.Last - params["arrBasePrice"][index]) / params["arrBasePrice"][index] > params["arrRatio"][index]: + params["arrAcc"][index] = _C(e.GetAccount) + if params["arrAcc"][index].Balance * params["arrRatio"][index] / ticker.Last > params["arrMinStocks"][index]: + e.Buy(ticker.Last, params["arrAcc"][index].Balance * params["arrRatio"][index] / ticker.Last) + params["arrBasePrice"][index] = ticker.Last + if ticker.Last - params["arrBasePrice"][index] < 0 and (params["arrBasePrice"][index] - ticker.Last) / params["arrBasePrice"][index] > params["arrRatio"][index]: + params["arrAcc"][index] = _C(e.GetAccount) + if params["arrAcc"][index].Stocks * params["arrRatio"][index] > params["arrMinStocks"][index]: + e.Sell(ticker.Last, params["arrAcc"][index].Stocks * params["arrRatio"][index]) + params["arrBasePrice"][index] = ticker.Last + ts = time.time() + if ts - params["arrLastCancelAll"][index] > 60 * 5 : + CancelAll(e) + params["arrLastCancelAll"][index] = ts + +def main(): + global params + + for i in range(len(exchanges)) : + params["arrAcc"].append(_C(exchanges[i].GetAccount)) + params["arrTick"].append(_C(exchanges[i].GetTicker)) + exchanges[i].SetPrecision(params["arrPricePrecision"][i], params["arrAmountPrecision"][i]) + + for key in params : + if len(params[key]) < len(exchanges): + raise "params error!" + + while True: + tblAcc = { + "type" : "table", + "title": "account", + "cols": ["账户信息"], + "rows": [] + } + + tblTick = { + "type" : "table", + "title": "ticker", + "cols": ["行情信息"], + "rows": [] + } + for i in range(len(exchanges)): + process(exchanges[i], i) + + for i in range(len(exchanges)): + tblAcc["rows"].append([json.dumps(params["arrAcc"][i])]) + tblTick["rows"].append([json.dumps(params["arrTick"][i])]) + + LogStatus(_D(), "\n`" + json.dumps([tblAcc, tblTick]) + "`") + Sleep(500) +``` + +> 策略出处 + +https://www.fmz.com/strategy/182268 + +> 更新时间 + +2020-01-20 17:44:33 diff --git "a/\bPython\347\211\210\350\277\275\346\266\250\346\235\200\350\267\214\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" "b/\bPython\347\211\210\350\277\275\346\266\250\346\235\200\350\267\214\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" new file mode 100644 index 00000000..0617e06e --- /dev/null +++ "b/\bPython\347\211\210\350\277\275\346\266\250\346\235\200\350\267\214\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" @@ -0,0 +1,74 @@ + +> 策略名称 + +Python版追涨杀跌策略(教学) + +> 策略作者 + +小小梦 + +> 策略描述 + +https://www.fmz.com/bbs-topic/4908 + + + +> 源码 (python) + +``` python +'''backtest +start: 2019-02-20 00:00:00 +end: 2020-01-10 00:00:00 +period: 1m +exchanges: [{"eid":"OKEX","currency":"BTC_USDT"}] +''' + +import time + +basePrice = -1 +ratio = 0.05 +acc = _C(exchange.GetAccount) +lastCancelAll = 0 +minStocks = 0.01 + +def CancelAll(): + while True : + orders = _C(exchange.GetOrders) + for i in range(len(orders)) : + exchange.CancelOrder(orders[i]["Id"], orders[i]) + if len(orders) == 0 : + break + Sleep(1000) + +def main(): + global basePrice, acc, lastCancelAll + exchange.SetPrecision(2, 3) + while True: + ticker = _C(exchange.GetTicker) + if basePrice == -1 : + basePrice = ticker.Last + if ticker.Last - basePrice > 0 and (ticker.Last - basePrice) / basePrice > ratio : + acc = _C(exchange.GetAccount) + if acc.Balance * ratio / ticker.Last > minStocks : + exchange.Buy(ticker.Last, acc.Balance * ratio / ticker.Last) + basePrice = ticker.Last + if ticker.Last - basePrice < 0 and (basePrice - ticker.Last) / basePrice > ratio : + acc = _C(exchange.GetAccount) + if acc.Stocks * ratio > minStocks : + exchange.Sell(ticker.Last, acc.Stocks * ratio) + basePrice = ticker.Last + ts = time.time() + if ts - lastCancelAll > 60 * 5 : + CancelAll() + lastCancelAll = ts + LogStatus(_D(), "\n", "行情信息:", ticker, "\n", "账户信息:", acc) + Sleep(500) +``` + +> 策略出处 + +https://www.fmz.com/strategy/181185 + +> 更新时间 + +2020-01-11 15:15:01 diff --git "a/8.12 hans123\346\227\245\345\206\205\347\252\201\347\240\264\347\255\226\347\225\245.md" "b/8.12 hans123\346\227\245\345\206\205\347\252\201\347\240\264\347\255\226\347\225\245.md" new file mode 100644 index 00000000..7bc6a3f1 --- /dev/null +++ "b/8.12 hans123\346\227\245\345\206\205\347\252\201\347\240\264\347\255\226\347\225\245.md" @@ -0,0 +1,120 @@ + +> 策略名称 + +8.12 hans123日内突破策略 + +> 策略作者 + +Hukybo + +> 策略描述 + +#### 前言 +HANS123策略最早主要应用于外汇市场,其交易方式比较简单,属于趋势突破系统,这种交易方式可以在趋势形成的第一时间入场,因此得到很多交易员的青睐,迄今为止HANS123已经扩展了许多版本,今天我们就一起来认识HANS123策略。 +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4878) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|count|50|count| +|stop|100|stop| + + +> 源码 (python) + +``` python +# 回测配置 +'''backtest +start: 2019-01-01 00:00:00 +end: 2020-01-01 00:00:00 +period: 1m +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +''' + + +# 全局函数 +up_line = 0 # 上轨 +down_line = 0 # 下轨 +trade_count = 0 # 当天交易次数 + + +# 策略主函数 +def onTick(): + # 获取数据 + exchange.SetContractType("rb888") # 订阅期货品种 + bar_arr = _C(exchange.GetRecords, PERIOD_M1) # 获取1分钟K线数组 + current_close = bar_arr[-1]['Close'] # 获取最新价格 + if len(bar_arr) < 50: # 如果小于50根K线 + return # 返回继续等待数据 + + # 处理时间函数 + def current_time(): + current_time = bar_arr[-1]['Time'] # 获取当前K线时间戳 + time_local = time.localtime(current_time / 1000) # 处理时间戳 + hour = time.strftime("%H", time_local) # 格式化时间戳,并获取小时 + minute = time.strftime("%M", time_local) # 格式化时间戳,并获取分钟 + if len(minute) == 1: + minute = "0" + minute + return int(hour + minute) + + # 计算上下轨 + global up_line, down_line, trade_count # 引入全局变量 + current_time = current_time() # 处理时间 + if current_time == 930: # 如果最新的K线时间是09:30 + up_line = TA.Highest(bar_arr, 30, 'High') + count # 前30根K线最高价 + down_line = TA.Lowest(bar_arr, 30, 'Low') - count # 前30根K线最低价 + trade_count = 0 # 重置交易次数为0 + + # 获取持仓 + position_arr = _C(exchange.GetPosition) # 获取持仓数组 + if len(position_arr) > 0: # 如果持仓数组长度大于0 + position_arr = position_arr[0] # 获取持仓字典数据 + if position_arr['ContractType'] == 'rb888': # 如果持仓品种等于订阅品种 + if position_arr['Type'] % 2 == 0: # 如果是多单 + position = position_arr['Amount'] # 赋值持仓数量为正数 + else: + position = -position_arr['Amount'] # 赋值持仓数量为负数 + profit = position_arr['Profit'] # 获取持仓盈亏 + else: + position = 0 # 赋值持仓数量为0 + profit = 0 # 赋值持仓盈亏为0 + + # 下单交易 + # 如果临近收盘或者达到止盈止损 + if current_time > 1450 or profit > stop * 3 or profit < -stop: + if position > 0: # 如果持多单 + exchange.SetDirection("closebuy") # 设置交易方向和类型 + exchange.Sell(current_close - 1, 1) # 平多单 + elif position < 0: # 如果持空单 + exchange.SetDirection("closesell") # 设置交易方向和类型 + exchange.Buy(current_close + 1, 1) # 平空单 + # 如果当前无持仓,并且小于指定交易次数,并且在指定交易时间内 + if position == 0 and trade_count < 2 and 930 < current_time < 1450: + if current_close > up_line: # 如果价格大于上轨 + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(current_close + 1, 1) # 开多单 + trade_count = trade_count + 1 # 交易次数加一次 + elif current_close < down_line: # 如果价格小于下轨 + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(current_close - 1, 1) # 开空单 + trade_count = trade_count + 1 # 交易次数加一次 + + +# 策略入口函数 +def main(): + while True: # 无限循环 + onTick() # 执行策略主函数 + Sleep(1000) #休眠1秒 + +``` + +> 策略出处 + +https://www.fmz.com/strategy/179805 + +> 更新时间 + +2020-01-17 15:00:03 diff --git "a/C++\346\234\237\350\264\247\351\253\230\351\242\221\345\245\227\345\270\201\347\255\226\347\225\245OKEX Websocket\347\211\210.md" "b/C++\346\234\237\350\264\247\351\253\230\351\242\221\345\245\227\345\270\201\347\255\226\347\225\245OKEX Websocket\347\211\210.md" index 583d13c1..a8b613e5 100644 --- "a/C++\346\234\237\350\264\247\351\253\230\351\242\221\345\245\227\345\270\201\347\255\226\347\225\245OKEX Websocket\347\211\210.md" +++ "b/C++\346\234\237\350\264\247\351\253\230\351\242\221\345\245\227\345\270\201\347\255\226\347\225\245OKEX Websocket\347\211\210.md" @@ -604,7 +604,8 @@ void main() { string qs = urlencode(json({{"op", "subscribe"}, {"args", {"futures/depth5:" + realSymbolA, "futures/depth5:" + realSymbolB}}}).dump()); Log("try connect to websocket"); - auto ws = Dial("wss://real.okex.com:10442/ws/v3|compress=gzip_raw&mode=recv&reconnect=true&payload="+qs); + // wss://real.OKEx.com:8443/ws/v3 + auto ws = Dial("wss://real.okex.com:8443/ws/v3|compress=gzip_raw&mode=recv&reconnect=true&payload="+qs); Log("connect to websocket success"); Depth depthA, depthB; @@ -667,4 +668,4 @@ https://www.fmz.com/strategy/163447 > 更新时间 -2019-09-10 17:58:50 +2020-02-28 17:12:06 diff --git "a/Dual Thrust OKEX\346\234\237\350\264\247 (\346\225\231\345\255\246).md" "b/Dual Thrust OKEX\346\234\237\350\264\247 (\346\225\231\345\255\246).md" index 4f5bde42..e5028c5a 100644 --- "a/Dual Thrust OKEX\346\234\237\350\264\247 (\346\225\231\345\255\246).md" +++ "b/Dual Thrust OKEX\346\234\237\350\264\247 (\346\225\231\345\255\246).md" @@ -15,13 +15,6 @@ Dual Thrust OKEX期货 (教学) - 在第二天开盘,记录开盘价,然后在价格超过(开盘+触发值)时马上买入,或者价格低于(开盘-触发值)时马上卖空。 - 这个系统是反转系统,没有单独止损。也就是说,反向信号也同时就是平仓信号。 -> 图解 - - https://dn-filebox.qbox.me/ab06814528c0ae8c54c6bebaea4438325968fbe5.jpg - -`Dual Thrust 策略包含完整的图表显示, 图表动态更新,模板引用等功能, 可做学习模板使用.` - -策略的详细介绍 : http://xueqiu.com/5256769224/32429363 > 策略参数 @@ -163,4 +156,4 @@ https://www.fmz.com/strategy/112425 > 更新时间 -2018-08-25 16:39:50 +2020-02-24 09:56:09 diff --git "a/KRT\345\207\257\345\260\224\347\211\271\347\272\263\351\200\232\351\201\223.md" "b/KRT\345\207\257\345\260\224\347\211\271\347\272\263\351\200\232\351\201\223.md" new file mode 100644 index 00000000..c691ae3e --- /dev/null +++ "b/KRT\345\207\257\345\260\224\347\211\271\347\272\263\351\200\232\351\201\223.md" @@ -0,0 +1,45 @@ + +> 策略名称 + +KRT凯尔特纳通道 + +> 策略作者 + +cyberking + +> 策略描述 + +ZF:=H-C; //振幅 +DX:=H+L+C)/3; //典型价格 +KRTHR^^EMA(DX,10)+EMA(ZF,10); //凯尔特纳上轨 +KRTXR^^EMA(DX,10)-EMA(ZF,10); //凯尔特纳下轨 + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2019-02-04 00:00:00 +end: 2020-03-04 00:00:00 +period: 1d +exchanges: [{"eid":"Huobi","currency":"BTC_USDT"}] +*) + + +ZF:=H-C; //振幅 +DX:=H+L+C)/3; //典型价格 +KRTHR^^EMA(DX,10)+EMA(ZF,10); //凯尔特纳上轨 +KRTXR^^EMA(DX,10)-EMA(ZF,10); //凯尔特纳下轨 +C>KRTHR,BPK; +C 策略出处 + +https://www.fmz.com/strategy/188499 + +> 更新时间 + +2020-03-05 11:41:52 diff --git "a/MACD\344\272\244\346\230\223\347\255\226\347\225\245btc\345\220\210\347\272\246\347\211\210.md" "b/MACD\344\272\244\346\230\223\347\255\226\347\225\245btc\345\220\210\347\272\246\347\211\210.md" new file mode 100644 index 00000000..bb2a3781 --- /dev/null +++ "b/MACD\344\272\244\346\230\223\347\255\226\347\225\245btc\345\220\210\347\272\246\347\211\210.md" @@ -0,0 +1,169 @@ + +> 策略名称 + +MACD交易策略btc合约版 + +> 策略作者 + +groot + +> 策略描述 + +一个简单的macd策略 +周期四小时 +金叉做多 +死叉做空 +杠杆均为一倍 +因为是反向系统,不带止损 +回测了下两年数据,币本位年化130%,最大回撤30% + +另外回测了另一种macd策略 +水上做多 +水下做空 +杠杆均一倍,也不带止损 +回测了两年数据,币本位才30%,回撤15%左右。 + +所以可以得出,金叉死叉的指标有效性要高很多; +其实从逻辑上来讲也容易理解,金叉反应的是快线拐头向上,代表的是一种趋势方向,水上反应的只是当前时间点的差值,并不能很好反应方向; +如果用快线的窗口差值当做一个指标,比如当前快线和上个快线的差值大于某个阀值就做多,那也能达到跟金叉同样的效果;只是如果阀值设置不合理,有可能在震荡行情中,会频繁产生无效交易信号。 + +另外,周期分别回测了小时线、四小时线、日线,指标有效性排序:日线>四小时线>小时线;其实也很好理解,金叉死叉属于趋势策略,周期越长有效性越高。 + +关于macd的第三个参数,移动平均周期,默认设置的9,改成10效果会更好,该值越大,快线慢线的间隔越大,也就越能避免震荡行情频繁产生无效交易信号,不过太大的话,进入趋势行情的时间就晚了。 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|short|12|short| +|long|26|long| +|m|10|m| +|threshold|5|threshold| +|fresh_rete|4|交易频率(小时)| + + +> 源码 (python) + +``` python +# 回测配置 +'''backtest +start: 2018-01-01 00:00:00 +end: 2020-03-01 00:00:00 +period: 1d +exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD","stocks":1}] +''' + +mp = 0 # 定义一个全局变量,用于控制虚拟持仓 +counts = 0 # 定义一个全局变量,用于控制开单张数 + + +# 判断两根两个数组是否金叉 +def is_up_cross(arr1, arr2): + if arr1[-2] < arr2[-2] and arr1[-1] > arr2[-1]: + return True + +# 判断两根两个数组是否死叉 +def is_down_cross(arr1, arr2): + if arr1[-2] > arr2[-2] and arr1[-1] < arr2[-1]: + return True + +# 判断水上 +def is_up(arr1): + if arr1[-1] > threshold: + return True + +# 判断水下 +def is_down(arr1): + if arr1[-1] < -threshold: + return True + + +# 程序主函数 +def onTick(): + exchange.SetContractType("quarter") + #金本位合约 + #exchange.IO("currency", "BTC_USDT") + bar_arr = exchange.GetRecords(fresh_rete*60*60) # 获取4小时的K线数组 + #if _D(bar_arr[-1]['Time']/1000) < '2020-01-05 00:00:00': + # Log("bar_arr",len(bar_arr)) + if len(bar_arr) < long + m + 1: # 如果K线数组长度太小,就不能计算MACD,所以直接返回跳过 + return + all_macd = TA.MACD(bar_arr, short, long, m) # 计算MACD值,返回的是一个二维数组 + dif = all_macd[0] # 获取DIF的值,返回一个数组 + dif.pop() # 删除DIF数组最后一个元素,因为最后一跟k线还未形成 + dea = all_macd[1] # 获取DEA的值,返回一个数组 + dea.pop() # 删除DEA数组最后一个元素,因为最后一跟k线还未形成 + last_close = bar_arr[-1]['Close'] # 获取最新价格(卖价),用于开平仓 + global mp # 全局变量,用于控制虚拟持仓 + global counts # 全局变量,用于记录上次开单张数 + + + + #杠杆倍数 + acct = exchange.GetAccount() + portfolio_value = (acct.Stocks+acct.FrozenStocks)*last_close + counts_tmp = int(portfolio_value/100) + + #开仓 + if mp == 0 : + #多单 + if is_up_cross(dif, dea): + #if is_up(dif): + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(last_close + 10, counts_tmp) # 开多单 + counts = counts_tmp + Log("bar_arr",bar_arr[-1],"dif",dif[-1],"dea",dea[-1]) + mp = 1 # 设置虚拟持仓的值,即有多单 + + #空单 + if is_down_cross(dif, dea): + #if is_down(dif): + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(last_close - 10, counts_tmp) # 开空单 + counts = counts_tmp + Log("bar_arr",bar_arr[-1],"dif",dif[-1],"dea",dea[-1]) + mp = -1 # 设置虚拟持仓的值,即有空单 + + #平多开空 + if mp == 1 and is_down_cross(dif, dea): + #if mp == 1 and is_down(dif,): + exchange.SetDirection("closebuy") # 设置交易方向和类型 + exchange.Sell(last_close - 10, counts) # 平多单 + + exchange.SetDirection("sell") # 设置交易方向和类型 + exchange.Sell(last_close - 10, counts_tmp) # 开空单 + counts = counts_tmp + Log("bar_arr",bar_arr[-1],"dif",dif[-1],"dea",dea[-1]) + mp = -1 + + # 平空开多 + if mp == -1 and is_up_cross(dif, dea): + #if mp == -1 and is_up(dif): + exchange.SetDirection("closesell") # 设置交易方向和类型 + exchange.Buy(last_close + 10, counts) # 平空单 + + exchange.SetDirection("buy") # 设置交易方向和类型 + exchange.Buy(last_close + 10, counts_tmp) # 开多单 + counts = counts_tmp + Log("bar_arr",bar_arr[-1],"dif",dif[-1],"dea",dea[-1]) + mp = 1 + + + +def main(): + while True: + onTick() + Sleep(fresh_rete*60*60*1000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/188100 + +> 更新时间 + +2020-03-06 12:01:46 diff --git "a/MACD\347\224\273\345\233\276\350\214\203\344\276\213.md" "b/MACD\347\224\273\345\233\276\350\214\203\344\276\213.md" index 7d15b742..9289dec1 100644 --- "a/MACD\347\224\273\345\233\276\350\214\203\344\276\213.md" +++ "b/MACD\347\224\273\345\233\276\350\214\203\344\276\213.md" @@ -24,9 +24,6 @@ exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}] var preTime = 0; var ChartObj = null; function main(){ - // 测试 - Log(aa.Last) // 测试 - LogReset(1); ChartObj = Chart(null); ChartObj.reset(); @@ -106,4 +103,4 @@ https://www.fmz.com/strategy/151972 > 更新时间 -2019-08-23 10:36:33 +2020-02-27 14:09:37 diff --git "a/OKex\346\234\237\350\264\247\346\265\213\350\257\225for\346\226\260\346\211\213.md" "b/OKex\346\234\237\350\264\247\346\265\213\350\257\225for\346\226\260\346\211\213.md" index b76c27c8..a53d1795 100644 --- "a/OKex\346\234\237\350\264\247\346\265\213\350\257\225for\346\226\260\346\211\213.md" +++ "b/OKex\346\234\237\350\264\247\346\265\213\350\257\225for\346\226\260\346\211\213.md" @@ -82,7 +82,7 @@ function oper(){ Log(account); Log("公允价格",midLine,"高点",mhigh,"低点",mlow); Log("刚下订单的信息,ID:", order.Id, "Price:", order.Price, "Amount:", order.Amount, - "DealAmount:", order.DealAmount, "type:", order.Type); + "account.Stocks:", account.Stocks, "type:", order.Type); } exchange.SetDirection("buy"); @@ -146,4 +146,4 @@ https://www.fmz.com/strategy/170842 > 更新时间 -2019-11-14 17:03:33 +2020-02-20 19:45:23 diff --git "a/Python\347\211\210MACD\346\214\207\346\240\207\347\224\273\345\233\276\350\214\203\344\276\213.md" "b/Python\347\211\210MACD\346\214\207\346\240\207\347\224\273\345\233\276\350\214\203\344\276\213.md" new file mode 100644 index 00000000..6de2e0f7 --- /dev/null +++ "b/Python\347\211\210MACD\346\214\207\346\240\207\347\224\273\345\233\276\350\214\203\344\276\213.md" @@ -0,0 +1,101 @@ + +> 策略名称 + +Python版MACD指标画图范例 + +> 策略作者 + +小小梦 + + + + + +> 源码 (python) + +``` python +'''backtest +start: 2020-01-28 00:00:00 +end: 2020-02-26 00:00:00 +period: 1d +exchanges: [{"eid":"OKEX","currency":"BTC_USDT"}] +''' + +ChartCfg = { + '__isStock': True, + 'title': { + 'text': 'Python画图' + }, + 'yAxis': [{ + 'title': {'text': 'K线'}, + 'style': {'color': '#4572A7'}, + 'opposite': False + }, { + 'title': {'text': '指标轴'}, + 'opposite': True + }], + 'series': [{ + 'type': 'candlestick', + 'name': '当前周期', + 'id': 'primary', + 'data': [] + }, { + 'type': 'line', + 'id': 'dif', + 'name': 'DIF', + "yAxis" : 1, + 'data': [] + }, { + 'type': 'line', + 'id': 'dea', + 'name': 'DEA', + "yAxis" : 1, + 'data': [] + }, { + 'type': 'line', + 'id': 'macd', + 'name': 'MACD', + "yAxis" : 1, + 'data': [] + }] +} + +def main(): + global ChartCfg + preTime = 0 + chart = Chart(ChartCfg) + chart.reset() + while True: + while True: + r = _C(exchange.GetRecords) + if len(r) > 50: + break + # 计算指标 + macd = TA.MACD(r) + + LogStatus(_D(), len(r)) + + # 画图 + for i in range(len(r)): + if r[i]["Time"] == preTime: + chart.add(0, [r[i]["Time"], r[i]["Open"], r[i]["High"], r[i]["Low"], r[i]["Close"]], -1) + chart.add(1, [r[i]["Time"], macd[0][i]], -1) + chart.add(2, [r[i]["Time"], macd[1][i]], -1) + chart.add(3, [r[i]["Time"], macd[2][i]], -1) + elif r[i]["Time"] > preTime: + chart.add(0, [r[i]["Time"], r[i]["Open"], r[i]["High"], r[i]["Low"], r[i]["Close"]]) + chart.add(1, [r[i]["Time"], macd[0][i]]) + chart.add(2, [r[i]["Time"], macd[1][i]]) + chart.add(3, [r[i]["Time"], macd[2][i]]) + preTime = r[i]["Time"] + Sleep(500) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/187379 + +> 更新时间 + +2020-02-27 19:02:49 diff --git "a/Python\347\211\210\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.md" "b/Python\347\211\210\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.md" new file mode 100644 index 00000000..dce3230d --- /dev/null +++ "b/Python\347\211\210\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.md" @@ -0,0 +1,106 @@ + +> 策略名称 + +Python版冰山委托 - 买入 + +> 策略作者 + +小小梦 + +> 策略描述 + +教学策略,相关文章地址:https://www.fmz.com/bbs-topic/5080 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|TotalBuyNet|10000|购买总金额(元)| +|AvgBuyOnce|100|单次购买数量均值(元)| +|FloatPoint|10|单次均值浮动点数(百分比)| +|EntrustDepth|0.1|委托深度(百分比)| +|MaxBuyPrice|20000|最高买入价格(元)| +|Interval|1000|失败重试(毫秒)| +|MinStock|0.0001|最小交易量| +|LoopInterval|true|价格轮询间隔(秒)| + + +> 源码 (python) + +``` python +import random + +def CancelPendingOrders(): + while True: + orders = _C(exchange.GetOrders) + if len(orders) == 0 : + return + + for j in range(len(orders)): + exchange.CancelOrder(orders[j]["Id"]) + if j < len(orders) - 1: + Sleep(Interval) + +LastBuyPrice = 0 +InitAccount = None + +def dispatch(): + global InitAccount, LastBuyPrice + account = None + ticker = _C(exchange.GetTicker) + LogStatus(_D(), "ticker:", ticker) + if LastBuyPrice > 0: + if len(_C(exchange.GetOrders)) > 0: + if ticker["Last"] > LastBuyPrice and ((ticker["Last"] - LastBuyPrice) / LastBuyPrice) > (2 * (EntrustDepth / 100)): + Log("偏离过多, 最新成交价:", ticker["Last"], "委托价", LastBuyPrice) + CancelPendingOrders() + else : + return True + else : + account = _C(exchange.GetAccount) + Log("买单完成, 累计花费:", _N(InitAccount["Balance"] - account["Balance"]), "平均买入价:", _N((InitAccount["Balance"] - account["Balance"]) / (account["Stocks"] - InitAccount["Stocks"]))) + LastBuyPrice = 0 + + BuyPrice = _N(ticker["Buy"] * (1 - EntrustDepth / 100)) + if BuyPrice > MaxBuyPrice: + return True + + if not account: + account = _C(exchange.GetAccount) + + if (InitAccount["Balance"] - account["Balance"]) >= TotalBuyNet: + return False + + RandomAvgBuyOnce = (AvgBuyOnce * ((100.0 - FloatPoint) / 100.0)) + (((FloatPoint * 2) / 100.0) * AvgBuyOnce * random.random()) # 随机数 0~1 + UsedMoney = min(account["Balance"], RandomAvgBuyOnce, TotalBuyNet - (InitAccount["Balance"] - account["Balance"])) + + BuyAmount = _N(UsedMoney / BuyPrice) + if BuyAmount < MinStock: + return False + LastBuyPrice = BuyPrice + exchange.Buy(BuyPrice, BuyAmount, "花费:¥", _N(UsedMoney), "上次成交价", ticker["Last"]) + return True + +def main(): + global LoopInterval, InitAccount + CancelPendingOrders() + InitAccount = _C(exchange.GetAccount) + Log(InitAccount) + if InitAccount["Balance"] < TotalBuyNet: + raise Exception("账户余额不足") + LoopInterval = max(LoopInterval, 1) + while dispatch(): + Sleep(LoopInterval * 1000) + Log("委托全部完成", _C(exchange.GetAccount)) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/188435 + +> 更新时间 + +2020-03-07 16:58:07 diff --git "a/Python\347\211\210\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.md" "b/Python\347\211\210\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.md" new file mode 100644 index 00000000..387f085e --- /dev/null +++ "b/Python\347\211\210\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.md" @@ -0,0 +1,106 @@ + +> 策略名称 + +Python版冰山委托 - 卖出 + +> 策略作者 + +小小梦 + +> 策略描述 + +教学策略,相关文章地址:https://www.fmz.com/bbs-topic/5080 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|TotalSellStocks|10|卖出总数量(币)| +|AvgSellOnce|0.3|单次卖出数量均值(币)| +|FloatPoint|10|单次均值浮动点数(百分比)| +|EntrustDepth|0.1|委托深度(百分比)| +|MinSellPrice|3800|最低卖出价格(元)| +|Interval|1000|失败重试(毫秒)| +|MinStock|0.0001|最小交易量| +|LoopInterval|300|价格轮询间隔(毫秒)| + + +> 源码 (python) + +``` python +import random + +def CancelPendingOrders(): + while True: + orders = _C(exchange.GetOrders) + if len(orders) == 0: + return + + for j in range(len(orders)): + exchange.CancelOrder(orders[j]["Id"]) + if j < len(orders) - 1: + Sleep(Interval) + +LastSellPrice = 0 +InitAccount = None + +def dispatch(): + global LastSellPrice, InitAccount + account = None + ticker = _C(exchange.GetTicker) + LogStatus(_D(), "ticker:", ticker) + if LastSellPrice > 0: + if len(_C(exchange.GetOrders)) > 0: + if ticker["Last"] < LastSellPrice and ((LastSellPrice - ticker["Last"]) / ticker["Last"]) > (2 * (EntrustDepth / 100)): + Log("偏离过多,最新成交价:", ticker["Last"], "委托价", LastSellPrice) + CancelPendingOrders() + else : + return True + else : + account = _C(exchange.GetAccount) + Log("买单完成,累计卖出:", _N(InitAccount["Stocks"] - account["Stocks"]), "平均卖出价:", _N((account["Balance"] - InitAccount["Balance"]) / (InitAccount["Stocks"] - account["Stocks"]))) + LastSellPrice = 0 + + SellPrice = _N(ticker["Sell"] * (1 + EntrustDepth / 100)) + if SellPrice < MinSellPrice: + return True + + if not account: + account = _C(exchange.GetAccount) + + if (InitAccount["Stocks"] - account["Stocks"]) >= TotalSellStocks: + return False + + RandomAvgSellOnce = (AvgSellOnce * ((100.0 - FloatPoint) / 100.0)) + (((FloatPoint * 2) / 100.0) * AvgSellOnce * random.random()) + SellAmount = min(TotalSellStocks - (InitAccount["Stocks"] - account["Stocks"]), RandomAvgSellOnce) + if SellAmount < MinStock: + return False + + LastSellPrice = SellPrice + exchange.Sell(SellPrice, SellAmount, "上次成交价", ticker["Last"]) + return True + +def main(): + global InitAccount, LoopInterval + CancelPendingOrders() + InitAccount = _C(exchange.GetAccount) + Log(InitAccount) + if InitAccount["Stocks"] < TotalSellStocks: + raise Exception("账户币数不足") + LoopInterval = max(LoopInterval, 1) + while dispatch(): + Sleep(LoopInterval) + Log("委托全部完成", _C(exchange.GetAccount)) + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/188754 + +> 更新时间 + +2020-03-07 16:57:48 diff --git "a/Python\347\211\210\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" "b/Python\347\211\210\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" new file mode 100644 index 00000000..0faccd15 --- /dev/null +++ "b/Python\347\211\210\345\215\225\345\271\263\345\217\260\345\235\207\350\241\241\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" @@ -0,0 +1,98 @@ + +> 策略名称 + +Python版单平台均衡策略(教学) + +> 策略作者 + +小小梦 + +> 策略描述 + +引用自JavaScript版单平台均衡策略 +> 这个需要建仓,比如账户有5000块钱,跟1个币,如果币的价值大于账户的余额5000了并且差价超过阀值,比如币现在值6000块钱,就卖掉(6000-5000)/6000/2个币,说明币升值了,把钱兑换回来,如果币贬值了,比如4000块钱了,就买入(5000-4000)/4000/2个币, 币跌的时候买一些回来,如果再涨了,就再卖掉,好像天平一样,两边不同的对冲,所以我命名为均衡策略 + +文章地址: https://www.fmz.com/bbs-topic/4986 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|threshold|0.05|阀值| +|Interval|2000|出错重试间隔(毫秒)| +|LoopInterval|60|轮询间隔(秒)| +|MinStock|0.001|最小交易量| +|XPrecision|4|量精度| +|ZPrecision|8|价格精度| + + +> 源码 (python) + +``` python +'''backtest +start: 2019-12-01 00:00:00 +end: 2020-02-01 11:00:00 +period: 1m +exchanges: [{"eid":"OKEX","currency":"BTC_USDT","stocks":1}] +''' + +InitAccount = None + +def CancelPendingOrders(): + ret = False + while True: + orders = _C(exchange.GetOrders) + if len(orders) == 0 : + return ret + + for j in range(len(orders)): + exchange.CancelOrder(orders[j].Id) + ret = True + if j < len(orders) - 1: + Sleep(Interval) + return ret + +def onTick(): + acc = _C(exchange.GetAccount) + ticker = _C(exchange.GetTicker) + spread = ticker.Sell - ticker.Buy + diffAsset = (acc.Balance - (acc.Stocks * ticker.Sell)) / 2 + ratio = diffAsset / acc.Balance + LogStatus("ratio:", ratio, _D()) + if abs(ratio) < threshold: + return False + if ratio > 0 : + buyPrice = _N(ticker.Sell + spread, ZPrecision) + buyAmount = _N(diffAsset / buyPrice, XPrecision) + if buyAmount < MinStock: + return False + exchange.Buy(buyPrice, buyAmount, diffAsset, ratio) + else : + sellPrice = _N(ticker.Buy - spread, ZPrecision) + sellAmount = _N(-diffAsset / sellPrice, XPrecision) + if sellAmount < MinStock: + return False + exchange.Sell(sellPrice, sellAmount, diffAsset, ratio) + return True + +def main(): + global InitAccount, LoopInterval + InitAccount = _C(exchange.GetAccount) + LoopInterval = max(LoopInterval, 1) + while True: + if onTick(): + Sleep(1000) + CancelPendingOrders() + Log(_C(exchange.GetAccount)) + Sleep(LoopInterval * 1000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/183374 + +> 更新时间 + +2020-02-05 10:19:20 diff --git "a/Python\347\211\210\347\256\200\345\215\225\347\275\221\346\240\274\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" "b/Python\347\211\210\347\256\200\345\215\225\347\275\221\346\240\274\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" new file mode 100644 index 00000000..33ddd377 --- /dev/null +++ "b/Python\347\211\210\347\256\200\345\215\225\347\275\221\346\240\274\347\255\226\347\225\245\357\274\210\346\225\231\345\255\246\357\274\211.md" @@ -0,0 +1,167 @@ + +> 策略名称 + +Python版简单网格策略(教学) + +> 策略作者 + +小小梦 + +> 策略描述 + +https://www.fmz.com/bbs-topic/4877 + + + +> 源码 (python) + +``` python +'''backtest +start: 2019-07-01 00:00:00 +end: 2020-01-03 00:00:00 +period: 1m +exchanges: [{"eid":"OKEX","currency":"BTC_USDT"}] +''' + +import json + +# 参数 +beginPrice = 5000 +endPrice = 8000 +distance = 20 +pointProfit = 50 +amount = 0.01 +minBalance = 300 + +# 全局变量 +arrNet = [] +arrMsg = [] +acc = None + +def findOrder (orderId, NumOfTimes, ordersList = []) : + for j in range(NumOfTimes) : + orders = None + if len(ordersList) == 0: + orders = _C(exchange.GetOrders) + else : + orders = ordersList + for i in range(len(orders)): + if orderId == orders[i]["Id"]: + return True + Sleep(1000) + return False + +def cancelOrder (price, orderType) : + orders = _C(exchange.GetOrders) + for i in range(len(orders)) : + if price == orders[i]["Price"] and orderType == orders[i]["Type"]: + exchange.CancelOrder(orders[i]["Id"]) + Sleep(500) + +def checkOpenOrders (orders, ticker) : + global arrNet, arrMsg + for i in range(len(arrNet)) : + if not findOrder(arrNet[i]["id"], 1, orders) and arrNet[i]["state"] == "pending" : + orderId = exchange.Sell(arrNet[i]["coverPrice"], arrNet[i]["amount"], arrNet[i], ticker) + if orderId : + arrNet[i]["state"] = "cover" + arrNet[i]["id"] = orderId + else : + # 撤销 + cancelOrder(arrNet[i]["coverPrice"], ORDER_TYPE_SELL) + arrMsg.append("挂单失败!" + json.dumps(arrNet[i]) + ", time:" + _D()) + +def checkCoverOrders (orders, ticker) : + global arrNet, arrMsg + for i in range(len(arrNet)) : + if not findOrder(arrNet[i]["id"], 1, orders) and arrNet[i]["state"] == "cover" : + arrNet[i]["id"] = -1 + arrNet[i]["state"] = "idle" + Log(arrNet[i], "节点平仓,重置为空闲状态。", "#FF0000") + + +def onTick () : + global arrNet, arrMsg, acc + + ticker = _C(exchange.GetTicker) + for i in range(len(arrNet)): + if i != len(arrNet) - 1 and arrNet[i]["state"] == "idle" and ticker.Sell > arrNet[i]["price"] and ticker.Sell < arrNet[i + 1]["price"]: + acc = _C(exchange.GetAccount) + if acc.Balance < minBalance : + arrMsg.append("资金不足" + json.dumps(acc) + "!" + ", time:" + _D()) + break + + orderId = exchange.Buy(arrNet[i]["price"], arrNet[i]["amount"], arrNet[i], ticker) + if orderId : + arrNet[i]["state"] = "pending" + arrNet[i]["id"] = orderId + else : + # 撤单 + cancelOrder(arrNet[i]["price"], ORDER_TYPE_BUY) + arrMsg.append("挂单失败!" + json.dumps(arrNet[i]) + ", time:" + _D()) + Sleep(1000) + orders = _C(exchange.GetOrders) + checkOpenOrders(orders, ticker) + Sleep(1000) + orders = _C(exchange.GetOrders) + checkCoverOrders(orders, ticker) + + tbl = { + "type" : "table", + "title" : "网格状态", + "cols" : ["节点索引", "详细信息"], + "rows" : [], + } + + for i in range(len(arrNet)) : + tbl["rows"].append([i, json.dumps(arrNet[i])]) + + errTbl = { + "type" : "table", + "title" : "记录", + "cols" : ["节点索引", "详细信息"], + "rows" : [], + } + + orderTbl = { + "type" : "table", + "title" : "orders", + "cols" : ["节点索引", "详细信息"], + "rows" : [], + } + + while len(arrMsg) > 20 : + arrMsg.pop(0) + + for i in range(len(arrMsg)) : + errTbl["rows"].append([i, json.dumps(arrMsg[i])]) + + for i in range(len(orders)) : + orderTbl["rows"].append([i, json.dumps(orders[i])]) + + LogStatus(_D(), "\n", acc, "\n", "arrMsg length:", len(arrMsg), "\n", "`" + json.dumps([tbl, errTbl, orderTbl]) + "`") + + +def main (): + global arrNet + for i in range(int((endPrice - beginPrice) / distance)): + arrNet.append({ + "price" : beginPrice + i * distance, + "amount" : amount, + "state" : "idle", # pending / cover / idle + "coverPrice" : beginPrice + i * distance + pointProfit, + "id" : -1, + }) + + while True: + onTick() + Sleep(500) +``` + +> 策略出处 + +https://www.fmz.com/strategy/180385 + +> 更新时间 + +2020-01-04 14:42:23 diff --git a/README.md b/README.md index 3652858a..c6ddd7bc 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,48 @@ -# 发明者(FMZ) - 筑就非凡的量化世界 +# 发明者(FMZ.COM) - 筑就非凡的量化世界 > 开源策略 + - [Python版冰山委托 - 买入](https://www.fmz.com/strategy/188435) + - [Python版冰山委托 - 卖出](https://www.fmz.com/strategy/188754) + - [交易终端插件范例](https://www.fmz.com/strategy/187708) + - [通用协议(Python3.X版)——改编自CoinPark交易所通用协议 6.27 16:00 更新 关闭了SSL验证](https://www.fmz.com/strategy/188813) + - [冰山委托 - 卖出](https://www.fmz.com/strategy/241) + - [冰山委托 - 买入](https://www.fmz.com/strategy/236) + - [暴雪网格-7*24小时交易机器人,每日更新实盘效果](https://www.fmz.com/strategy/175807) + - [海龟策略btc现货版](https://www.fmz.com/strategy/186598) + - [MACD交易策略btc合约版](https://www.fmz.com/strategy/188100) + - [典型价格百分比通道-凯尔特纳与百分比通道变形](https://www.fmz.com/strategy/188507) + - [KRT凯尔特纳通道](https://www.fmz.com/strategy/188499) + - [区块链量化投资系列课程(4) - 动态平衡策略](https://www.fmz.com/strategy/110545) + - [标定值或均线交叉策略](https://www.fmz.com/strategy/187874) + - [深度快照](https://www.fmz.com/strategy/187969) + - [商品期货预定开仓后平仓机器人](https://www.fmz.com/strategy/187736) + - [C++期货高频套币策略OKEX Websocket版](https://www.fmz.com/strategy/163447) + - [Python版MACD指标画图范例](https://www.fmz.com/strategy/187379) + - [MACD画图范例](https://www.fmz.com/strategy/151972) + - [定量分型速率交易策略-by:泊宇量化](https://www.fmz.com/strategy/183416) + - [Dual Thrust OKEX期货 (教学)](https://www.fmz.com/strategy/112425) + - [区块链量化投资系列课程(3) - 跨期套利](https://www.fmz.com/strategy/104964) + - [OKex期货测试for新手](https://www.fmz.com/strategy/170842) + - [robotCtrl(教学策略)](https://www.fmz.com/strategy/184600) + - [蜡烛图技术](https://www.fmz.com/strategy/96793) + - [行情中心延时](https://www.fmz.com/strategy/183009) + - [行情中心客户端|market center client](https://www.fmz.com/strategy/182185) + - [Python版单平台均衡策略(教学)](https://www.fmz.com/strategy/183374) + - [网格变形策略之单边网格](https://www.fmz.com/strategy/629) - [优先版/FMEX[多头]趋势mining策略,附图,赚币赚钱赚矿](https://www.fmz.com/strategy/178347) + - [分享模板引用错误追踪](https://www.fmz.com/strategy/182793) + - [获取最新疫情|Fetch nCoV News](https://www.fmz.com/strategy/182505) + - [基于资金主动性流向的交易策略(Bar)](https://www.fmz.com/strategy/87698) + - [Python版多品种追涨杀跌策略(教学)](https://www.fmz.com/strategy/182268) + - [日志|Logger](https://www.fmz.com/strategy/151754) + - [8.12 hans123日内突破策略](https://www.fmz.com/strategy/179805) + - [大中小三周期跃迁策略V2.0_现货](https://www.fmz.com/strategy/177631) + - [基于期货基本面分析的交易策略](https://www.fmz.com/strategy/161412) + - [Python版追涨杀跌策略(教学)](https://www.fmz.com/strategy/181185) + - [Python版简单网格策略(教学)](https://www.fmz.com/strategy/180385) - [8.9 Dual Thrust 区间突破策略 Python 版](https://www.fmz.com/strategy/177504) - [8.8 增强版唐奇安通道策略](https://www.fmz.com/strategy/176458) - [8.7 日内高低点突破策略](https://www.fmz.com/strategy/175316) @@ -14,26 +52,19 @@ - [8.3 经典MACD交易策略](https://www.fmz.com/strategy/171604) - [8.2 自适应动态双均线策略Python版](https://www.fmz.com/strategy/170551) - [8.11 菲阿里四价策略](https://www.fmz.com/strategy/179505) - - [fcoin-多空力量排序](https://www.fmz.com/strategy/161034) - [Deribit期权测试策略](https://www.fmz.com/strategy/179475) - [8.10 经典恒温器策略](https://www.fmz.com/strategy/179014) - [恒温器 Thermostat 择时策略研究](https://www.fmz.com/strategy/127033) - - [FMEX[空头]趋势挖矿策略(随机网格排序)](https://www.fmz.com/strategy/178417) - - [FMEX挖矿策略(排序)btc均衡或【震荡版】](https://www.fmz.com/strategy/178700) - [简单的做市对冲功能](https://www.fmz.com/strategy/178194) - [深度做市 盘口控制 操盘机器人 做市工具](https://www.fmz.com/strategy/146238) - - [区块链量化投资系列课程(4) - 动态平衡策略](https://www.fmz.com/strategy/110545) - - [区块链量化投资系列课程(3) - 跨期套利](https://www.fmz.com/strategy/104964) - [FMEX简单挂单挖矿机器人](https://www.fmz.com/strategy/171258) - [FMEX简单交易挖矿机器人](https://www.fmz.com/strategy/171560) - [FMEX简单排序挖矿机器人](https://www.fmz.com/strategy/171042) - [商品期货布林指标突破策略(教学)](https://www.fmz.com/strategy/177584) - - [暴雪网格-7*24小时交易机器人](https://www.fmz.com/strategy/175807) - [根据商品期货计划委托工具实现一个短线策略(教学)](https://www.fmz.com/strategy/176022) - [自适应动态双均线策略My语言版](https://www.fmz.com/strategy/170606) - [商品期货计划委托工具(教学)](https://www.fmz.com/strategy/175150) - [牛熊猴市判断V1.0_区班主](https://www.fmz.com/strategy/170014) - - [OKex期货测试for新手](https://www.fmz.com/strategy/170842) - [教学策略TCI策略(麦语言移植)](https://www.fmz.com/strategy/174457) - [牛熊小卖部策略V1.0_OKex合约](https://www.fmz.com/strategy/171038) - [简单预定买入后卖出机器人|Buy then Sell (ping-pong strategy)](https://www.fmz.com/strategy/121228) @@ -49,11 +80,9 @@ - [SeamlessConnWS](https://www.fmz.com/strategy/167755) - [多级百分比止盈策略](https://www.fmz.com/strategy/166753) - [裸K上下影线在交易策略中的应用](https://www.fmz.com/strategy/165130) - - [C++期货高频套币策略OKEX Websocket版](https://www.fmz.com/strategy/163447) - [期货看穿式测试](https://www.fmz.com/strategy/152670) - [移植 OKCoin 韭菜收割机](https://www.fmz.com/strategy/34388) - [数字货币期货现货差价监控](https://www.fmz.com/strategy/164680) - - [基于期货基本面分析的交易策略](https://www.fmz.com/strategy/161412) - [香农网格)](https://www.fmz.com/strategy/164257) - [单点狙击高频加仓自动反手解套算法](https://www.fmz.com/strategy/164256) - [马丁格尔网格btc](https://www.fmz.com/strategy/164255) @@ -62,7 +91,6 @@ - [单边网格 (OK期货)](https://www.fmz.com/strategy/164252) - [多线程批量任务](https://www.fmz.com/strategy/159978) - [HFT strategy](https://www.fmz.com/strategy/162372) - - [MACD画图范例](https://www.fmz.com/strategy/151972) - [MultDualThrust(教学)](https://www.fmz.com/strategy/163212) - [标准差价格通道策略|Standard deviation price channel strategy](https://www.fmz.com/strategy/128121) - [Dual Thrust (麦语言版)|Dual Thrust (MyLanguage version)](https://www.fmz.com/strategy/128884) @@ -110,7 +138,6 @@ - [DMI 测试范例](https://www.fmz.com/strategy/154050) - [动态平衡策略 python 版](https://www.fmz.com/strategy/152830) - [麦语言网格策略](https://www.fmz.com/strategy/142701) - - [日志|Logger](https://www.fmz.com/strategy/151754) - [三角套利-基础版](https://www.fmz.com/strategy/151145) - [期货反手加倍算法](https://www.fmz.com/strategy/3648) - [每日市价定投](https://www.fmz.com/strategy/151259) @@ -195,7 +222,6 @@ - [GuoJian_First](https://www.fmz.com/strategy/113871) - [50行网格策略(教学)](https://www.fmz.com/strategy/113144) - [50行多平台对冲策略(教学)](https://www.fmz.com/strategy/113278) - - [Dual Thrust OKEX期货 (教学)](https://www.fmz.com/strategy/112425) - [[VNC] SVM Test](https://www.fmz.com/strategy/112188) - [单平台均衡策略](https://www.fmz.com/strategy/345) - [商品期货跨期对冲 - 单品种套利合约](https://www.fmz.com/strategy/27122) @@ -205,7 +231,6 @@ - [Dual Thrust OKEX Feature](https://www.fmz.com/strategy/103247) - [转换任意K线周期管理模板(最近更新20180627)](https://www.fmz.com/strategy/41163) - [检查https://quant.la/Argus/是否正常](https://www.fmz.com/strategy/100344) - - [fcoin挖矿演示](https://www.fmz.com/strategy/97791) - [币安出售所有山寨币](https://www.fmz.com/strategy/97629) - [商品期货 - 形态策略(增强型锤子)](https://www.fmz.com/strategy/97130) - [追涨杀跌](https://www.fmz.com/strategy/96634) @@ -227,14 +252,11 @@ - [单边网格](https://www.fmz.com/strategy/88472) - [okex币币最小交易量](https://www.fmz.com/strategy/88754) - [基于CCI周期性区间交易策略](https://www.fmz.com/strategy/60287) - - [网格变形策略之单边网格](https://www.fmz.com/strategy/629) - [talib简单应用之查找三只乌鸦](https://www.fmz.com/strategy/62163) - [内外盘期货品种实时差价图](https://www.fmz.com/strategy/82929) - [测试多图表展示Python版](https://www.fmz.com/strategy/84042) - [okex-BTC合约账户公开](https://www.fmz.com/strategy/83189) - [抢盘口做市策略 - 对敲](https://www.fmz.com/strategy/304) - - [冰山委托 - 卖出](https://www.fmz.com/strategy/241) - - [冰山委托 - 买入](https://www.fmz.com/strategy/236) - [趋势跟踪震荡策略](https://www.fmz.com/strategy/179) - [多平台强制滑动平仓(买一价)](https://www.fmz.com/strategy/99) - [定点进场下单定点离场卖单](https://www.fmz.com/strategy/64) diff --git "a/robotCtrl\357\274\210\346\225\231\345\255\246\347\255\226\347\225\245\357\274\211.md" "b/robotCtrl\357\274\210\346\225\231\345\255\246\347\255\226\347\225\245\357\274\211.md" new file mode 100644 index 00000000..1e493463 --- /dev/null +++ "b/robotCtrl\357\274\210\346\225\231\345\255\246\347\255\226\347\225\245\357\274\211.md" @@ -0,0 +1,146 @@ + +> 策略名称 + +robotCtrl(教学策略) + +> 策略作者 + +小小梦 + +> 策略描述 + +相关文章:https://www.fmz.com/bbs-topic-new/5011 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|strRobotParams|["175708,14:55:33-15:10:33"]|机器人定时参数| +|isPushMsg|false|是否推送到微信| +|accessKey|$$$__enc__$$$|FMZ平台扩展API的ACCESS KEY| +|secretKey|$$$__enc__$$$|FMZ平台扩展API的SECRET KEY| + + +> 源码 (python) + +``` python +# -*- coding: utf-8 -*- +import time +import json + +try: + import md5 + import urllib2 + from urllib import urlencode +except: + import hashlib as md5 + import urllib.request as urllib2 + from urllib.parse import urlencode + +def api(method, *args): + d = { + 'version': '1.0', + 'access_key': accessKey, + 'method': method, + 'args': json.dumps(list(args)), + 'nonce': int(time.time() * 1000), + } + + d['sign'] = md5.md5(('%s|%s|%s|%d|%s' % (d['version'], d['method'], d['args'], d['nonce'], secretKey)).encode('utf-8')).hexdigest() + return json.loads(urllib2.urlopen('https://www.fmz.com/api/v1', urlencode(d).encode('utf-8')).read().decode('utf-8')) + +RobotParams = json.loads(strRobotParams) + +def main(): + global RobotParams + arrParams = [] + nowDay = 0 + strPush = "" + if isPushMsg: + strPush = "@" + + for i in range(len(RobotParams)): + param = {} + arr = RobotParams[i].split(",") + if len(arr) != 2: + raise Exception("字符串配置错误:分隔符号,") + param["id"] = arr[0] + param["isProcessOpenThisDay"] = False + param["isProcessCloseThisDay"] = False + + arr = arr[1].split("-") + if len(arr) != 2: + raise Exception("字符串配置错误:分隔符号-") + + begin = arr[0] + arrBegin = begin.split(":") + if len(arrBegin) != 3: + raise Exception("字符串配置错误:起始时间分隔符号:") + + param["begin"] = {} + param["begin"]["hour"] = float(arrBegin[0]) + param["begin"]["min"] = float(arrBegin[1]) + param["begin"]["sec"] = float(arrBegin[2]) + + end = arr[1] + arrEnd = end.split(":") + if len(arrEnd) != 3: + raise Exception("字符串配置错误:结束时间分隔符号:") + + param["end"] = {} + param["end"]["hour"] = float(arrEnd[0]) + param["end"]["min"] = float(arrEnd[1]) + param["end"]["sec"] = float(arrEnd[2]) + arrParams.append(param) + + # 测试 + Log("输出参数", arrParams, "#FF0000") + + while True: + nowTime = time.localtime(time.time()) + nowHour = nowTime.tm_hour + nowMin = nowTime.tm_min + nowSec = nowTime.tm_sec + + tbl = { + "type" : "table", + "title" : "msg", + "cols" : ["id", "begin", "end", "今天是否执行过启动", "今天是否执行过停止"], + "rows" : [] + } + + for i in range(len(arrParams)): + tbl["rows"].append([arrParams[i]["id"], json.dumps(arrParams[i]["begin"]), json.dumps(arrParams[i]["end"]), arrParams[i]["isProcessOpenThisDay"], arrParams[i]["isProcessCloseThisDay"]]) + if nowDay != nowTime.tm_mday: + arrParams[i]["isProcessOpenThisDay"] = False + arrParams[i]["isProcessCloseThisDay"] = False + + if arrParams[i]["isProcessOpenThisDay"] == False: + if nowTime.tm_hour == arrParams[i]["begin"]["hour"] and nowTime.tm_min >= arrParams[i]["begin"]["min"] and nowTime.tm_sec >= arrParams[i]["begin"]["sec"]: + ret = api('RestartRobot', int(arrParams[i]["id"])) + arrParams[i]["isProcessOpenThisDay"] = True + Log("机器人ID:", arrParams[i]["id"], "执行启动,请登录平台检查是否启动成功", "扩展API返回值:", ret, strPush) + + if arrParams[i]["isProcessCloseThisDay"] == False: + if nowTime.tm_hour == arrParams[i]["end"]["hour"] and nowTime.tm_min >= arrParams[i]["end"]["min"] and nowTime.tm_sec >= arrParams[i]["end"]["sec"]: + ret = api('StopRobot', int(arrParams[i]["id"])) + arrParams[i]["isProcessCloseThisDay"] = True + Log("机器人ID:", arrParams[i]["id"], "执行停止,请登录平台检查是否停止成功", "扩展API返回值:", ret, strPush) + + if nowDay != nowTime.tm_mday: + nowDay = nowTime.tm_mday + + LogStatus(_D(), nowTime, "\n`" + json.dumps(tbl) + "`") + Sleep(500) + +``` + +> 策略出处 + +https://www.fmz.com/strategy/184600 + +> 更新时间 + +2020-02-16 20:03:16 diff --git "a/\344\272\244\346\230\223\347\273\210\347\253\257\346\217\222\344\273\266\350\214\203\344\276\213.md" "b/\344\272\244\346\230\223\347\273\210\347\253\257\346\217\222\344\273\266\350\214\203\344\276\213.md" new file mode 100644 index 00000000..24356aa0 --- /dev/null +++ "b/\344\272\244\346\230\223\347\273\210\347\253\257\346\217\222\344\273\266\350\214\203\344\276\213.md" @@ -0,0 +1,110 @@ + +> 策略名称 + +交易终端插件范例 + +> 策略作者 + +小小梦 + +> 策略描述 + +用于演示交易终端插件嵌入功能。 +https://www.fmz.com/api#%E4%BA%A4%E6%98%93%E6%8F%92%E4%BB%B6 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|TransactionTimes|5|交易次数| +|Amount|0.02|每笔交易币数| +|Side|0|交易方向: 买|卖| + + + + +|按钮|默认值|描述| +|----|----|----| +|Buy|__button__|买入| + + +> 源码 (javascript) + +``` javascript +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 + } else { + // Log(obj, "is not object or not have attribute 'Info'") + return obj + } +} + + +function main() { + var initAcc = _C(exchange.GetAccount) + var tbl = { + "type" : "table", + "title" : "表格", + "cols" : ["项目", "内容"], + "rows" : [], + } + + for (var i = 0 ; i < TransactionTimes ; i++) { + var info = null + if (Side == 0) { + info = $.Buy(Amount) + } else if (Side == 1) { + info = $.Sell(Amount) + } else { + throw "side error!" + } + + tbl.rows.push([i + "号订单,成交情况:", JSON.stringify(info)]) + Sleep(300) + } + + var nowAcc = _C(exchange.GetAccount) + tbl.rows.push(["初始账户:", JSON.stringify(E(initAcc))]) + tbl.rows.push(["执行后账户:", JSON.stringify(E(nowAcc))]) + return tbl +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/187708 + +> 更新时间 + +2020-03-07 09:47:10 diff --git "a/\344\274\230\345\205\210\347\211\210-FMEX[\345\244\232\345\244\264]\350\266\213\345\212\277mining\347\255\226\347\225\245\357\274\214\351\231\204\345\233\276\357\274\214\350\265\232\345\270\201\350\265\232\351\222\261\350\265\232\347\237\277.md" "b/\344\274\230\345\205\210\347\211\210-FMEX[\345\244\232\345\244\264]\350\266\213\345\212\277mining\347\255\226\347\225\245\357\274\214\351\231\204\345\233\276\357\274\214\350\265\232\345\270\201\350\265\232\351\222\261\350\265\232\347\237\277.md" index 5274b8b6..df2ef6e9 100644 --- "a/\344\274\230\345\205\210\347\211\210-FMEX[\345\244\232\345\244\264]\350\266\213\345\212\277mining\347\255\226\347\225\245\357\274\214\351\231\204\345\233\276\357\274\214\350\265\232\345\270\201\350\265\232\351\222\261\350\265\232\347\237\277.md" +++ "b/\344\274\230\345\205\210\347\211\210-FMEX[\345\244\232\345\244\264]\350\266\213\345\212\277mining\347\255\226\347\225\245\357\274\214\351\231\204\345\233\276\357\274\214\350\265\232\345\270\201\350\265\232\351\222\261\350\265\232\347\237\277.md" @@ -11,10 +11,10 @@ **FMex排序挖矿多头版本代码使用说明** -(注意api地址)(另有加强版-增加仓位管理-增加时间设定,调整单量方向等-购买联系微信:ying5737)讨论联系微信:ying5737 +(注意api地址)(另有加强版-增加仓位管理-增加时间设定,调整单量方向等-微信:ying5737)讨论联系微信:ying5737 (预计日行情稳定涨幅1%以上,赚币又赚钱,反之亏损明显) 保证金市场风险巨大,你可能随时面临100%损失。或有不明bug100%损失,概不负责。 - +//(若考虑持仓做空或震荡,可对应修改参数和代码挡位) **策略原理:** ![](http://https://wx1.sinaimg.cn/mw690/c5775633ly1gaajdxk8a8j20u10f4dhx.jpg) @@ -40,7 +40,7 @@ https://wx1.sinaimg.cn/mw690/c5775633ly1gaajdxk8a8j20u10f4dhx.jpg 正常持仓,long买3/4买5(盘口波动随机成交多单) **//参数中的备注描述,仅供参考,另可加挡位** -******风险自负/参数可调,购买加强版联系微信:ying5737** +******风险自负/参数可调,微信:ying5737** **优化方向:加入均线或K线对比来确定方向,挡位优化,增加单量等/****** > 策略参数 @@ -70,8 +70,9 @@ https://wx1.sinaimg.cn/mw690/c5775633ly1gaajdxk8a8j20u10f4dhx.jpg ``` javascript exchange.IO("base", Url)//保证金市场风险巨大,你可能随时面临100%损失。或有不明bug100%损失,概不负责。 +//(若考虑持仓做空或震荡,可对应修改参数和代码挡位) //实盘地址:https://api.fmex.com 测试网https://api.testnet.fmex.com//注意:先持仓long100u。 -var ordersInfo = {//(加强版-增加仓位管理-增加时间设定-调整单量方向等-价格美丽/购买联系微信:ying5737)请备注fm +var ordersInfo = {//(加强版-增加仓位管理-增加时间设定-调整单量方向等-联系微信:ying5737)请备注fm buyId: 0, buyPrice: 0, sellId: 0, @@ -320,7 +321,7 @@ function main() { shishang() Sleep(mainIntervel * 1000) } -}//FMex排序挖矿多头版本代码使用说明。(注意api地址)(加强版-增加仓位管理-增加时间设定等-购买联系微信:ying5737) +}//FMex排序挖矿多头版本代码使用说明。(注意api地址)(加强版-增加仓位管理-联系微信:ying5737) ``` > 策略出处 @@ -329,4 +330,4 @@ https://www.fmz.com/strategy/178347 > 更新时间 -2019-12-29 19:00:38 +2020-01-31 23:21:41 diff --git "a/\345\205\270\345\236\213\344\273\267\346\240\274\347\231\276\345\210\206\346\257\224\351\200\232\351\201\223-\345\207\257\345\260\224\347\211\271\347\272\263\344\270\216\347\231\276\345\210\206\346\257\224\351\200\232\351\201\223\345\217\230\345\275\242.md" "b/\345\205\270\345\236\213\344\273\267\346\240\274\347\231\276\345\210\206\346\257\224\351\200\232\351\201\223-\345\207\257\345\260\224\347\211\271\347\272\263\344\270\216\347\231\276\345\210\206\346\257\224\351\200\232\351\201\223\345\217\230\345\275\242.md" new file mode 100644 index 00000000..bac1876c --- /dev/null +++ "b/\345\205\270\345\236\213\344\273\267\346\240\274\347\231\276\345\210\206\346\257\224\351\200\232\351\201\223-\345\207\257\345\260\224\347\211\271\347\272\263\344\270\216\347\231\276\345\210\206\346\257\224\351\200\232\351\201\223\345\217\230\345\275\242.md" @@ -0,0 +1,48 @@ + +> 策略名称 + +典型价格百分比通道-凯尔特纳与百分比通道变形 + +> 策略作者 + +cyberking + +> 策略描述 + +典型价格百分比通道-凯尔特纳与百分比通道变形 +DX^^EMA((H+L+C)/3,N); //21天典型价格均线 中 +KRTHR^^EMA(DX,N)*1.05; //21天百分比通道 上 +KRTXR^^EMA(DX,N)/1.05; //21天百分比通道 下 + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2019-02-09 00:00:00 +end: 2020-03-04 00:00:00 +period: 1d +exchanges: [{"eid":"Huobi","currency":"BTC_USDT"}] +*) + +//ZF:=H-C; //振幅 +N:=21; +DX^^EMA((H+L+C)/3,N); //21天典型价格均线 中 +KRTHR^^EMA(DX,N)*1.05; //21天百分比通道 上 +KRTXR^^EMA(DX,N)/1.05; //21天百分比通道 下 + +C>DX AND (DXDX AND REF(DX,1)>REF(DX,2),BPK; +CKRTXR),SPK; //下突破典型 中轨, 中轨大于下轨 +//C 策略出处 + +https://www.fmz.com/strategy/188507 + +> 更新时间 + +2020-03-05 21:36:49 diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.md" "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.md" index 2ced9a48..76e27b02 100644 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.md" +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \344\271\260\345\205\245.md" @@ -103,6 +103,9 @@ function dispatch() { } function main() { + if (exchange.GetName().indexOf('Futures_') != -1) { + throw "只支持现货"; + } CancelPendingOrders(); InitAccount = _C(exchange.GetAccount); Log(InitAccount); @@ -124,4 +127,4 @@ https://www.fmz.com/strategy/236 > 更新时间 -2018-03-27 16:21:44 +2020-03-06 19:47:41 diff --git "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.md" "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.md" index dc719993..66fcb796 100644 --- "a/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.md" +++ "b/\345\206\260\345\261\261\345\247\224\346\211\230 - \345\215\226\345\207\272.md" @@ -99,6 +99,9 @@ function dispatch() { } function main() { + if (exchange.GetName().indexOf('Futures_') != -1) { + throw "只支持现货"; + } CancelPendingOrders(); InitAccount = _C(exchange.GetAccount); Log(InitAccount); @@ -121,4 +124,4 @@ https://www.fmz.com/strategy/241 > 更新时间 -2018-03-27 16:23:50 +2020-03-06 19:47:44 diff --git "a/\345\210\206\344\272\253\346\250\241\346\235\277\345\274\225\347\224\250\351\224\231\350\257\257\350\277\275\350\270\252.md" "b/\345\210\206\344\272\253\346\250\241\346\235\277\345\274\225\347\224\250\351\224\231\350\257\257\350\277\275\350\270\252.md" new file mode 100644 index 00000000..6fe6fd32 --- /dev/null +++ "b/\345\210\206\344\272\253\346\250\241\346\235\277\345\274\225\347\224\250\351\224\231\350\257\257\350\277\275\350\270\252.md" @@ -0,0 +1,85 @@ + +> 策略名称 + +分享模板引用错误追踪 + +> 策略作者 + +leviyuan + +> 策略描述 + +使用方法,首先引用这个模板类库 +在每一个脚本文件里面添加 $.fileLineMark("main", 35) 第一个参数:文件名 第二个参数:这行代码在文件里面的行号 +并保证在追踪错误之前,这行代码被执行 +最后在策略代码加上 main = $.tryfunc(main) 以保证所有的调用都通过try + +在策略报错时,会自动有一行红字指出在哪个文件的哪一行 + +原理:托管着加载js代码的方式,是把所有的js代码,包含类库,合并成一个大文件载入;找出每个文件在大文件中的位置,最后报错时候,反向对应,即可知道具体报错的行号 + + ![IMG](https://www.fmz.com/upload/asset/443a3c3f50e09c3ca4be.png) + + + +> 源码 (javascript) + +``` javascript +var fileStartLine = [] +$.fileLineMark = function(file, line) { + try{a=a+1}catch(ex){ + var markline = parseInt(ex.stack.split('\n')[3].split('(__FILE__:')[1].split(')')[0]) + fileStartLine.push([file, markline-line]) + fileStartLine.sort(function(a, b){ + return b[1] - a[1] + }) + } +} + +$.tryfunc = function(func) { + return function(a,b,c,d,e,f,g,h,i,j,k,l,m,n) { + try { + return func(a,b,c,d,e,f,g,h,i,j,k,l,m,n) + } catch(ex) { + if (ex.message == "execution timeout") { + Log("忽略机器人停止指令") + throw ex + return + } + + var line = parseInt(ex.stack.split('\n')[2].split('(__FILE__:')[1].split(')')[0]) + for (var ii = 0; ii < fileStartLine.length; ii++) { + if (line > fileStartLine[ii][1]) { + Log("catch error at " + fileStartLine[ii][0] + ":" + (line-fileStartLine[ii][1])+"#ff0000") + break + } + } + + throw ex + } + } +} + +function onTick() { + +} + +function main() { + $.fileLineMark("main", 41) + onTick = $.tryfunc(onTick) + + while(true){ + onTick() + Sleep(1000) + } +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/182793 + +> 更新时间 + +2020-01-28 21:11:06 diff --git "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" index d2df71ed..7c5e2c1e 100644 --- "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" +++ "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(3) - \350\267\250\346\234\237\345\245\227\345\210\251.md" @@ -9,144 +9,9 @@ Hukybo > 策略描述 -阅读原文:[区块链量化投资系列课程(3) - 跨期套利](https://quantinfo.com/Article/View/816/%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B%283%29---%E8%B7%A8%E6%9C%9F%E5%A5%97%E5%88%A9.html) -### NO.1 -索罗斯在1987年撰写的《金融炼金术》 一书中,曾经提出过一个重要的命题:I believe the market prices are always wrong in the sense that they present a biased view of the future. -[]( ![IMG](https://www.fmz.com/upload/asset/3a50b5d2432cb4ff4eed.png) ) -市场有效假说只是理论上的假设,实际上市场参与者并不总是理性的,并且在每一个时间点上,参与者不可能完全获取和客观解读所有的信息,再者就算是同样的信息,每个人的反馈都不尽相同。 +索罗斯在1987年撰写的《金融炼金术》 一书中,曾经提出过一个重要的命题:I believe the market prices are always wrong in the sense that they present a biased view of the future.市场有效假说只是理论上的假设,实际上市场参与者并不总是理性的,并且在每一个时间点上,参与者不可能完全获取和客观解读所有的信息,再者就算是同样的信息,每个人的反馈都不尽相同。也就是说,价格本身就已经包含了市场参与者的错误预期,所以本质上市场价格总错误的。这或许是套利者的利润来源。 -也就是说,价格本身就已经包含了市场参与者的错误预期,所以本质上市场价格总错误的。这或许是套利者的利润来源。 - - - -### NO.2 -根据上述原理,我们也就知道,在一个非有效的期货市场中,不同时期交割合约之间受到市场影响也并不总是同步,其定价也并非完全有效的原因。 - -那么,根据同一种交易标的的不同时期交割合约价格为基础,如果两个价格出现了较大的价差幅度,就可以同时买卖不同时期的期货合约,进行跨期套利。 -[]( ![IMG](https://www.fmz.com/upload/asset/39c5e58ad36a6ef82d32.png) ) -与商品期货一样,数字货币也有与之相关的跨期套利合约组合。如在 OkEX 交易所中就有:ETC 当周、ETC 次周、ETC 季度。 - -举个例子,假设 ETC 当周和 ETC 季度的价差长期维持在 5 左右。如果某一天价差达到 7,我们预计价差会在未来某段时间回归到 5。那么就可以卖出 ETC 当周,同时买入 ETC 季度,来做空这个价差。反之亦然。 - - - -### NO.3 -尽管这种价差是存在的,但是人工操作耗时、准确性差以及价格变化的影响,人工套利往往存在诸多不确定性。 - -通过量化模型捕捉套利机会并制定套利交易策略,以及程序化算法自动向交易所下达交易订单,快速准确捕捉机会,高效稳定赚取收益,这就是量化套利的魅力所在。 -[]( ![IMG](https://www.fmz.com/upload/asset/39fb7e34588bd2e7ddcf.png) ) -本篇将会教大家如何在数字货币交易中,利用发明者量化交易平台和 OkEX 交易所中 ETC 期货合约,以一个简单的套利策略,来演示如果捕捉瞬时的套利机会,把握住每一次可以看得到的利润,同时对冲有可能遇到的风险。 - - - -### NO.4 -创建一个数字货币跨期套利策略 -难易度:普通级 - []( ![IMG](https://www.fmz.com/upload/asset/3975b5c50dd3e4618d12.png) ) - - 策略环境: -- 交易标的:以太经典(ETC) -- 价差数据:ETC 当周 - ETC 季度(省略协整性检验) -- 交易周期:5 分钟 -- 头寸匹配:1:1 -- 交易类型:同品种跨期 - -策略逻辑: -- 做多价差开仓条件:如果当前账户没有持仓,并且价差小于 boll 下轨,就做多价差。即:买开 ETC 当周,卖开 ETC 季度。 -- 做空价差开仓条件:如果当前账户没有持仓,并且价差大于 boll 上轨,就做空价差。即:卖开 ETC 当周,买开 ETC 季度。 -- 做多价差平仓条件:如果当前账户持有 ETC 当周多单,并且持有 ETC 季度空单,并且价差大于 boll 中轨,就平多价差。即:卖平 ETC 当周,买平 ETC 季度。 -- 做空价差平仓条件:如果当前账户持有 ETC 当周空单,并且持有 ETC 季度多单,并且价差小于 boll 中轨,就平空价差。即:买平 ETC 当周,卖平 ETC 季度。 - - - -### NO.5 -上面是一个简单的数字货币跨期套利策略逻辑描述,那么如何在程序中实现自己的想法呢?我们试着在发明者量化交易平台先把框架搭建起来。 -**策略框架:** - [发明者量化(www.fmz.com)]( ![IMG](https://www.fmz.com/upload/asset/399e03afb094d0d149ed.png) ) - 对照着策略思路以及交易流程,可以很轻松把策略框架搭建起来。整个策略可以简化为三个步骤: - 1.交易前预处理。 -2.获取并计算数据。 -3.下单并对后续处理。 - - - -### NO.6 -接下来,我们就需要根据实际交易流程和交易细节,在策略框架里面填充必要的细节代码。 -##### 一、交易前预处理 -第1步:在全局环境中,声明必要的全局变量。 - -- 声明一个配置图表的 chart 对象 -var chart = { } -- 调用 Chart 函数,初始化图表 -var ObjChart = Chart ( chart ) -- 声明一个空数组,用来存储价差序列 -var bars = [ ] -- 声明一个记录历史数据时间戳变量 -var oldTime = 0 - -第2步:配置策略的外部参数。 -[发明者量化(www.fmz.com)]( ![IMG](https://www.fmz.com/upload/asset/398ab0b260d21ee7462c.png) ) - -第3步:定义数据处理函数 -**基础数据函数**:Data ( ) -创建一个构造函数 Data,并定义它的内部属性。包括:账户数据、持仓数据、K线数据时间戳、套利A/B合约的买/卖一价、正/反套价差。 -[发明者量化(www.fmz.com)]( ![IMG](https://www.fmz.com/upload/asset/39a74331ead8bf6351b6.png) ) -**获取持仓函数**:mp ( ) -遍历整个持仓数组,返回指定合约、指定方向的持仓数量,如果没有就返回 false -[]( ![IMG](https://www.fmz.com/upload/asset/39283091a2290f3c2e4a.png) ) -**K线和指标函数**:boll ( ) -根据正/反套价差数据,合成新的K线序列。并返回由boll指标计算的上轨、中轨、下轨数据。 -[]( ![IMG](https://www.fmz.com/upload/asset/3973481a1310ddffa47d.png) ) -**下单函数**:trade ( ) -传入下单合约名称和下单类型,然后以对价下单,并返回下单后的结果。由于需要同时下两个不同方向的单子,所以在函数内部根据下单合约名称对买/卖一价做了转换。 -[]( ![IMG](https://www.fmz.com/upload/asset/3a36d770938d35a407b1.png) ) -**取消订单函数**:cancelOrders ( ) -获取所有未成交订单数组,并逐个取消。并且如果有未成交的订单就返回false,如果没有未成交的订单就返回true。 -[]( ![IMG](https://www.fmz.com/upload/asset/395b0a12d3a6814d13a3.png) ) -**处理持有单个合约**:isEven ( ) -在处理套利交易中出现单腿情况,这里直接用简单的平掉所有仓位处理。当然,也可以改为追单方式。 -[]( ![IMG](https://www.fmz.com/upload/asset/3a4db92b687659c4ffe6.png) ) -**画图函数**:drawingChart ( ) -调用 ObjChart.add ( ) 方法,在图表中画出必要的行情数据和指标数据:上轨、中轨、下轨、正/反套价差。 -[]( ![IMG](https://www.fmz.com/upload/asset/39e1621a909a34c5b9d1.png) ) -第4步:在入口函数 main ( ) 里面,执行交易前预处理代码,这些代码在程序启动后,只运行一次。包括: -- 过滤控制台中不是很重要的信息 SetErrorFilter ( ) -- 设置要交易的数字货币币种 exchange.IO ( ) -- 程序启动前清空之前绘制的图表 ObjChart.reset ( ) -- 程序启动前清空之前的状态栏信息 LogProfitReset ( ) - -[]( ![IMG](https://www.fmz.com/upload/asset/39082440603314ba0136.png) ) - - - -### NO.7 -定义完上述的交易前预处理,紧接着就要进入下一个步骤,进入轮询模式,重复执行 onTick ( ) 函数。 -并设置 Sleep ( ) 轮询时的休眠时间,因为部分数字货币交易所的 API 对一定时间内内置了访问次数限制。 -[]( ![IMG](https://www.fmz.com/upload/asset/3a31da7c4d17305936a9.png) ) -##### 二、获取并计算数据 -第1步:获取基础数据对象、账户余额、boll 指标数据,以供交易逻辑使用。 -[]( ![IMG](https://www.fmz.com/upload/asset/3a04d9408da5c6263b7d.png) ) -##### 三、下单并对后续处理 -第1步:根据上述的策略逻辑,执行买卖操作。首先会判断价格和指标条件是否成立,然后再判断持仓条件是否成立,最后执行 trade ( ) 下单函数 -[]( ![IMG](https://www.fmz.com/upload/asset/39573695cd117b864773.png) ) -第2步:下单完成后,需要对未成交的订单、持有单个合约等非正常情况做处理。以及绘制图表。 -[]( ![IMG](https://www.fmz.com/upload/asset/39ecb07f954fa643c38e.png) ) - - - -### NO.8 -以上,我们通过 200 多行,就把一个简单的数字货币跨期套利策略完完整整的创建出来。完整的代码如下: - []( ![IMG](https://www.fmz.com/upload/asset/39853edcb19072073099.png) ) - - - ### NO.9 - 本篇策略只是一个抛砖引玉,真实的实盘可不是这么简单,不过你可以照着例子发挥自己天马行空的想象。 - -需要提醒大家的是,以我有限的经验来看,目前的数字货币市场状况,纯粹的期期套利策略基本上全部不值得跑,不论是无风险的三角套利还是跨市场套利。 -[]( ![IMG](https://www.fmz.com/upload/asset/399dbae8aef4b1738435.png) ) -原因就在于,无论哪个数字货币交易所的期货市场,其保证金不是法币。现如今几乎所有的数字货币从今年初至今已经下跌了70%左右。也就是说策略始终都是在赚币,但是币价是下跌的。 - -放眼望去,数字货币市场俨然已经脱离了区块链,就像当年的郁金香一样,价格始终来自于人们的预期和信心,信心又来源于价格... +[点击阅读更多内容](https://www.fmz.com/bbs-topic/5026) @@ -424,4 +289,4 @@ https://www.fmz.com/strategy/104964 > 更新时间 -2019-12-09 11:59:12 +2020-02-22 19:56:37 diff --git "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" index dffc62fd..a36cb8e7 100644 --- "a/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" +++ "b/\345\214\272\345\235\227\351\223\276\351\207\217\345\214\226\346\212\225\350\265\204\347\263\273\345\210\227\350\257\276\347\250\213(4) - \345\212\250\346\200\201\345\271\263\350\241\241\347\255\226\347\225\245.md" @@ -9,103 +9,8 @@ Hukybo > 策略描述 -阅读原文:[区块链量化投资系列课程(4) - 动态平衡策略](https://quantinfo.com/Article/View/1573/[1-4]%E5%8C%BA%E5%9D%97%E9%93%BE%E9%87%8F%E5%8C%96%E6%8A%95%E8%B5%84%E7%B3%BB%E5%88%97%E8%AF%BE%E7%A8%8B---%E5%8A%A8%E6%80%81%E5%B9%B3%E8%A1%A1%E7%AD%96%E7%95%A5.html) - -### 前言 -沃伦 · 巴菲特的导师本杰明 · 格雷厄姆曾经在[《聪明的投资者》](https://quantinfo.com/Download/View/2742/%E8%81%AA%E6%98%8E%E7%9A%84%E6%8A%95%E8%B5%84%E8%80%85%EF%BC%88%E7%AC%AC4%E7%89%88%EF%BC%89.html)一书中,曾经提到过一种股票债券动态平衡的交易模式。 -[]( https://dn-filebox.qbox.me/71666050bcdc809d074f5cfa3499650045306c5d.png ) -这种交易模式非常简单: -- 把手中 50% 的资金投资于股票基金,剩下 50% 投资于债券基金。即股票和债券两者各占一半。 -- 根据固定间隔时间或市场变化进行一次资产再平衡,使股票资产和债券资产的比例恢复到初始的 1:1。 -这就是整个策略的全部逻辑,包含了什么时候买卖,以及买卖多少。够简单吧! - -在这个方法中,债券基金的波动率其实很小,远远低于股票波动率,所以债券在这里被当做『 参照锚 』,也就是说,用债券来衡量股票究竟是涨得太多了,还是涨得太少了。如果,股票价格上涨,会使得股票的市值大于债券的市值,当两者市值比率超过设定的阈值时,则对总仓位进行重新调整,卖出股票,并且买入债券,使股债市值比例恢复至初始的 1:1。 - -反之,股票价格下跌,会使得股票的市值小于债券的市值,当两者市值比率超过设定的阈值时,则对总仓位进行重新调整,买入股票,并且卖出债券,使股债市值比例恢复至初始的 1:1。 -[]( ![IMG](https://www.fmz.com/upload/asset/38c501464347620f3d16.png) ) - -就这样,在动态平衡股票和债券之间的比例,就够享受到股票成长的果实,并且减少了资产波动率。作为价值投资的先驱,格雷厄姆为我们提供了一个很好的思路。 - -既然这是一个完整的策略,为何我们不把它用在数字货币上呢? - -### 区块链资产 BTC 中的动态平衡策略 -#### 策略逻辑 -- 按照当前的 BTC 的价值,账户余额保留¥5000 现金和 0.1个 BTC,即现金和BTC 市值的初始比例是 1:1。 -- 如果 BTC 的价格上涨至¥6000,即 BTC 市值大于账户余额,并且其之间的差超过设定的阈值,就卖掉(6000-5000)/6000/2个币。说明 BTC 升值了,把钱兑换回来。 -- 如果 BTC 的价格下跌至¥4000,即 BTC市值小于账户余额,并且其之间的差超过设定的阈值,就买入(5000-4000)/4000/2个币。说明 BTC 贬值了,把 BTC 买回来。 - -就这样,不管 BTC 是升值还是贬值,始终动态保持账户余额和 BTC 的市值相等。如果 BTC 贬值了就买一些,等再涨回来,就再卖一些,就好像天平一样。 - -### 那么,如何用代码去实现呢? -我们以发明者量化交易平台为例,首先让我们看一下策略框架: -[]( https://dn-filebox.qbox.me/f0b1866a50126e6ffb3670fefc9cc0a0f5677ab6.png ) - -整个策略框架其实很简单,一个 main 主函数、一个 onTick 下单函数、一个 CancelPendingOrders 函数、以及必要参数。 - -### 下单模块 -[]( https://dn-filebox.qbox.me/fa17c458239f19cab2986f0cf7cd097a521eec4b.png ) - -下单交易逻辑条理清晰,所有的注释都已经写到代码里面了,可以点击图片放大查看。 - -#### 主要流程如下: -- 获取账户信息。 -- 获取 Tick 数据。 -- 计算 Tick 数据买卖价差。 -- 计算账户余额和 BTC 市值价差。 -- 计算买卖条件、下单价格、下单量。 -- 下单,并返回 true。 - -### 撤单模块 -[]( https://dn-filebox.qbox.me/6245854ec66a01bb7ea610da75b9ad46422a4f5d.png ) - -撤单模块就更简单了,步骤如下: -- 撤单前先等待 1 秒,个别交易所,你懂的。 -- 持续获取未成交订单数组,如果返回异常,则继续获取。 -- 如果未成交订单数组为空,即时返回撤单状态。 -- 如果有未成交的订单,则遍历整个数组,并依次根据订单号撤单。 - - -### 策略全部源码 -![]( https://dn-filebox.qbox.me/8df49e36426dfdc05c5d496c73f1300afd79af0f.jpg ) - -借助发明者量化交易平台,短短 80 行代码,一个完整的区块链 BTC 动态平衡策略应运而生。但这么简单的策略,究竟有没有价值呢? - -接下来,让我们测试一下这个简单的动态平衡策略,看看到底有没有效果。以下是在 BTC 的历史数据上的回测,仅供大家参考。 - - -### 回测环境 -[]( https://dn-filebox.qbox.me/e9ffd2a1451dc0c2b31a20cd1a54697567d1e561.png ) - - -### 回测绩效 -[]( https://dn-filebox.qbox.me/2a1e1ff7497de19f707add137debc547a93ca4ba.png ) - - -### 回测曲线 -[]( https://dn-filebox.qbox.me/dcbcd9b31ade9b9ce72b0ed86aa82435d5a11ef5.png ) - - -再来一张,同时期 BTC 价格走势图 -[]( https://dn-filebox.qbox.me/ec84ecde879721f515b9db17200b5fded748fc76.png ) - - -有没有震精到你。 - - -BTC 已经持续了长达 8 个月下跌,甚至最大跌幅超过70%,这造成很多投资者对区块链资产失去信心。本篇策略累计收益高达 160%,年化收益风险比超过 5。对于一个这么简单的投资策略,这个投资回报率已经超过绝大多数梭哈的群众了。 - -本篇动态平衡策略,只有一个核心参数(threshold 阈值),是一个很简单的投资方法,追求的不是超额的收益,而是稳健的收益。与趋势策略相反,动态平衡策略却是逆势而动。在市场热的时候减仓降温,市场冷清的时候加仓蛰伏,有点类似宏观经济调控。其实,动态平衡策略正是秉承了价格不可预测的观念,同时又捕捉价格波动的一门手艺。动态平衡策略的关键核心在设定和调整资产配置比例,还有触发阈值。 - -鉴于篇幅原因,一篇文章没办法做到面面俱到,要知道文字之外,存乎一心。动态平衡策略最重要的是投资思想,你甚至可以把本篇中的单个 BTC 资产换成一篮子区块链资产组合。 -[]( ![IMG](https://www.fmz.com/upload/asset/3a38be32a654bdd0d7cc.png) ) - -最后,让我们以本杰明 · 格雷厄姆在《聪明的投资者》一书中的名言来结束本篇:股票市场并非一个能精确衡量价值的『 称重计 』,相反它是一个『 投票机 』,不计其数的人所做出的决定是一种理性和感性的掺杂物,有很多时候这些抉择和理性的价值评判相去甚远。投资的秘诀就是在价格远远低于内在价值时投资,并且相信市场趋势会回升。——本杰明 · 格雷厄姆《聪明的投资者》 - - -延伸阅读: -[区块链量化投资系列课程(1) - 简介](https://quantinfo.com/Article/View/818/Empty.html) -[区块链量化投资系列课程(2) - 认识数字货币](https://quantinfo.com/Article/View/819/Empty.html) -[区块链量化投资系列课程(3) - 跨期套利](https://quantinfo.com/Article/View/816/Empty.html) +沃伦 · 巴菲特的导师本杰明 · 格雷厄姆曾经在《聪明的投资者》一书中,曾经提到过一种股票债券动态平衡的交易模式。这种交易模式非常简单:把手中 50% 的资金投资于股票基金,剩下 50% 投资于债券基金。即股票和债券两者各占一半。根据固定间隔时间或市场变化进行一次资产再平衡,使股票资产和债券资产的比例恢复到初始的 1:1。这就是整个策略的全部逻辑,包含了什么时候买卖,以及买卖多少。够简单吧! +[点击阅读更多内容](https://www.fmz.com/bbs-topic/5062) > 策略参数 @@ -129,7 +34,7 @@ BTC 已经持续了长达 8 个月下跌,甚至最大跌幅超过70%,这造 start: 2018-01-01 00:00:00 end: 2018-08-01 11:00:00 period: 1m -exchanges: [{"eid":"OKCoin_EN","currency":"BTC"}] +exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ @@ -207,4 +112,4 @@ https://www.fmz.com/strategy/110545 > 更新时间 -2019-12-09 12:01:25 +2020-03-03 10:22:22 diff --git "a/\345\225\206\345\223\201\346\234\237\350\264\247\351\242\204\345\256\232\345\274\200\344\273\223\345\220\216\345\271\263\344\273\223\346\234\272\345\231\250\344\272\272.md" "b/\345\225\206\345\223\201\346\234\237\350\264\247\351\242\204\345\256\232\345\274\200\344\273\223\345\220\216\345\271\263\344\273\223\346\234\272\345\231\250\344\272\272.md" new file mode 100644 index 00000000..434a1ae3 --- /dev/null +++ "b/\345\225\206\345\223\201\346\234\237\350\264\247\351\242\204\345\256\232\345\274\200\344\273\223\345\220\216\345\271\263\344\273\223\346\234\272\345\231\250\344\272\272.md" @@ -0,0 +1,93 @@ + +> 策略名称 + +商品期货预定开仓后平仓机器人 + +> 策略作者 + +小草 + +> 策略描述 + +如题,可设定买入价格,买入成功后自动挂卖出价格卖出, + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Contract|MA005|交易合约| +|Direction|0|交易方向: 做多|做空| +|Open_Price|2090|开仓价格| +|Amount|10|开仓数量| +|Close_Price|2100|平仓价格| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2020-01-30 00:00:00 +end: 2020-02-28 00:00:00 +period: 5m +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +args: [["Direction",0]] +*/ + + +var buy = false +var trade_amount = 0 +function main(){ + while(true){ + if(exchange.IO("status")){ + exchange.SetContractType(Contract) + if(!buy){ + buy = true + if(Direction == 0){ + exchange.SetDirection('buy') + exchange.Buy(Open_Price, Amount) + }else{ + exchange.SetDirection('sell') + exchange.Sell(Open_Price, Amount) + } + } + pos = exchange.GetPosition() + if(pos && pos.length > 0){ + for(var i=0;i0){ + var cover_amount = math.min(Amount-trade_amount, pos[i].Amount-pos[i].FrozenAmount) + if(cover_amount >= 1){ + trade_amount += cover_amount + if(Direction == 0){ + exchange.SetDirection('closebuy_today') + exchange.Sell(Close_Price, cover_amount) + }else{ + exchange.SetDirection('closesell_today') + exchange.Buy(Close_Price, cover_amount) + } + } + } + } + } + } else { + LogStatus(_D(), "未连接CTP !") + Sleep(10000) + } + if(trade_amount >= Amount){ + Log('任务完成') + return + } + Sleep(1000) + } +} + +``` + +> 策略出处 + +https://www.fmz.com/strategy/187736 + +> 更新时间 + +2020-02-29 20:42:01 diff --git "a/\345\237\272\344\272\216\346\234\237\350\264\247\345\237\272\346\234\254\351\235\242\345\210\206\346\236\220\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" "b/\345\237\272\344\272\216\346\234\237\350\264\247\345\237\272\346\234\254\351\235\242\345\210\206\346\236\220\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" index 9914581c..cd2fecd1 100644 --- "a/\345\237\272\344\272\216\346\234\237\350\264\247\345\237\272\346\234\254\351\235\242\345\210\206\346\236\220\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" +++ "b/\345\237\272\344\272\216\346\234\237\350\264\247\345\237\272\346\234\254\351\235\242\345\210\206\346\236\220\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245.md" @@ -14,6 +14,8 @@ Hukybo > 源码 (python) ``` python + + '''backtest start: 2019-01-01 00:00:00 end: 2019-08-09 00:00:00 @@ -54,6 +56,8 @@ receipt_data = 0 profit_data = 0 # 日期转时间戳 + + def to_timestamp(date_str): times = date_str + " 00:00:00" time_array = time.strptime(times, "%Y-%m-%d %H:%M:%S") @@ -67,7 +71,8 @@ def date_arr(year, month, day): arr = [] for i in range((end - begin).days + 1): day = begin + datetime.timedelta(days=i) - arr.append([str(day).replace('-', ''), str(day), day.weekday() + 1, to_timestamp(str(day))]) + arr.append([str(day).replace('-', ''), str(day), + day.weekday() + 1, to_timestamp(str(day))]) return arr @@ -76,17 +81,19 @@ def spot_futures_diff_data(date, futures_name): global diff_data url = f"http://www.100ppi.com/sf2/day-{date}.html" try: - url_text = requests.get(url, headers=request_headers).text # , proxies=proxies + url_text = requests.get( + url, headers=request_headers).text # , proxies=proxies except BaseException: - print('获取基差数据失败') + Log('获取基差数据失败') return int(diff_data) soup = BeautifulSoup(url_text, "html5lib") - results = soup.select("#fdata")[0] - for i in results.find_all('tr'): - if len(i.find_all('td', text=futures_name)) > 0: - data = i.find_all('font')[0].text - if data is not None: - diff_data = data + if len(soup.select("#fdata")) > 0: + results = soup.select("#fdata")[0] + for i in results.find_all('tr'): + if len(i.find_all('td', text=futures_name)) > 0: + data = i.find_all('font')[0].text + if data is not None: + diff_data = data return int(diff_data) @@ -128,6 +135,7 @@ def spot_receipt_data(date, futures_name): return receipt_data total = 0 count = 0 + Log(url_text[0]) if url_text[0] == '{': for i in json.loads(url_text)['o_cursor']: if futures_name in i['VARNAME']: @@ -157,21 +165,21 @@ def main(): # threading.Thread(target=commodity_warehouse_receipt_arr, args=('天然橡胶',)).start() cfgA = { - "extension": { - "layout": 'single', - "col": 6, - "height": "500px", - }, - "title" : { - "text" : "基差图表" - }, - "xAxis" : { - "type" : "datetime" - }, - "series" : [{ - "name" : "基差", - "data" : [], - }] + "extension": { + "layout": 'single', + "col": 6, + "height": "500px", + }, + "title": { + "text": "基差图表" + }, + "xAxis": { + "type": "datetime" + }, + "series": [{ + "name": "基差", + "data": [], + }] } cfgB = { "extension": { @@ -179,15 +187,15 @@ def main(): "col": 6, "height": "500px", }, - "title" : { - "text" : "库存图表" + "title": { + "text": "库存图表" }, - "xAxis" : { - "type" : "datetime" - }, - "series" : [{ - "name" : "库存", - "data" : [], + "xAxis": { + "type": "datetime" + }, + "series": [{ + "name": "库存", + "data": [], }] } cfgC = { @@ -196,15 +204,15 @@ def main(): "col": 6, "height": "500px", }, - "title" : { - "text" : "仓单图表" + "title": { + "text": "仓单图表" + }, + "xAxis": { + "type": "datetime" }, - "xAxis" : { - "type" : "datetime" - }, - "series" : [{ - "name" : "仓单", - "data" : [], + "series": [{ + "name": "仓单", + "data": [], }] } cfgD = { @@ -213,15 +221,15 @@ def main(): "col": 6, "height": "500px", }, - "title" : { - "text" : "利润图表" + "title": { + "text": "利润图表" }, - "xAxis" : { - "type" : "datetime" - }, - "series" : [{ - "name" : "利润", - "data" : [], + "xAxis": { + "type": "datetime" + }, + "series": [{ + "name": "利润", + "data": [], }] } LogReset() @@ -242,9 +250,6 @@ def main(): Log(f'基差:{diff} 库存:{reserve} 仓单:{receipt} 日期:{i[1]}') - - - ``` > 策略出处 @@ -253,4 +258,4 @@ https://www.fmz.com/strategy/161412 > 更新时间 -2019-08-31 16:32:29 +2020-01-14 14:50:36 diff --git "a/\345\237\272\344\272\216\350\265\204\351\207\221\344\270\273\345\212\250\346\200\247\346\265\201\345\220\221\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245\357\274\210Bar\357\274\211.md" "b/\345\237\272\344\272\216\350\265\204\351\207\221\344\270\273\345\212\250\346\200\247\346\265\201\345\220\221\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245\357\274\210Bar\357\274\211.md" new file mode 100644 index 00000000..1493e6be --- /dev/null +++ "b/\345\237\272\344\272\216\350\265\204\351\207\221\344\270\273\345\212\250\346\200\247\346\265\201\345\220\221\347\232\204\344\272\244\346\230\223\347\255\226\347\225\245\357\274\210Bar\357\274\211.md" @@ -0,0 +1,143 @@ + +> 策略名称 + +基于资金主动性流向的交易策略(Bar) + +> 策略作者 + +Hukybo + +> 策略描述 + +#### 摘要 +价格不是上就是下,长期而言,价格的涨跌概率应各是50%,那么要正确预测未来的价格,就需要实时获取影响价格的全部因素,然后给每个因素一个正确权重,最后作出客观理性分析。要把影响价格的全部因素罗列出来,可能会写满整个屏幕。 + +概括为:全球经济环境、国家宏观政策、相关产业政策、供需关系、国际事件、利率与汇率、通货膨胀与紧缩、市场心理、未知因素等等。预测也就变成了一个工程浩大,又不可能完成的任务。所以很早的时候,我就明白市场不可预测。那么在市场中所有的预测,都变成了假设,交易也成了概率游戏,这就有意思了。 + +[点击阅读更多内容](https://www.fmz.com/bbs-topic/4961) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|contractType|rb000|合约类型| +|hgLen|50|周期长度| +|len|10|数据长度| +|openValve|4|开仓阈值| +|unit|true|单位| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2016-01-01 09:00:00 +end: 2019-12-31 15:00:00 +period: 1h +exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}] +*/ + +var p = $.NewPositionManager(); //调用商品期货交易类库 + +//持仓数据处理 +function positions(name) { + var self = {}; + var mp = _C(exchange.GetPosition); //获取持仓 + if (mp.length == 0) { + self.amount = 0; + } + for (var i = 0; i < mp.length; i++) { //持仓数据处理 + if (mp[i].ContractType == name) { + if (mp[i].Type == PD_LONG || mp[i].Type == PD_LONG_YD) { + self.amount = mp[i].Amount; + } else if (mp[i].Type == PD_SHORT || mp[i].Type == PD_SHORT_YD) { + self.amount = -mp[i].Amount; + } + self.profit = mp[i].Profit; + } else { + self.amount = 0; + } + } + return self; +} + +//行情数据处理函数 +function data() { + var self = {}; + var barVol = []; + var bars = _C(exchange.GetRecords); //获取bar数据 + if (bars.length < len * 2) { //控制bar数据数组的长度 + return; + } + for (var i = len; i > 0; i--) { + var barSub_1 = bars[bars.length - (i + 1)].Close - bars[bars.length - (i + 2)].Close; //计算当前收盘价与上个bar收盘价的价差 + if (barSub_1 > 0) { //如果价格涨了,就在数组里面添加正数 + barVol.push(bars[bars.length - (i + 1)].Volume * (bars[bars.length - (i + 1)].High - bars[bars.length - (i + 1)].Low)); + } else if (barSub_1 < 0) { //如果价格跌了,就在数组里面添加负数 + barVol.push(-bars[bars.length - (i + 1)].Volume * (bars[bars.length - (i + 1)].High - bars[bars.length - (i + 1)].Low)); + } + } + if (barVol.length > len) { + barVol.shift(); //释放多余的数据 + } + self.barIn = 0; + self.barOut = 0; + for (var v = 0; v < barVol.length; v++) { + if (barVol[v] > 0) { + self.barIn += barVol[v]; //合并全部主动流入的资金 + } else { + self.barOut -= barVol[v]; //合并全部主动流出的资金 + } + } + self.barRatio = self.barIn / Math.abs(self.barOut); //计算主动流入资金与主动流出资金的比值 + bars.pop(); //删除未结束的bar数据 + self.close = bars[bars.length - 1].Close; //获取上根K线的收盘价 + self.hh = TA.Highest(bars, hgLen, 'High'); //获取前高 + self.ll = TA.Lowest(bars, hgLen, 'Low'); //获取前低 + return self; +} + +//交易函数 +function trade() { + var myData = data(); //执行data函数 + if (!myData) { + return; + } + var mp = positions(contractType); //获取持仓信息 + var myAmount = mp.amount; //获取持仓数量 + var myProfit = mp.profit; //获取持仓浮动盈亏 + if (myAmount > 0 && myData.close < myData.ll) { + p.Cover(contractType, unit); //多头平仓 + } + if (myAmount < 0 && myData.close > myData.hh) { + p.Cover(contractType, unit); //空头平仓 + } + if (myAmount == 0) { + if (myData.barRatio > openValve) { + p.OpenLong(contractType, unit); //多头开仓 + } else if (myData.barRatio < 1 / openValve) { + p.OpenShort(contractType, unit); //空头开仓 + } + } +} + +//程序主入口,从这里启动 +function main() { + while (true) { //进入循环 + if (exchange.IO("status")) { //如果是开市时间 + _C(exchange.SetContractType, contractType); //订阅合约 + trade(); //执行trade函数 + } + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/87698 + +> 更新时间 + +2020-01-21 15:29:52 diff --git "a/\345\244\247\344\270\255\345\260\217\344\270\211\345\221\250\346\234\237\350\267\203\350\277\201\347\255\226\347\225\245V2.0_\347\216\260\350\264\247.md" "b/\345\244\247\344\270\255\345\260\217\344\270\211\345\221\250\346\234\237\350\267\203\350\277\201\347\255\226\347\225\245V2.0_\347\216\260\350\264\247.md" new file mode 100644 index 00000000..bd96e983 --- /dev/null +++ "b/\345\244\247\344\270\255\345\260\217\344\270\211\345\221\250\346\234\237\350\267\203\350\277\201\347\255\226\347\225\245V2.0_\347\216\260\350\264\247.md" @@ -0,0 +1,248 @@ + +> 策略名称 + +大中小三周期跃迁策略V2.0_现货 + +> 策略作者 + +tomjava + +> 策略描述 + +大中小三周期跃迁策略。总的来说,就是大周期指明了市场方向,中周期是当前的操作周期,小周期指出了趋势止步信号。当你进场时,只要你参看了大中小三周期的状态,就可如诸葛亮一般,采取千变万化的策略来应付复杂的市场。如果你的操作周期频率是一天几次,那大周期可以选择日线,中周期可以选择4小时,小周期可以选择30分钟;如果你的操作周期频率是一天几十次,那大周期可以选择4小时,中周期可以选择30分钟,小周期可以选择5分钟;上一个周期始终和下一个周期相差6倍到8倍。 +然后我们再把每个周期的K线与布林线的关系罗列出来,一共有8种状态,三个周期就有8*8*8=512种状态,这512种状态足以应付所有可能出现的盘面,技术能力强的程序员可以把每一种状态的最佳下单点位和止损点位预先设计出来。为了大家有一个讨论的基础,区班主也在发明者平台把策略公开了,欢迎大家在此基础上进行完善。 +然后我们来回测一下,我们可以看到年化29,回撤有点高,达到36%。我们把日志下载下来,并针对回撤进行分析,这就是发明者平台的优势。 + ![IMG](https://www.fmz.com/upload/asset/13120536c7fe04832dbcb.png) + ![IMG](https://www.fmz.com/upload/asset/131192810d7ecb2b1d1ef.png) + ![IMG](https://www.fmz.com/upload/asset/130ed64aa7da2ceabc187.png) +分析下来,主要有以下几个原因: +1、大中小周期架构虽然比较好,但是小周期对中周期怎样影响的策略不好构思,可以先简化,后面再补上; +2、行情走空时,应该坚决抛弃仓位 +3、5日均线的指向作用很重要,在策略里没有体现 +4、布林线之外的快速下跌,应该抛售 +5、上涨理由跌破时,应该及时止盈和止损 + ![IMG](https://www.fmz.com/upload/asset/1310b2148822a81917ce8.png) ![IMG](https://www.fmz.com/upload/asset/13173d3b37858cf619f9e.png) +经过有针对性的改进后,迭代了几十次,我们终于把年化率做到了210,回撤为16.4,交易次数也降了下来。 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|Interval|10|轮询周期(秒)| + + +> 源码 (javascript) + +``` javascript +/*backtest +start: 2019-01-01 00:00:00 +end: 2019-10-10 00:00:00 +period: 1d +exchanges: [{"eid":"OKEX","currency":"ETH_USDT","stocks":0}] +args: [["OpMode",1,10989],["MaxAmount",1,10989],["TradeFee",0.001,10989]] +*/ +//注册币乎后https://m.bihu.com/signup?i=1ewtKO&s=4&c=4 +//搜索 物联网区块链 可以联系到作者区班主 +var midStatus = 0; //中周期状态 +var bigStatus = 0; //大周期状态 +var beforeBigStatus = 0; //之前大周期状态 +var operPrice; +var markTime=0; + +function mySell(rate){ + var account = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + var nowPrice=ticker.Sell; + + //以下开始卖出 + var allAmount=account.Balance+account.Stocks*ticker.Sell; //计算出总金额 + var cashRatio=account.Balance*100/allAmount; + + if(cashRatio<90){ //现金比率小于10,才可以卖出 + if(rate==1){ //卖出1份 + if(cashRatio<80){ + $.Sell(allAmount*0.1/nowPrice); + Log("现金比率",cashRatio+10); + }else{ + $.Sell(allAmount*0.05/nowPrice); + Log("现金比率",cashRatio+5); + } + }else{ + if(cashRatio<75){ + $.Sell(allAmount*0.2/nowPrice); + Log("现金比率",cashRatio+20); + }else{ + $.Sell(allAmount*0.1/nowPrice); + Log("现金比率",cashRatio+10); + } + } + } +} + +function myBuy(rate){ + var account = _C(exchange.GetAccount); + var ticker = _C(exchange.GetTicker); + var nowPrice=ticker.Sell; + + //以下开始买入 + var allAmount=account.Balance+account.Stocks*ticker.Sell; //计算出总金额 + var cashRatio=account.Balance*100/allAmount; + //Log("需要买入比率",rate); + if(cashRatio>10){ //现金比率大于10,才可以买入 + if(rate==1){ //买入1份 + if(cashRatio>20){ + $.Buy(allAmount*0.1/nowPrice); + Log("现金比率",cashRatio-10); + }else{ + $.Buy(allAmount*0.05/nowPrice); + Log("现金比率",cashRatio-5); + } + }else{ + if(cashRatio>25){ + $.Buy(allAmount*0.2/nowPrice); + Log("现金比率",cashRatio-20); + }else{ + $.Buy(allAmount*0.1/nowPrice); + Log("现金比率",cashRatio-10); + } + } + } +} + +function oper(){ + var ticker = _C(exchange.GetTicker); + var nowPrice=ticker.Sell; + + var h1records = exchange.GetRecords(PERIOD_H1); + var h1boll;var h1upLine;var h1midLine;var h1downLine; + var h1bw; + if(h1records && h1records.length > 20) { + h1boll = TA.BOLL(h1records, 20, 2); + h1upLine = h1boll[0][h1records.length-1]; + h1midLine = h1boll[1][h1records.length-1]; + h1downLine = h1boll[2][h1records.length-1]; + } + + var drecords = exchange.GetRecords(PERIOD_D1); + var dboll;var dupLine;var dmidLine;var ddownLine; + var dbw;var beforePrice; + if(drecords && drecords.length > 20) { + dboll = TA.BOLL(drecords, 20, 2); + dupLine = dboll[0][drecords.length-1]; + dmidLine = dboll[1][drecords.length-1]; + ddownLine = dboll[2][drecords.length-1]; + dbw=dupLine-dmidLine; + beforePrice=(drecords[drecords.length-2].Open+drecords[drecords.length-2].Close)/2; + } + + if(ticker.Time-markTime<15*60*1000){ //只有满足15分钟间隔,才允许判断状态 + return; + }else{ + markTime=ticker.Time; + } + + if(h1records && h1records.length > 20 && drecords && drecords.length > 20) { + if(nowPrice>dupLine+dbw*0.1){ + bigStatus=0; + }else if(nowPrice>dupLine-dbw*0.1){ + bigStatus=1; + }else if(nowPrice>dmidLine+dbw*0.1){ + bigStatus=2; + }else if(nowPrice>dmidLine){ + bigStatus=3; + }else if(nowPrice>dmidLine-dbw*0.1){ + bigStatus=4; + }else if(nowPrice>ddownLine+dbw*0.1){ + bigStatus=5; + }else if(nowPrice>ddownLine-dbw*0.1){ + bigStatus=6; + }else{ + bigStatus=7; + } + + if(beforePrice>dupLine+dbw*0.1){ + beforeBigStatus=0; + }else if(beforePrice>dupLine-dbw*0.1){ + beforeBigStatus=1; + }else if(beforePrice>dmidLine+dbw*0.1){ + beforeBigStatus=2; + }else if(beforePrice>dmidLine){ + beforeBigStatus=3; + }else if(beforePrice>dmidLine-dbw*0.1){ + beforeBigStatus=4; + }else if(beforePrice>ddownLine+dbw*0.1){ + beforeBigStatus=5; + }else if(beforePrice>ddownLine-dbw*0.1){ + beforeBigStatus=6; + }else{ + beforeBigStatus=7; + } + + if(nowPrice>h1upLine+h1bw*0.1){ + midStatus=0; + }else if(nowPrice>h1upLine-h1bw*0.1){ + midStatus=1; + }else if(nowPrice>h1midLine+h1bw*0.1){ + midStatus=2; + }else if(nowPrice>h1midLine){ + midStatus=3; + }else if(nowPrice>h1midLine-h1bw*0.1){ + midStatus=4; + }else if(nowPrice>h1downLine+h1bw*0.1){ + midStatus=5; + }else if(nowPrice>h1downLine-h1bw*0.1){ + midStatus=6; + }else{ + midStatus=7; + } + + if(bigStatus-beforeBigStatus>0){ //当前有一个大周期下跌跃迁 + if(midStatus==6||midStatus==7){ + //Log("卖2份 当大",bigStatus,"前大",beforeBigStatus,"中",midStatus); + //买2份 + mySell(2); + }else if(midStatus==3||midStatus==4){ + //Log("卖1份 当大",bigStatus,"前大",beforeBigStatus,"中",midStatus); + //买1份 + mySell(1); + }else{ + //Log("当大",bigStatus,"前大",beforeBigStatus,"中",midStatus); + } + }else if(bigStatus-beforeBigStatus<0){ //当前有一个大周期上涨跃迁 + if(midStatus==6||midStatus==7){ + //Log("买2份 当大",bigStatus,"前大",beforeBigStatus,"中",midStatus); + //买2份 + myBuy(2); + }else if(midStatus==3||midStatus==4){ + //Log("买1份 当大",bigStatus,"前大",beforeBigStatus,"中",midStatus); + //买1份 + myBuy(1); + }else{ + //Log("当大",bigStatus,"前大",beforeBigStatus,"中",midStatus); + } + }else{ + //Log("当大",bigStatus,"前大",beforeBigStatus,"中",midStatus," dup",dupLine," 长度",dboll[0].length); + } + } +} + +function main() { + var initAccount = _C(exchange.GetAccount); + Log(initAccount); + + while (true) { + oper(); + Sleep(Interval*1000); + } +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/177631 + +> 更新时间 + +2020-01-16 13:50:52 diff --git "a/\345\256\232\351\207\217\345\210\206\345\236\213\351\200\237\347\216\207\344\272\244\346\230\223\347\255\226\347\225\245-by:\346\263\212\345\256\207\351\207\217\345\214\226.md" "b/\345\256\232\351\207\217\345\210\206\345\236\213\351\200\237\347\216\207\344\272\244\346\230\223\347\255\226\347\225\245-by:\346\263\212\345\256\207\351\207\217\345\214\226.md" new file mode 100644 index 00000000..577ed7d8 --- /dev/null +++ "b/\345\256\232\351\207\217\345\210\206\345\236\213\351\200\237\347\216\207\344\272\244\346\230\223\347\255\226\347\225\245-by:\346\263\212\345\256\207\351\207\217\345\214\226.md" @@ -0,0 +1,47 @@ + +> 策略名称 + +定量分型速率交易策略-by:泊宇量化 + +> 策略作者 + +homily + + + + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2019-01-01 00:00:00 +end: 2020-02-24 00:00:00 +period: 1h +exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD","fee":[0.05,0.05]}] +args: [["TradeAmount",200,126961],["ContractType","quarter",126961]] +*) + +len:=35;//设计周期数 + +hh^^HHV(H,len);//取一定周期内的最高价 +ll^^LLV(L,len);//取一定周期内的最低价 +hl2^^(hh+ll)/2;//最高价、最低价的平均值 +avg^^MA(hl2,5);//对平均值计算平滑移动均线 + +ss:SLOPE(avg,len);// 对均线计算回归斜率 + +ssREF(ss,1),BPK;//当斜率变大说明行情动能不断增加,有上升趋势,平空做多 +AUTOFILTER; + + +``` + +> 策略出处 + +https://www.fmz.com/strategy/183416 + +> 更新时间 + +2020-02-25 14:09:34 diff --git "a/\346\227\245\345\277\227|Logger.md" "b/\346\227\245\345\277\227|Logger.md" index 74ec2ce7..dc8dcb4f 100644 --- "a/\346\227\245\345\277\227|Logger.md" +++ "b/\346\227\245\345\277\227|Logger.md" @@ -71,4 +71,4 @@ https://www.fmz.com/strategy/151754 > 更新时间 -2019-06-19 08:12:16 +2020-01-20 10:17:59 diff --git "a/\346\232\264\351\233\252\347\275\221\346\240\274-7*24\345\260\217\346\227\266\344\272\244\346\230\223\346\234\272\345\231\250\344\272\272\357\274\214\346\257\217\346\227\245\346\233\264\346\226\260\345\256\236\347\233\230\346\225\210\346\236\234.md" "b/\346\232\264\351\233\252\347\275\221\346\240\274-7*24\345\260\217\346\227\266\344\272\244\346\230\223\346\234\272\345\231\250\344\272\272\357\274\214\346\257\217\346\227\245\346\233\264\346\226\260\345\256\236\347\233\230\346\225\210\346\236\234.md" new file mode 100644 index 00000000..f66aa36e --- /dev/null +++ "b/\346\232\264\351\233\252\347\275\221\346\240\274-7*24\345\260\217\346\227\266\344\272\244\346\230\223\346\234\272\345\231\250\344\272\272\357\274\214\346\257\217\346\227\245\346\233\264\346\226\260\345\256\236\347\233\230\346\225\210\346\236\234.md" @@ -0,0 +1,190 @@ + +> 策略名称 + +暴雪网格-7*24小时交易机器人,每日更新实盘效果 + +> 策略作者 + +红色的雪 + + + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|base_price|3|基础价格-中线价格| +|sale_buy_diff|0.03|买卖差价,卖出的价格- 买入的价格| +|two_distance|0.01|递增、递减的时候,每个格子的距离| +|trade_amount|2|每次交易的数量| +|sale_price_max|5|卖出的上限价格| +|buy_price_min|true|买入的上限价格| + + +> 源码 (python) + +``` python +#!python2 +# -*- coding:utf-8 -*- +''' +主要是使用发明者量化API进行网格买卖,当前只支持单品网格买卖 +''' +from time import sleep +import datetime,copy + +sale_price_list = [] #卖出的价格列表 +buy_price_list = [] #买入的价格列表 + +class fmz_market(): + def get_data_depth(self): + data_depth = exchange.GetDepth() + return data_depth + + + + #检查当前是否可以进行买卖操作 + def make_trade_check(self,symbol): + trade_infor = {'price':0,'trade_type':''} + #进行买卖列表判断,先更新交易记录列表 + trade_price_list = self.get_trade_price_list(symbol) + sale_price_list = trade_price_list[0] + buy_price_list = trade_price_list[1] + #获取深度数据 + data_depth = self.get_data_depth() + #买单列表: + data_depth_bids = data_depth.Bids[0] + #卖单列表: + data_depth_asks = data_depth.Asks[0] + #如果买入记录不为空 + sale_buy_diff_now = two_distance*len(sale_price_list) if len(sale_price_list) >0 else sale_buy_diff + sale_buy_diff_sale = two_distance if len(sale_price_list) > 0 else sale_buy_diff + # sale_price_last = float(sale_price_list[len(sale_price_list)-1]) if len(sale_price_list) >0 else base_price + # buy_price_last = float(buy_price_list[len(buy_price_list)-1]) if len(buy_price_list) >0 else base_price + sale_price_last = float(sale_price_list[0]) if len(sale_price_list) > 0 and float(sale_price_list[0]) > base_price else base_price + buy_price_last = float(buy_price_list[0]) if len(buy_price_list) > 0 and float(buy_price_list[0]) < base_price else base_price + #判断当前价格是否满足 卖出的价格请求 + if float(data_depth_bids.Price) - sale_price_last > sale_buy_diff_sale and float(data_depth_bids.Amount) > trade_amount * 1.5: + Log("当前卖价:",str(data_depth_bids.Price),"订单中最高卖价:",str(sale_price_last),"生成卖单") + trade_infor['price'] = float(data_depth_bids.Price) + trade_infor['trade_type'] = 'sale' + #判断当前价格是否满足 买入的价格请求 + if buy_price_last - float(data_depth_asks.Price) > sale_buy_diff_now and float(data_depth_bids.Amount) > trade_amount * 1.5: + #Log("当前买价:", str(data_depth_asks.Price), "订单中最高买价:", str(sale_price_last),"生成买单") + trade_infor['price'] = float(data_depth_bids.Price) + trade_infor['trade_type'] = 'buy' + #判断当前价格是否破格,破格则置空买卖信息 + if float(data_depth_bids.Price) - sale_price_max > 0 or buy_price_min - float(data_depth_asks.Price) > 0: + trade_infor['price'] = 0 + trade_infor['trade_type'] = '' + timestr = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S') + Log(trade_infor,"...time:",timestr) + if trade_infor['price'] != 0: + #Log(trade_infor,"...time:",timestr) + pass + return trade_infor + + #根据委托信息生成买卖价格列表 + def get_trade_price_list(self,symbol): + sale_list = [] + buy_list = [] + #获取所有的交易记录,根据不同的类型 分配到 买卖列表中 + orders = exchange.GetOrders() + for i in range(len(orders)): + if orders[i].Type == 1: + sale_price = float(orders[i].Price) + sale_price_bak = copy.deepcopy(sale_price) + sale_list.append(sale_price_bak) + if orders[i].Type == 0: + buy_price = float(orders[i].Price) + buy_price_bak = copy.deepcopy(buy_price) + buy_list.append(buy_price_bak) + #判断为0的数组进处理 + if len(sale_list) == 0: + for i in range(len(buy_list)): + sale_list.append(float('%.6f' % (buy_list[i] + sale_buy_diff))) + if len(buy_list) == 0: + for i in range(len(sale_list)): + buy_list.append(float('%.6f' % (sale_list[i] - sale_buy_diff))) + trade_price_list = [sale_list,buy_list] + return trade_price_list + + #网格交易入口: + def grid_trade_start(self,symbol): + #进行状态获取,上涨/下跌 + # trend_status = self.kline_trend_check(symbol) + + #获取可否进行交易 + trade_infor = self.make_trade_check(symbol) + #进行判断是否交易,判断是否可以卖出 + # if trend_status == 'is_up' and trade_infor['price'] > 0 and trade_infor['trade_type'] == 'sale': + if trade_infor['price'] > 0 and trade_infor['trade_type'] == 'sale': + buy_price = float('%.6f' % (trade_infor['price'] - sale_buy_diff)) + #调用下单功能,先调用卖,再调用买 + order_id = exchange.Sell(trade_infor['price'], trade_amount) + #Log('order_id:',order_id) + #检查下单是否成功,不成功,则直接返回 + if order_id is None: + Log("下单失败,等待600s继续.........") + sleep(600) + return 0 + #检查主交易是否成功:判断卖单单是否交易成功,交易成功则进行买单下单 + for i in range(100): + sale_orders = exchange.GetOrder(order_id) + #Log('sale_orders:',sale_orders) + if sale_orders.Status == 1: + #如果卖单已成交,则进行买单提交 + exchange.Buy(buy_price, trade_amount) + return 0 + sleep(10) + #如果循环1000次还未成交,则取消订单 + exchange.CancelOrder(order_id) + # 进行判断是否交易,判断是否可以买入 + if trade_infor['price'] > 0 and trade_infor['trade_type'] == 'buy': + sale_price = float('%.6f' % (trade_infor['price'] + sale_buy_diff)) + # 调用下单功能,先调用买入,再调用卖出 + order_id = exchange.Buy(trade_infor['price'], trade_amount) + # 检查下单是否成功,不成功,则直接返回 + if order_id is None: + #Log("下单失败,等待600s继续.........") + sleep(600) + return 0 + # 检查主交易是否成功:判断买单是否交易成功,交易成功则进行卖单下单 + for i in range(100): + buy_orders = exchange.GetOrder(order_id) + if buy_orders.Status == 1: + # 如果买单已成交,则进行卖单提交 + exchange.Sell(sale_price, trade_amount) + return 0 + sleep(10) + # 如果循环1000次还未成交,则取消订单 + exchange.CancelOrder(order_id) + + #进行循环调用 + def grid_trade_cycle(self,symbol): + cycle_num = 0 + while(True): + timestr = (datetime.datetime.now()).strftime('%H%M%S') + self.grid_trade_start(symbol) + sleep(10) + cycle_num = cycle_num + 1 + if cycle_num % 100 == 0: + account_infor = exchange.GetAccount() + Log("当前用户的账号信息:%s,....当前已循环检查次数:%s"%(account_infor,str(cycle_num))) + +def main(): + Log(exchange.GetAccount()) + Log("测试") + fmz_market_instances = fmz_market() + fmz_market_instances.grid_trade_cycle(100) + #order_id = exchange.Sell(10000,1) +``` + +> 策略出处 + +https://www.fmz.com/strategy/175807 + +> 更新时间 + +2020-03-06 14:36:28 diff --git "a/\346\240\207\345\256\232\345\200\274\346\210\226\345\235\207\347\272\277\344\272\244\345\217\211\347\255\226\347\225\245.md" "b/\346\240\207\345\256\232\345\200\274\346\210\226\345\235\207\347\272\277\344\272\244\345\217\211\347\255\226\347\225\245.md" new file mode 100644 index 00000000..8604b1c2 --- /dev/null +++ "b/\346\240\207\345\256\232\345\200\274\346\210\226\345\235\207\347\272\277\344\272\244\345\217\211\347\255\226\347\225\245.md" @@ -0,0 +1,70 @@ + +> 策略名称 + +标定值或均线交叉策略 + +> 策略作者 + +cyberking + +> 策略描述 + +标定值 + 高点> btc 10000 || MA(10)MA(30)则买入; + Stoploss为8 , 8%止损点. + 周期按日线.回测数据还可以;低于日线周期回测数据不好. + 本策略是用的趋势指标. +*取10000和6725的理由是根据江恩的思路. + ![IMG](https://www.fmz.com/upload/asset/149338fe3f9011badc20c.png) ![IMG](https://www.fmz.com/upload/asset/14947231d56707e5f7e8c.png) + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|HGH|10000|高点| +|MMD|6725|中坚点| +|STOPLOSS|8|止损数| + + +> 源码 (麦语言) + +``` pascal +(*backtest +start: 2019-01-05 00:00:00 +end: 2020-02-29 00:00:00 +period: 1d +exchanges: [{"eid":"Huobi","currency":"BTC_USDT"}] +*) +// +MA10:=MA(C,10); +MA30:=MA(C,30); + +买入开仓价:=VALUEWHEN(BARSBK=1,O); +卖出开仓价:=VALUEWHEN(BARSSK=1,O); +//开仓条件 + +BUYCONDITION:=REF(C,1) < MMD OR CROSSUP(MA10,MA30); +SELLCONDITION:=REF(C,1) > HGH OR CROSSDOWN(MA10,MA30); + +BKVOL=0 AND BUYCONDITION,BK; +SKVOL=0 AND SELLCONDITION,SK; + +//离场条件 +BKVOL>0 AND SELLCONDITION,SP; +SKVOL>0 AND BUYCONDITION,BP; +// 启动止损 +SKVOL>0 AND HIGH>=卖出开仓价*(1+STOPLOSS*0.01),BP; +BKVOL>0 AND LOW<=买入开仓价*(1-STOPLOSS*0.01),SP; +AUTOFILTER; +``` + +> 策略出处 + +https://www.fmz.com/strategy/187874 + +> 更新时间 + +2020-03-02 11:22:35 diff --git "a/\346\265\267\351\276\237\347\255\226\347\225\245btc\347\216\260\350\264\247\347\211\210.md" "b/\346\265\267\351\276\237\347\255\226\347\225\245btc\347\216\260\350\264\247\347\211\210.md" new file mode 100644 index 00000000..67bed761 --- /dev/null +++ "b/\346\265\267\351\276\237\347\255\226\347\225\245btc\347\216\260\350\264\247\347\211\210.md" @@ -0,0 +1,132 @@ + +> 策略名称 + +海龟策略btc现货版 + +> 策略作者 + +groot + +> 策略描述 + +看到平台上没有公开的python海龟策略,自己写个简单的抛个砖。 +接近原版的海龟系统,没怎么优化,当做回测试验吧,也可以自己再优化下接实盘跑。 + +开仓:超过唐奇安上轨开仓 +加仓:超过之前的价格的0.5ATR就加仓 +止损止盈:跌破下轨或者跌破上次开仓价-2ATR就全部止盈 + +回测了1年数据,年化80%,最大回撤16% + +现货资金利用率较低,改成合约版后收益会更高。 + +> 策略参数 + + + +|参数|默认值|描述| +|----|----|----| +|fresh_rete|24|交易频率(小时)| +|trade_percent|0.01|资产比率| +|DC_range|30|通道周期数| +|atrlength|24|atr周期数| + + +> 源码 (python) + +``` python +'''backtest +start: 2019-01-01 00:00:00 +end: 2020-03-02 00:00:00 +period: 1d +exchanges: [{"eid":"OKEX","currency":"BTC_USDT","stocks":0}] +args: [["fresh_rete",24],["DC_range",20],["atrlength",14]] +''' + + +import numpy as np +import pandas as pd +import datetime + + +data = {'ordertime':[],'id':[],'price':[]} +hisorder = pd.DataFrame(data) + +def turtle(): + #声明全局变量 + global hisorder + + acct = exchange.GetAccount() + + records=exchange.GetRecords(fresh_rete*60*60) + + ticker = exchange.GetTicker() + + + portfolio_value = acct.Balance+acct.FrozenBalance+(acct.Stocks+acct.FrozenStocks)*records[-1]['Close'] + atr = TA.ATR(records, atrlength)[-1] + #计算得到unit大小 + value = portfolio_value*trade_percent + unit = min(round(value/atr,4),round(acct.Balance/(ticker['Last']+100),4)) + #unit = round(value/atr,2) + + df = pd.DataFrame(records) + current_price = records[-1]['Close'] + last_price = 0 + if len(hisorder)!=0: + last_price = hisorder.iloc[-1]['price'] + max_price = df[-DC_range:-2]['High'].max() + min_price = df[-int(DC_range/2):-2]['Low'].min() + + opensign = len(hisorder)==0 and current_price > max_price + + + addsign = len(hisorder)!=0 and current_price > last_price + 0.5*atr + + + stopsign = len(hisorder)!=0 and current_price < min_price + + + closesign = len(hisorder)!=0 and current_price < (last_price - 2*atr) + + +# if _D(records[-1]['Time']/1000) == '2020-01-25 00:00:00': +# Log("records[-1]",records[-1]) + + + + + + if opensign | addsign: + if acct.Balance >= (ticker['Last']+10)*unit and unit >0: + id = exchange.Buy(ticker['Last']+10,unit) + orderinfo = exchange.GetOrder(id) + data = {'ordertime':_D(records[-1]['Time']/1000),'id':id,'price':records[-1]['Close']} + hisorder = hisorder.append(data,ignore_index=True) + Log('买入后,最新账户信息:', exchange.GetAccount()) + Log("opensign",opensign,"addsign",addsign) + # else: + # Log('余额已不足,请充值......', exchange.GetAccount()) + if stopsign | closesign: + exchange.Sell(-1, acct.Stocks+acct.FrozenStocks) + data = {'ordertime':[],'id':[],'price':[]} + hisorder = pd.DataFrame(data) + Log('卖出后,最新账户信息:', exchange.GetAccount()) + Log("stopsign",stopsign,"closesign",closesign) + + + + +def main(): + while True: + turtle() + Sleep(fresh_rete*60*60*1000) +``` + +> 策略出处 + +https://www.fmz.com/strategy/186598 + +> 更新时间 + +2020-03-06 12:04:41 diff --git "a/\346\267\261\345\272\246\345\277\253\347\205\247.md" "b/\346\267\261\345\272\246\345\277\253\347\205\247.md" new file mode 100644 index 00000000..5a3fe20e --- /dev/null +++ "b/\346\267\261\345\272\246\345\277\253\347\205\247.md" @@ -0,0 +1,38 @@ + +> 策略名称 + +深度快照 + +> 策略作者 + +发明者量化 + + + + + +> 源码 (javascript) + +``` javascript +function main() { + var tbl = { + type: 'table', + title: '深度快照 @ ' + _D(), + cols: ['#', 'Amount', 'Ask', 'Bid', 'Amount'], + rows: [] + }; + var d = exchange.GetDepth(); + for (var i = 0; i < Math.min(Math.min(d.Asks.length, d.Bids.length), 15); i++) { + tbl.rows.push([i, d.Asks[i].Amount, d.Asks[i].Price+'#ff0000', d.Bids[i].Price+'#0000ff', d.Bids[i].Amount]); + } + return tbl; +} +``` + +> 策略出处 + +https://www.fmz.com/strategy/187969 + +> 更新时间 + +2020-03-01 23:49:04 diff --git "a/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.md" "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.md" index 3ad6845c..d7d83bab 100644 --- "a/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.md" +++ "b/\347\275\221\346\240\274\345\217\230\345\275\242\347\255\226\347\225\245\344\271\213\345\215\225\350\276\271\347\275\221\346\240\274.md" @@ -9,14 +9,14 @@ Zero > 策略描述 -网格可以自定义方向 -先买后卖: -网格会从首价格开始向下挂买单, 每个买单间隔 "价格间隔" 这个参数, 挂单数量为"单笔数量", 挂够 "总数量" 个买单, 有任意买单成交以后, 程序会在买价基础上加 "价差(元)" 这个参数的的值的价格挂出卖单, 卖出, 卖出以后,重新按原来这个网格的价格挂买入单 -先卖后买: -操作刚好相反 - -策略最大的风险就是单边行情, 价格波动超出网格范围. - +网格可以自定义方向 +先买后卖: +网格会从首价格开始向下挂买单, 每个买单间隔 "价格间隔" 这个参数, 挂单数量为"单笔数量", 挂够 "总数量" 个买单, 有任意买单成交以后, 程序会在买价基础上加 "价差(元)" 这个参数的的值的价格挂出卖单, 卖出, 卖出以后,重新按原来这个网格的价格挂买入单 +先卖后买: +操作刚好相反 + +策略最大的风险就是单边行情, 价格波动超出网格范围. + 网格带有自动止损和移动功能 > 策略参数 @@ -196,7 +196,7 @@ function Trader() { return orders; } this.GetOrder = function(orderId) { - if (typeof(orderId) === 'number') { + if (orderId && orderId.toString().indexOf("V") != 0) { return exchange.GetOrder(orderId); } if (typeof(hisBooks[orderId]) !== 'undefined') { @@ -242,7 +242,7 @@ function Trader() { var pfn = order.Type == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell; if (order.Id == 0 && diff <= priceDiff) { var realId = pfn(order.Price, order.Amount, order.Extra + "(距离: " + diff + (order.Type == ORDER_TYPE_BUY ? (" 买一: " + ticker.Buy) : (" 卖一: " + ticker.Sell))+")"); - if (typeof(realId) === 'number') { + if (realId) { order.Id = realId; } } else if (order.Id > 0 && diff > (priceDiff + 1)) { @@ -585,13 +585,13 @@ function fishing(orgAccount, fishCount) { if (state == STATE_WAIT_COVER) { var coverId = CoverFunc(coverPrice, (BuyFirst ? amountS[idx] : amountB[idx]), (BuyFirst ? '完成买单:' : '完成卖单:'), openPrice, '量:', (BuyFirst ? amountB[idx] : amountS[idx])); - if (typeof(coverId) === 'number' || typeof(coverId) === 'string') { + if (coverId) { fishTable[idx] = STATE_WAIT_CLOSE; uuidTable[idx] = coverId; } } else if (state == STATE_WAIT_OPEN || state == STATE_WAIT_CLOSE) { var openId = OpenFunc(openPrice, BuyFirst ? amountB[idx] : amountS[idx]); - if (typeof(openId) === 'number' || typeof(openId) === 'string') { + if (openId) { fishTable[idx] = STATE_WAIT_COVER; uuidTable[idx] = openId; if (state == STATE_WAIT_CLOSE) { @@ -672,4 +672,4 @@ https://www.fmz.com/strategy/629 > 更新时间 -2018-04-08 12:23:15 +2020-02-04 16:33:32 diff --git "a/\350\216\267\345\217\226\346\234\200\346\226\260\347\226\253\346\203\205|Fetch nCoV News.md" "b/\350\216\267\345\217\226\346\234\200\346\226\260\347\226\253\346\203\205|Fetch nCoV News.md" new file mode 100644 index 00000000..7be88fbc --- /dev/null +++ "b/\350\216\267\345\217\226\346\234\200\346\226\260\347\226\253\346\203\205|Fetch nCoV News.md" @@ -0,0 +1,70 @@ + +> 策略名称 + +获取最新疫情|Fetch nCoV News + +> 策略作者 + +fmzero + +> 策略描述 + +病毒无情,人间有爱。 +FMZ一直有情怀。 +丁香园一直做实时发布疫情发展情况,而我想通过FMZ的`HttpQuery`爬取其实时信息。并用Log(...&)推送至微信公众号上,用LogStatus展现信息(有人说可能没卵用)。 +这就是温度。 +如下代码未能实现正则表达式过滤信息,仅仅是一个半成品。望大神助力 + +[温度](https://www.fmz.com/strategy/182505) + + + + +> 源码 (javascript) + +``` javascript +// 有温度的FMZ + +var url = 'https://3g.dxy.cn/newh5/view/pneumonia' +var newsRegex = "/