Фьючерсная торговля криптовалютами (тестирование)

Автор:Маленькие мечты, Дата: 2020-04-29 11:19:39
Тэги:

Фьючерсная торговля криптовалютами (тестирование)

  • main как тест-функция, пример вызова

Если у вас есть какие-либо вопросы, пожалуйста, оставьте комментарии.


// 参数
/*
var MinAmount = 1
var SlidePrice = 5
var Interval = 500
*/

function GetPosition(e, contractType, direction) {
    e.SetContractType(contractType)
    var positions = _C(e.GetPosition);
    for (var i = 0; i < positions.length; i++) {
        if (positions[i].ContractType == contractType && positions[i].Type == direction) {
            return positions[i]
        }
    }

    return null
}

function Open(e, contractType, direction, opAmount) {
    var initPosition = GetPosition(e, contractType, direction);
    var isFirst = true;
    var initAmount = initPosition ? initPosition.Amount : 0;
    var nowPosition = initPosition;
    var directBreak = false 
    var preNeedOpen = 0
    var timeoutCount = 0
    while (true) {
        var ticker = _C(e.GetTicker)
        var needOpen = opAmount;
        if (isFirst) {
            isFirst = false;
        } else {
            nowPosition = GetPosition(e, contractType, direction);
            if (nowPosition) {
                needOpen = opAmount - (nowPosition.Amount - initAmount);
            }
            // 检测directBreak 并且持仓未变的情况
            if (preNeedOpen == needOpen && directBreak) {
                Log("疑似仓位数据延迟,等待30秒", "#FF0000")
                Sleep(30000)
                nowPosition = GetPosition(e, contractType, direction);
                if (nowPosition) {
                    needOpen = opAmount - (nowPosition.Amount - initAmount);
                }
                /*
                timeoutCount++
                if (timeoutCount > 10) {
                    Log("连续10次疑似仓位延迟,下单失败!", "#FF0000")
                    break
                }
                */
            } else {
                timeoutCount = 0
            }
        }
        if (needOpen < MinAmount) {
            break;
        }
        
        var amount = needOpen;
        preNeedOpen = needOpen
        e.SetDirection(direction == PD_LONG ? "buy" : "sell");
        var orderId;
        if (direction == PD_LONG) {
            orderId = e.Buy(ticker.Sell + SlidePrice, amount, "开多仓", contractType, ticker);
        } else {
            orderId = e.Sell(ticker.Buy - SlidePrice, amount, "开空仓", contractType, ticker);
        }

        directBreak = false
        var n = 0
        while (true) {
            Sleep(Interval);
            var orders = _C(e.GetOrders);
            if (orders.length == 0) {
                if (n == 0) {
                    directBreak = true
                }
                break;
            }
            for (var j = 0; j < orders.length; j++) {
                e.CancelOrder(orders[j].Id);
                if (j < (orders.length - 1)) {
                    Sleep(Interval);
                }
            }
            n++
        }
    }

    var ret = {
        price: 0,
        amount: 0,
        position: nowPosition
    };
    if (!nowPosition) {
        return ret;
    }
    if (!initPosition) {
        ret.price = nowPosition.Price;
        ret.amount = nowPosition.Amount;
    } else {
        ret.amount = nowPosition.Amount - initPosition.Amount;
        ret.price = _N(((nowPosition.Price * nowPosition.Amount) - (initPosition.Price * initPosition.Amount)) / ret.amount);
    }
    return ret;
}

function Cover(e, contractType, opAmount, direction) {
    var initPosition = null;
    var position = null;
    var isFirst = true;

    while (true) {
        while (true) {
            Sleep(Interval);
            var orders = _C(e.GetOrders);
            if (orders.length == 0) {
                break;
            }
            for (var j = 0; j < orders.length; j++) {
                e.CancelOrder(orders[j].Id);
                if (j < (orders.length - 1)) {
                    Sleep(Interval);
                }
            }
        }

        position = GetPosition(e, contractType, direction)
        if (!position) {
            break
        }
        if (isFirst == true) {
            initPosition = position;
            opAmount = Math.min(opAmount, initPosition.Amount)
            isFirst = false;
        }

        var amount = opAmount - (initPosition.Amount - position.Amount)
        if (amount <= 0) {
            break
        }

        var ticker = _C(e.GetTicker)
        if (position.Type == PD_LONG) {
            e.SetDirection("closebuy");
            e.Sell(ticker.Buy - SlidePrice, amount, "平多仓", contractType, ticker);
        } else if (position.Type == PD_SHORT) {
            e.SetDirection("closesell");
            e.Buy(ticker.Sell + SlidePrice, amount, "平空仓", contractType, ticker);
        }

        Sleep(Interval)
    }

    return position
}

$.OpenLong = function(e, contractType, amount) {
    if (typeof(e) == "string") {
        amount = contractType
        contractType = e
        e = exchange
    }

    return Open(e, contractType, PD_LONG, amount);
}

$.OpenShort = function(e, contractType, amount) {
    if (typeof(e) == "string") {
        amount = contractType
        contractType = e
        e = exchange
    }

    return Open(e, contractType, PD_SHORT, amount);
};

$.CoverLong = function(e, contractType, amount) {
    if (typeof(e) == "string") {
        amount = contractType
        contractType = e
        e = exchange
    }

    return Cover(e, contractType, amount, PD_LONG);
};

$.CoverShort = function(e, contractType, amount) {
    if (typeof(e) == "string") {
        amount = contractType
        contractType = e
        e = exchange
    }

    return Cover(e, contractType, amount, PD_SHORT);
};


function main() {
    Log(exchange.GetPosition())
    var info = $.OpenLong(exchange, "quarter", 100)
    Log(info, "#FF0000")

    Log(exchange.GetPosition())
    info = $.CoverLong(exchange, "quarter", 30)
    Log(exchange.GetPosition())
    Log(info, "#FF0000")

    info = $.CoverLong(exchange, "quarter", 80)
    Log(exchange.GetPosition())
    Log(info, "#FF0000")
}

Больше

Костяные ножиА теперь, пожалуйста, объясните, как использовать ссылки в основной функции. Например, если вы открываете контракт BTC_USDT за квартал по цене 30000, как это должно быть написано? Живые дают объяснения в основной функции. var info = $.OpenLong ((exchange, "quarter", 100) Это много позиций для открытия квартальных контрактов, верно?

Высокий всасывание низкий бросокSlidePrice лучше всего будет относиться к цене.

Маленькие мечты$.OpenLong ((exchange, "quarter", 100) В то же время, если вы хотите, чтобы ваши клиенты были готовы к тому, что вы можете получить больше денег, вы должны быть готовы к тому, что вы получите больше.

Маленькие мечтыЧасто рекомендуется писать отдельные механизмы торговли, для которых требуется некоторое количество времени для обнаружения остатков сделок. Часто рекомендуется напрямую настроить логику торговли.

Высокий всасывание низкий бросокЯ использую этот OpenLong DOT ((4 ножи), дайте мне 9 ножи для выписки ((4 + 5).

Маленькие мечтыНе, это скидка, это немного больше, чем при еде.