HUSD/USD stabilitas mata uang

Penulis:Anak laki-laki, Tanggal: 2019-08-28 17:06:53
Tag:

HUSD/USDT stabilitas mata uang

Bitcoin telah beraktivitas untuk sementara waktu, dan daerah HUSD bebas biaya, jadi saya membuat skrip untuk membuat wol. Menurut selalu akanKembali ke 1.Fitur untuk melakukan stabilization


var _running = false
var _tickTimeCost = 0
var _profit = _G('profit') || 0
var _config = {
    orderAmount: ORDER_AMOUNT,
    priceCeil: PRICE_CEIL,
    priceFloor: PRICE_FLOOR,
    maxATR: MAX_ATR,
    profitRate: PROFIT_RATE
}
var _arbitCount = _G('arbit_count') || 0
var _depthHistory = _G('depth_history') || []

function getNow() {
    return UnixNano() / 1000000
}

function getDepth() {
    var depth = _C(exchange.GetDepth)
    _depthHistory.push(depth)
    _depthHistory = _depthHistory.slice(-5)
    _G('_depthHistory', JSON.stringify(_depthHistory))
    return depth
}

function getBase(ex) {
    return ex.GetCurrency().split('_')[0]
}

function getTypeText(type) {
    var list = [
        [ORDER_TYPE_BUY, 'Buy', '购买', '#01bf6a'],
        [ORDER_TYPE_SELL, 'Sell', '出售', '#ff0000']
    ]
    var found = _.find(list, function(items) {
        return items[0] === type || items[1] === type
    })
    return found ? found[2] + found[3] : ''
}

function getPriceTypeText(type) {
    if (type === 0) {
        return '对手价'
    } else if (type === 1) {
        return '成交价'
    } else if (type === 2) {
        return '挂1价'
    }
}

function getStatusText(st, showColor) {
    showColor = showColor == null ? true : showColor
    var list = [
        [ORDER_STATE_CLOSED, '已完成', '#f4b300'],
        [ORDER_STATE_PENDING, '未完成', '#000000'],
        [ORDER_STATE_CANCELED, '已取消', '#a3a3a3'],
        [ORDER_STATE_UNKNOWN, '未知状态', '#777777']
    ]
    var found = _.find(list, function(item) {
        return item[0] === st
    })
    return found && found.length > 0 ? found[1] + (showColor ? found[2] : '') : ''
}

function logMyProfit(num) {
    var newProfit = _profit + num
    if (newProfit !== _profit) {
        LogProfit(newProfit)
        _profit = newProfit
        _G('profit', _profit)
    }
}

function cancelOrder(id) {
    while (1) {
        var order = _C(exchange.GetOrder, id)
        if (order.Status === ORDER_STATE_PENDING) {
            exchange.CancelOrder(id)
        } else {
            return
        }
        Sleep(200)
    }
}

function getLastATR() {
    var askPrices = _.flatten(_.pluck(_depthHistory, 'Asks').map(function(d) { return d[0].Price }))
    var slicedPrices = askPrices.slice(-5)
    var avgPrice = new Decimal(_.reduce(slicedPrices, function(p, n) {
        return new Decimal(p).plus(n).toNumber()
    }, 0)).div(slicedPrices.length).toNumber()
    var askVaiance = new Decimal(_.reduce(slicedPrices, function(p, n) {
        return new Decimal(p).plus(new Decimal(n).minus(avgPrice).pow(2)).toNumber()
    }, 0)).div(slicedPrices.length).toNumber()
    var askSD = new Decimal(askVaiance).sqrt().toNumber()
    return askSD
}

function getHighestPrice() {
    var records = _C(exchange.GetRecords, PERIOD_H1)
    var highestPrice = TA.Highest(records, 8, 'Close')
    return highestPrice
}

function onTick() {
    var depth = getDepth() //_C(exchange.GetDepth)
    var arbitOrders = JSON.parse(_G('arbit_orders')) || []

    arbitOrders = _.map(arbitOrders, function(arbitOrder) {
        if (arbitOrder.Status === ORDER_STATE_CLOSED) {
            var buyOrder = arbitOrder.BuyOrder || {}
            var sellOrder = arbitOrder.SellOrder || {}
            var buyTradePrice = new Decimal(buyOrder.AvgPrice || 0).mul(buyOrder.DealAmount || 0).toNumber()
            var sellTradePrice = new Decimal(sellOrder.AvgPrice || 0).mul(sellOrder.DealAmount || 0).toNumber()
            var profit = new Decimal(sellTradePrice).minus(buyTradePrice).toNumber()
            if (profit > 0) {
                _arbitCount++
                _G('arbit_count', _arbitCount)
                logMyProfit(profit)
                $.ddNotice('套利成功', [
                    '### 套利成功',
                    '- 买价: ' + buyOrder.Price,
                    '- 卖价: ' + sellOrder.Price,
                    '- 买量: ' + buyOrder.DealAmount,
                    '- 卖量: ' + sellOrder.DealAmount,
                    '- 买交易额: ' + buyTradePrice,
                    '- 卖交易额: ' + sellTradePrice,
                    '- 利润: ' + profit,
                    '- 耗时: ' + ((getNow() - arbitOrder.CreatedAt) / 1000).toFixed(2) + 's',
                ])
            }
            return null
        }
        return arbitOrder
    })
    arbitOrders = _.compact(arbitOrders)
    _G('arbit_orders', JSON.stringify(arbitOrders))

    arbitOrders = _.map(arbitOrders, function(arbitOrder) {
        if (arbitOrder.Status === ORDER_STATE_PENDING) {
            var buyOrder = _C(exchange.GetOrder, arbitOrder.BuyOrder.Id)
            var sellOrder = arbitOrder.SellOrder ? _C(exchange.GetOrder, arbitOrder.SellOrder.Id) : null

            // 标记订单完成
            if (buyOrder && sellOrder && buyOrder.Status !== ORDER_STATE_PENDING && sellOrder.Status !== ORDER_STATE_PENDING) {
                return _.extend(arbitOrder, {
                    Status: ORDER_STATE_CLOSED,
                    BuyOrder: buyOrder,
                    SellOrder: sellOrder,
                })
            }

            // 购买完成后发起出售订单
            if (buyOrder.Status !== ORDER_STATE_PENDING && !sellOrder) {
                var sellAmount = _N(buyOrder.DealAmount, AMOUNT_PRECISION)
                if (sellAmount >= MIN_ORDER_AMOUNT) {
                    var sellPrice = +(new Decimal(buyOrder.Price).mul(1 + FEE_RATE).div(1 - _config.profitRate).div(1 - FEE_RATE).toFixed(PRICE_PRECISION, Decimal.ROUND_UP))
                    var sellId = exchange.Sell(sellPrice, sellAmount)
                    if (sellId) {
                        sellOrder = _C(exchange.GetOrder, sellId)
                    }
                } else {
                    return _.extend(arbitOrder, {
                        Status: ORDER_STATE_CLOSED
                    })
                }
            }

            if (buyOrder.Status === ORDER_STATE_PENDING) {
                /*
                撤单条件
                1. 买1价格发生变化
                2. 均幅波动超出设定值
                3. 当买1的量等于这个买单的剩余量的时候(说明是自己挂的单)
                */
                if (buyOrder.Price !== depth.Bids[0].Price || getLastATR() > _config.maxATR || depth.Bids[0].Amount === _N(new Decimal(buyOrder.Amount).minus(buyOrder.DealAmount).toNumber(), AMOUNT_PRECISION)) {
                    cancelOrder(buyOrder.Id)
                    buyOrder = _C(exchange.GetOrder, buyOrder.Id)
                }
            }

            return _.extend(arbitOrder, {
                BuyOrder: buyOrder,
                BuyPrice: buyOrder.Price,
                SellOrder: sellOrder,
                SellPrice: sellOrder ? sellOrder.Price || 0 : 0
            })
        }
        return arbitOrder
    })

    _G('arbit_orders', JSON.stringify(arbitOrders))

    var buyPrice = depth.Bids[0].Price
    
    // 只有当上一笔同一价格的买单结束后才会开始新的一轮
    if (!_.findWhere(arbitOrders, {
            Status: ORDER_STATE_PENDING,
            BuyPrice: buyPrice
        }) && buyPrice >= _config.priceFloor && buyPrice <= (_config.priceCeil > 0 ? _config.priceCeil : getHighestPrice()) && getLastATR() <= _config.maxATR) {
        var account = _C(exchange.GetAccount)
        var buyTradePrice = _N(new Decimal(buyPrice).mul(_config.orderAmount).toNumber(), PRICE_PRECISION)
        if (account.Balance >= buyTradePrice) {
            var buyId = exchange.Buy(buyPrice, _config.orderAmount)
            if (buyId) {
                var buyOrder = _C(exchange.GetOrder, buyId)
                arbitOrders.push({
                    Status: ORDER_STATE_PENDING,
                    BuyOrder: buyOrder,
                    BuyPrice: buyPrice,
                    SellOrder: null,
                    SellPrice: 0,
                    CreatedAt: getNow()
                })
                _G('arbit_orders', JSON.stringify(arbitOrders))
            }
        }

    }
}

function logMyStatus() {
    var account = _C(exchange.GetAccount)
    var arbitOrders = JSON.parse(_G('arbit_orders')) || []
    var basicStatus = {
        type: 'table',
        title: '基本信息',
        cols: ['运行状态', '耗时', '套利次数', '实现盈亏', '最大均幅 (最近5个卖1标准差 | 设定最大值)', '单次下单量', '阻力位', '支撑位'],
        rows: [
            [
                _running ? '运行中#01c401' : '未运行#a3a3a3',
                new Date().toLocaleString() + ' - ' + (_tickTimeCost / 1000).toFixed(2) + 's',
                _arbitCount,
                (_profit || 0) + '#ff0000',
                getLastATR() + ' | ' + _config.maxATR,
                _config.orderAmount,
                _config.priceCeil > 0 ? _config.priceCeil : getHighestPrice(),
                _config.priceFloor
            ]
        ]
    }

    var assetsStatus = {
        type: 'table',
        title: '资产信息',
        cols: [exchanges[0].GetQuoteCurrency() + ' (可用 | 冻结)', getBase(exchanges[0]) + ' (可用 | 冻结)'],
        rows: [
            [
                new Decimal(account.Balance).plus(account.FrozenBalance).toNumber() + ' (' + account.Balance + ' | ' + account.FrozenBalance + ')',
                new Decimal(account.Stocks).plus(account.FrozenStocks).toNumber() + ' (' + account.Stocks + ' | ' + account.FrozenStocks + ')',
            ]
        ]
    }

    var arbitOrdersStatus = {
        type: 'table',
        title: '套利订单列表',
        cols: ['套利状态', '买单 (状态 | 价格 | 单量)', '卖单 (状态 | 价格 | 单量)', '创建时间'],
        rows: _.map(arbitOrders, function(arbitOrder) {
            var sideOrders = _.map([arbitOrder.BuyOrder, arbitOrder.SellOrder], function(order) {
                if (order) {
                    return getStatusText(order.Status, false) + ' | ' + order.Price + ' | ' + order.DealAmount
                } else {
                    return '-'
                }
            })
            return [getStatusText(arbitOrder.Status), sideOrders[0], sideOrders[1], new Date(arbitOrder.CreatedAt).toLocaleString()]
        })
    }

    var statusList = _.flatten([
        basicStatus,
        assetsStatus,
        arbitOrdersStatus
    ])

    LogStatus(_.compact(statusList).map(function(d) {
        return '`' + JSON.stringify(d) + '`'
    }).join('\n'))
}

function main() {
    _.each(_config, function(v, k) {
        $.BindingFunc(k, function(cmd, val) {
            if (typeof(v) === 'number') {
                val = +val
            }
            _config[k] = val
        })
    })
    $.BindingFunc("开始", function() {
        _running = true
    })
    $.BindingFunc("暂停", function() {
        _running = false
    })
    while (true) {
        var _tickStartTime = getNow()
        LogReset(1000)
        $.GetCommand()
        if (_running) {
            onTick()
        }
        _tickTimeCost = getNow() - _tickStartTime
        logMyStatus()
        Sleep(500)
    }
}

Lebih banyak

Orang-orang blokHalo, maafkan saya, saya orang kulit putih, saya selalu mengirim kesalahan saat saya melakukan operasi GetAccount: 500: ["error", 10100, "apikey: digest invalid"] Apa artinya ini?