격자 변형 전략의 단면 격자

저자:제로, 날짜: 2014-09-24 11:38:00
태그:격자

그레이드가 방향을 설정할 수 있습니다. 사면 팔면: 네트워크는 첫 번째 가격부터 아래로 청구서를 매달아, 각 청구서 간격 가격 간격 이 매개 변수,挂单数量은 "单笔数量",挂足 총 수 한 청구서, 임의의 청구서 거래가 완료된 후, 프로그램은 구매 가격에 따라 추가 가격 차이 ((元) 이 매개 변수의 값의 가격 판매 주문, 판매, 판매 후, 다시 원래의 grid의 가격에 따라 挂单 판매 후 구매: 다른 방식으로 작동합니다.

이 전략의 가장 큰 위험은 단일 시장이며, 가격 변동은 격자 범위를 초월합니다.

자동 중단 및 이동 기능이있는 격자


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 (orderId && orderId.toString().indexOf("V") != 0) {
            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 (realId) {
                    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 (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 (openId) {
                    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);
    }
}

관련

더 많은

살아있어요자동 자동으로, 재배망은 자동으로 재활용 재배 또는 지불량에 따라 재배입니다.

살아있어요자동 자동으로, 재배망은 자동으로 재활용 재배 또는 지불량에 따라 재배입니다.

살아있어요자동 자동으로, 재배망은 자동으로 재활용 재배 또는 지불량에 따라 재배입니다.

살아있어요자동 자동으로, 재배망은 자동으로 재활용 재배 또는 지불량에 따라 재배입니다.

살아있어요만약 손실이 줄어들면, 또 다른 손실이 발생할 수 있습니다.

스 7812미래에 대한 지원?

초목/upload/asset/1a80e4a5d664116b890.png 오더가 열리지 않는 경우 이 조건을 삭제합니다.

실행해보세요. 아래와 같은 오류가 발생하면, 문제는 무엇입니까? 주문 정보 획득 실패, ID: FHYCiq0FQsLrTI4fX_sESWuE2RSE0tgGZqDqgm3yk8M=

jjkk이 전략은, 동적 보유를 실행하고, 계속 주문을 하려면 버그가 있어야 합니다.

와이880무장군님, 아직 저를 포함하지 않았습니다. QQ:3219496198

대수이 현금 가격이 오픈 가격보다 낮다는 메커니즘은 무엇입니까?

모박스이득이 얼마나 되는지에 대한 대표성이 없습니다. 전략은 수익을 기준으로 측정하는 것이 아닙니다.

침몰함 7한달에 얼마죠?

침몰함 7왜 이 수익을 공개하지 않는 걸까요?

fyl_4545저는 여러분과 같은 문제를 가지고 있습니다.

노후이 전략은 제가 좀 더 잘 알고 있습니다. 어떤 문제가 있다면, 저를 연락해 수정하거나, 2차 개발을 할 수 있습니다.

제로309368835 더하기 그룹 연락처는 바로 나입니다.

침몰함 7어떻게 연락을 했는지, 여기서만 답하는 것을 알게 되었는지, zeropool@qq.com 또는 zero@botvs.com에 이메일을 보내서 답이 오지 않았는지; 어떻게 지불합니까?

제로이 전략은 짧은 문자열과 관련이 있으며 매개 변수를 조정해야하며 수익은 거의 대표적이지 않습니다. 500/월