Skip to content

Latest commit

 

History

History
258 lines (226 loc) · 8.52 KB

数字货币现货多品种双均线策略教学.md

File metadata and controls

258 lines (226 loc) · 8.52 KB

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