Name
数字货币现货多品种双均线策略教学
Author
小小梦
Strategy Description
相关文章:https://www.fmz.com/bbs-topic/8512
Strategy Arguments
Argument | Default | Description |
---|---|---|
symbols | ETH_USDT,ETC_USDT,LTC_USDT | 交易对代码 |
ema1Periods | 10,15,20 | 第一个EMA指标 |
ema2Periods | 15,20,25 | 第二个EMA指标 |
orderAmounts | 1,1,1 | 下单量,币数 |
takeLevel | 10 | 吃单档位 |
isReset | false | 重置所有数据 |
Source (javascript)
function cancelAll(e) {
while (true) {
var orders = _C(e.GetOrders)
if (orders.length == 0) {
break
} else {
for (var i = 0 ; i < orders.length ; i++) {
e.CancelOrder(orders[i].Id, orders[i])
Sleep(500)
}
}
Sleep(500)
}
}
function getProfit(account, initAccount, lastPrices) {
var sum = 0
_.each(account, function(val, key) {
if (key != "USDT" && typeof(initAccount[key]) == "number" && lastPrices[key + "_USDT"]) {
sum += (account[key] - initAccount[key]) * lastPrices[key + "_USDT"]
}
})
return account["USDT"] - initAccount["USDT"] + sum
}
function createChartConfig(symbol, ema1Period, ema2Period) {
var chart = {
__isStock: true,
extension: {
layout: 'single',
height: 600,
},
title : { text : symbol},
xAxis: { type: 'datetime'},
series : [
{
type: 'candlestick',
name: symbol,
id: symbol,
data: []
}, {
type: 'line',
name: symbol + ',EMA1:' + ema1Period,
data: [],
}, {
type: 'line',
name: symbol + ',EMA2:' + ema2Period,
data: []
}
]
}
return chart
}
function main() {
// 重置所有数据
if (isReset) {
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("重置所有数据", "#FF0000")
}
// 解析参数
var arrSymbols = symbols.split(",")
var arrEma1Periods = ema1Periods.split(",")
var arrEma2Periods = ema2Periods.split(",")
var arrAmounts = orderAmounts.split(",")
var account = {}
var initAccount = {}
var currTradeMsg = {}
var lastPrices = {}
var lastBarTime = {}
var arrChartConfig = []
if (_G("currTradeMsg")) {
currTradeMsg = _G("currTradeMsg")
Log("恢复记录", currTradeMsg)
}
// 初始化account
_.each(arrSymbols, function(symbol, index) {
exchange.SetCurrency(symbol)
var arrCurrencyName = symbol.split("_")
var baseCurrency = arrCurrencyName[0]
var quoteCurrency = arrCurrencyName[1]
if (quoteCurrency != "USDT") {
throw "only support quoteCurrency: USDT"
}
if (!account[baseCurrency] || !account[quoteCurrency]) {
cancelAll(exchange)
var acc = _C(exchange.GetAccount)
account[baseCurrency] = acc.Stocks
account[quoteCurrency] = acc.Balance
}
lastBarTime[symbol] = 0
arrChartConfig.push(createChartConfig(symbol, arrEma1Periods[index], arrEma2Periods[index]))
})
if (_G("initAccount")) {
initAccount = _G("initAccount")
Log("恢复初始账户记录", initAccount)
} else {
_.each(account, function(val, key) {
initAccount[key] = val
})
}
Log("account:", account, "initAccount:", initAccount)
var chart = Chart(arrChartConfig)
chart.reset()
while (true) {
_.each(arrSymbols, function(symbol, index) {
exchange.SetCurrency(symbol)
var arrCurrencyName = symbol.split("_")
var baseCurrency = arrCurrencyName[0]
var quoteCurrency = arrCurrencyName[1]
var ema1Period = parseFloat(arrEma1Periods[index])
var ema2Period = parseFloat(arrEma2Periods[index])
var amount = parseFloat(arrAmounts[index])
var r = exchange.GetRecords()
if (!r || r.length < Math.max(ema1Period, ema2Period)) {
Sleep(1000)
return
}
var currBarTime = r[r.length - 1].Time
lastPrices[symbol] = r[r.length - 1].Close
var ema1 = TA.EMA(r, ema1Period)
var ema2 = TA.EMA(r, ema2Period)
if (ema1.length < 3 || ema2.length < 3) {
Sleep(1000)
return
}
var ema1Last2 = ema1[ema1.length - 2]
var ema1Last3 = ema1[ema1.length - 3]
var ema2Last2 = ema2[ema2.length - 2]
var ema2Last3 = ema2[ema2.length - 3]
// 写入图表数据
var klineIndex = index + 2 * index
for (var i = 0 ; i < r.length ; i++) {
if (r[i].Time == lastBarTime[symbol]) {
// 更新
chart.add(klineIndex, [r[i].Time, r[i].Open, r[i].High, r[i].Low, r[i].Close], -1)
chart.add(klineIndex + 1, [r[i].Time, ema1[i]], -1)
chart.add(klineIndex + 2, [r[i].Time, ema2[i]], -1)
} else if (r[i].Time > lastBarTime[symbol]) {
// 添加
lastBarTime[symbol] = r[i].Time
chart.add(klineIndex, [r[i].Time, r[i].Open, r[i].High, r[i].Low, r[i].Close])
chart.add(klineIndex + 1, [r[i].Time, ema1[i]])
chart.add(klineIndex + 2, [r[i].Time, ema2[i]])
}
}
if (ema1Last3 < ema2Last3 && ema1Last2 > ema2Last2 && currTradeMsg[symbol] != currBarTime) {
var depth = exchange.GetDepth()
var price = depth.Asks[Math.min(takeLevel, depth.Asks.length)].Price
if (depth && price * amount <= account[quoteCurrency]) {
exchange.Buy(price, amount, ema1Last3, ema2Last3, ema1Last2, ema2Last2)
cancelAll(exchange)
var acc = _C(exchange.GetAccount)
if (acc.Stocks != account[baseCurrency]) {
account[baseCurrency] = acc.Stocks
account[quoteCurrency] = acc.Balance
currTradeMsg[symbol] = currBarTime
_G("currTradeMsg", currTradeMsg)
var profit = getProfit(account, initAccount, lastPrices)
if (profit) {
LogProfit(profit, account, initAccount)
}
}
}
} else if (ema1Last3 > ema2Last3 && ema1Last2 < ema2Last2 && currTradeMsg[symbol] != currBarTime) {
var depth = exchange.GetDepth()
var price = depth.Bids[Math.min(takeLevel, depth.Bids.length)].Price
if (depth && amount <= account[baseCurrency]) {
exchange.Sell(price, amount, ema1Last3, ema2Last3, ema1Last2, ema2Last2)
cancelAll(exchange)
var acc = _C(exchange.GetAccount)
if (acc.Stocks != account[baseCurrency]) {
account[baseCurrency] = acc.Stocks
account[quoteCurrency] = acc.Balance
currTradeMsg[symbol] = currBarTime
_G("currTradeMsg", currTradeMsg)
var profit = getProfit(account, initAccount, lastPrices)
if (profit) {
LogProfit(profit, account, initAccount)
}
}
}
}
Sleep(1000)
})
var tbl = {
type : "table",
title : "账户信息",
cols : [],
rows : []
}
tbl.cols.push("--")
tbl.rows.push(["初始"])
tbl.rows.push(["当前"])
_.each(account, function(val, key) {
if (typeof(initAccount[key]) == "number") {
tbl.cols.push(key)
tbl.rows[0].push(initAccount[key]) // 初始
tbl.rows[1].push(val) // 当前
}
})
LogStatus(_D(), "\n", "profit:", getProfit(account, initAccount, lastPrices), "\n", "`" + JSON.stringify(tbl) + "`")
}
}
Detail
https://www.fmz.com/strategy/333783
Last Modified
2021-12-07 10:14:09