ग्रिड विरूपण रणनीति के एकतरफा ग्रिड (ओके वायदा)

लेखक:शून्य, दिनांकः 2015-12-16 23:00:05
टैगःओकेएक्सग्रिड

ग्रिड को अपनी ओर मोड़ सकते हैं पहले खरीदें और फिर बेचेंः ग्रिड शुरू मूल्य से नीचे लटकाने के लिए चालान, प्रत्येक भुगतान के अंतराल के लिए लटकन मूल्य अंतराल इस पैरामीटर, लटकन की संख्या के लिए है "एक पेन की संख्या", लटकन के लिए पर्याप्त है लटकन की कुल संख्या लटकन एक चालान है, किसी भी चालान के लेनदेन के बाद, कार्यक्रम खरीद मूल्य के आधार पर जोड़ देगा लटकन मूल्य अंतर (यूरो) लटकन इस पैरामीटर के मूल्य के मूल्य लटकन खरीद, बिक्री, बिक्री के बाद, फिर से मूल रूप से इस ग्रिड की कीमत पर लटकन खरीद पहले बेचें और बाद में खरीदेंः यह बिल्कुल विपरीत है।

रणनीति का सबसे बड़ा जोखिम एकतरफा बाजार है, जहां कीमतें ग्रिड सीमा से परे चलती हैं।

ऑटो-स्टॉप और मोबाइल के साथ ग्रिड


var isFuture = false;

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 balanceAccount(orgAccount, initAccount) {
    if (isFuture) {
        while (true) {
            cancelPending();
            var positions = _C(exchange.GetPosition);
            if (positions.length === 0 ) {
                var accountNow = _C(exchange.GetAccount);
                LogProfit(_N(accountNow.Stocks - orgAccount.Stocks), "可用保证金:", accountNow.Stocks);
                return;
            }
            for (var i = 0; i < positions.length; i++) {
                if (positions[i].Type == PD_LONG) {
                    exchange.SetDirection("closebuy");
                    exchange.Sell(positions[i].Amount);
                } else {
                    exchange.SetDirection("closesell");
                    exchange.Buy(positions[i].Amount);
                }
            }
            Sleep(Interval);
        }
    }
    var account = _C(exchange.GetAccount);
    while (true) {
        var diff = _N(account.Stocks - initAccount.Stocks);
        if (Math.abs(diff) < exchange.GetMinStock()) {
            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;
            }
        }
        Log("开始平衡", (diff > 0 ? "卖出" : "买入"), Math.abs(diff), "个币");
        if (diff > 0) {
            exchange.Sell(price - 0.2, diff);
        } else {
            exchange.Buy(price + 0.2, -diff);
        }
        Sleep(1000);
        cancelPending();
        account = _C(exchange.GetAccount);
    }
    Log("平衡完成", account);
}

var STATE_WAIT_OPEN  = 0;
var STATE_WAIT_COVER = 1;
var STATE_WAIT_CLOSE = 2;
var ProfitCount = 0;
var BuyFirst = (OpType == 0);
var IsSupportGetOrder = true;
var LastBusy = 0;
var LastFloatProfit = 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) {
        amountB = BAmountOnce;
        amountS = SAmountOnce;
    }
    if (FirstPriceAuto) {
        FirstPrice = BuyFirst ? _N(ticker.Buy - PriceGrid) : _N(ticker.Sell + PriceGrid);
    }
    // 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;
    var marginLevel = [10,20][MarginLevelIdx];
    exchange.SetMarginLevel(marginLevel);
    for (var idx = 0; idx < AllNum; idx++) {
        var price = _N(BuyFirst ? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid));
        if (isFuture) {
            needStocks += ((100 * amountB) / price) / marginLevel;
            if (_N(needStocks) <= _N(account.Stocks)) {
                actualNeedStocks = needStocks;
                canNum++;
            } else {
                notEnough = true;
            }
        } else {
            needStocks += amountS;
            needMoney += price * amountB;
            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 (EnableProtectDiff) {
        if (BuyFirst && (FirstPrice - ticker.Sell) > ProtectDiff) {
            throw "首次买入价比市场卖1价高" + _N(FirstPrice - ticker.Sell) + ' 元';
        } else if (!BuyFirst && (ticker.Buy - FirstPrice) > ProtectDiff) {
            throw "首次卖出价比市场买1价高 " + _N(ticker.Buy - FirstPrice) + ' 元';
        }
    }
    if (BuyFirst && !isFuture) {
        if (account.Balance < _N(needMoney)) {
            if (fishCount == 1) {
                throw "资金不足, 需要"+ _N(needMoney) + "元";
            } else {
                Log("资金不足, 需要", _N(needMoney), "元, 程序只做", canNum, "个网格 #ff0000");
            }
        } else {
            Log('预计动用资金: ', _N(needMoney), "元");
        }
    } else {
        if (account.Stocks < _N(needStocks)) {
            if (fishCount == 1) {
                throw "币数不足, 需要 "+ _N(needStocks) + " 个币";
            } else {
                Log("资金不足, 需要", _N(needStocks), "个币, 程序只做", canNum, "个网格 #ff0000");
            }
        } else {
            Log('预计动用币数: ', _N(needStocks), "个");
        }
    }

    var OpenFunc = BuyFirst ? exchange.Buy : exchange.Sell;
    var CoverFunc = BuyFirst ? exchange.Sell : exchange.Buy;
    var ts = new Date();
    var preMsg = "";
    var profitMax = 0;
    while (true) {
        var now = new Date();
        if (now.getTime() - ts.getTime() > 5000) {
            if (typeof(GetCommand) == 'function' && GetCommand() == "收网") {
                Log("开始执行命令进行收网操作");
                balanceAccount(orgAccount, InitAccount);
                return false;
            }
            ts = now;
            var msg = "";
            var positions, isHold;
            var ticker = _C(exchange.GetTicker);
            var nowAccount = _C(exchange.GetAccount);
            if (isFuture) {
                positions = _C(exchange.GetPosition);
                isHold = positions.length > 0;
                if (isHold) {
                    msg += "持仓: " + positions[0].Amount + " 持仓均价: " + _N(positions[0].Price) + " 浮动盈亏: " + _N(positions[0].Profit);
                    if (EnableStopLoss && -positions[0].Profit >= StopLoss) {
                        Log("当前浮动盈亏", positions[0].Profit, "开始止损");
                        balanceAccount(orgAccount, InitAccount);
                        if (StopLossMode === 0) {
                            throw "止损退出";
                        } else {
                            return true;
                        }
                    }
                } else {
                    msg += "空仓";
                }
                msg += " 可用保证金: " + nowAccount.Stocks;
                
            } else {
                isHold = Math.abs(amount_diff) >= exchange.GetMinStock();
                
                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));
                LastFloatProfit = floatProfitAll;
                profitMax = Math.max(floatProfit, profitMax);
                if (EnableStopLoss) {
                    if ((profitMax - floatProfit) >= StopLoss) {
                        Log("当前浮动盈亏", floatProfit, "利润最高点: ", profitMax, "开始止损");
                        balanceAccount(orgAccount, InitAccount);
                        if (StopLossMode === 0) {
                            throw "止损退出";
                        } else {
                            return true;
                        }
                    }
                }
                if (isHold) {
                    if (RestoreProfit && ProfitAsOrg) {
                        if (BuyFirst) {
                            money_diff += LastProfit;
                        } else {
                            money_diff -= LastProfit;
                        }
                    }
                    var hold_amount = amount_diff;
                    var hold_price = (-money_diff) / amount_diff;
                    if (!BuyFirst) {
                        hold_amount = -amount_diff;
                        hold_price = (money_diff) / -amount_diff;
                    }
                    msg = (BuyFirst ? "做多: " : "做空: ") +  _N(hold_amount, 4) + " 个币, 均价: " + _N(hold_price);
                } else {
                    msg += "空仓";
                }
                msg += " 当前网格浮动盈亏: " + floatProfit + " 总浮动盈亏: " + floatProfitAll + " 第 " + fishCount + " 次撒网 最新币价: " + _N(ticker.Last);
            }
            if (isHold) {
                setBusy();
            }

            var distance = 0;
            if (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), "当前价格:", ticker.Last);
                    refish = true;
                }
                if (refish) {
                    balanceAccount(orgAccount, InitAccount);
                    return true;
                }
            }

            if (AutoMove && distance > 0) {
                msg += " (离网格" + (BuyFirst ? "向上" : "向下") + "偏离: " + _N(distance) + " 元)";
            }
            if (msg != preMsg) {
                LogStatus(msg);
                preMsg = msg;
            }

        }
        var orders = _C(exchange.GetOrders);
        for (var idx = 0; idx < canNum; idx++) {
            var openPrice = _N(BuyFirst ? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid));
            var coverPrice = _N(BuyFirst ? openPrice + PriceDiff : openPrice - PriceDiff);
            var state = fishTable[idx];
            var fishId = uuidTable[idx];
            if (hasOrder(orders, fishId)) {
                continue;
            }

            if (fishId != -1 && IsSupportGetOrder) {
                var order = exchange.GetOrder(fishId);
                if (!order) {
                    Log("获取订单信息失败, ID: ", fishId);
                    continue;
                }
                if (order.Status == ORDER_STATE_PENDING) {
                    Log("订单状态为未完成, ID: ", fishId);
                    continue;
                }
            }

            if (state == STATE_WAIT_COVER) {
                if (isFuture) {
                    exchange.SetDirection(BuyFirst ? "closebuy" : "closesell");
                }
                var coverId = CoverFunc(coverPrice, BuyFirst ? amountS : amountB, BuyFirst ? '完成买单:' : '完成卖单:', openPrice);
                if (coverId) {
                    fishTable[idx] = STATE_WAIT_CLOSE;
                    uuidTable[idx] = coverId;
                }
            } else if (state == STATE_WAIT_OPEN || state == STATE_WAIT_CLOSE) {
                if (isFuture) {
                    exchange.SetDirection(BuyFirst ? "buy" : "sell");
                }
                var openId = OpenFunc(openPrice, BuyFirst ? amountB : amountS);
                if (openId) {
                    fishTable[idx] = STATE_WAIT_COVER;
                    uuidTable[idx] = openId;
                    if (state == STATE_WAIT_CLOSE) {
                        ProfitCount++;
                        if (AmountType === 0) {
                            Log((BuyFirst ? '完成卖单: ' : '完成买单: ') + coverPrice);
                        } else {
                            Log((BuyFirst ? '完成卖单: ' : '完成买单: ') + coverPrice);
                        }
                        if (!isFuture) {
                            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);
                            LogProfit(LastFloatProfit, "总浮动盈亏率:", _N(LastFloatProfit * 100 / actualNeedMondy, 4), '%');
                        }
                    }
                }
            }
        }
        Sleep(CheckInterval);
    }
    return true;
}

function main() {
    if (typeof(AmountType) === 'undefined') {
        AmountType = 0;
    }
    IsSupportGetOrder = exchange.GetName().indexOf('itstamp') == -1;
    if (!IsSupportGetOrder) {
        Log(exchange.GetName(), "不支持GetOrder, 可能影响策略稳定性.");
    }
    
    isFuture = exchange.GetName().indexOf("Future") != -1;
    if (AmountType === 0) {
        BAmountOnce = AmountOnce;
        SAmountOnce = AmountOnce;
    }
    if (exchange.GetName() == "Futures_OKCoin" && (AmountOnce.toString().indexOf(".") != -1 || BAmountOnce.toString().indexOf(".") != -1 || SAmountOnce.toString().indexOf(".") != -1)) {
        throw "OKCoin期货下单数必须为整数";
    }

    SetErrorFilter("502:|503:|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|refused|EOF|When");

    exchange.SetRate(1);
    Log('已经禁用汇率转换, 当前货币为', exchange.GetBaseCurrency());

    if (!RestoreProfit) {
        LastProfit = 0;
    }
    exchange.SetContractType(["this_week", "next_week", "quarter"][ContractTypeIdx]);
    var orgAccount = _C(exchange.GetAccount);
    var fishCount = 1;
    while (true) {
        if (!fishing(orgAccount, fishCount)) {
            break;
        }
        fishCount++;
        Log("第", fishCount, "次重新撒网...");
        FirstPriceAuto = true;
        Sleep(1000);
    }
}



संबंधित

अधिक

बादलओकेएक्स एक्सचेंजों का वास्तविक परीक्षण करें, 100% त्रुटि का जोखिम दर्ज करें। देखें, ग्रिड की कुल संख्या की सीमा अमान्य है, और गारंटी समाप्त होने तक लंबित रहेगी, फिर लगातार त्रुटि दर्ज करें।

ब्लाक हिमशैलस्टॉक्स के नोट्स को हटा दें ताकि यह काम कर सके, अन्यथा यह हमेशा गलत रहता है।

वर्ष 1966क्या यह ग्रिड ठीक V3 एपीआई के साथ संगत है?

a8269917कीमतों का अंतर प्रतिशत में बदलना अच्छा है।

सीज्लियुजनमस्ते, एक समस्या हैः यदि रणनीति शुरू होती है और नीचे की ओर लटकती है, तो क्या धन उपयोगिता का सवाल है, क्योंकि एक बार जब आप आदेश देते हैं, तो धन अवरुद्ध हो जाता है, और समान मात्रा में धन एक ही समय में अधिक अनुबंधों का संचालन नहीं कर सकता है।

सीज्लियुजनमस्ते, एक समस्या हैः यदि रणनीति शुरू होती है और नीचे की ओर लटकती है, तो क्या धन उपयोगिता का सवाल है, क्योंकि एक बार जब आप आदेश देते हैं, तो धन अवरुद्ध हो जाता है, और समान मात्रा में धन एक ही समय में अधिक अनुबंधों का संचालन नहीं कर सकता है।

हमला करने वाला सूअरमैं पूछना चाहता हूं कि क्या यह दो साल पहले की रणनीति है और क्या यह अभी भी काम करती है, क्या कोई समस्या है?

शून्ययह सिर्फ देखा गया है, यह बदल गया है।

a8269917लेकिन फ्यूचर्स कॉन्ट्रैक्ट्स के लिए पैसा नहीं है, आप पैसे बचा सकते हैं और अन्य कॉन्ट्रैक्ट्स पर उपयोग नहीं कर सकते हैं, जब तक कि आप शुरू में पैसे को दो भागों में विभाजित नहीं करते हैं और दो ग्रिडों का संचालन करते हैं, और फिर गतिशील लटकन सूची में धन का उपयोग बढ़ाने के लिए चाहते हैं, तो जोखिम भी बढ़ जाता है, मुझे लगता है कि आपको अभी भी विचार करना चाहिए ओके फिक्स्ड प्वाइंट ब्लास्ट, डर है कि आज कुछ कॉन्ट्रैक्ट्स का चयन करें और कल यह विस्फोट हो जाएगा, जो कि सभी लोगों के लिए काम कर रहे हैं, फ्यूचर्स नकद से बेहतर हैं, इस रणनीति में नकदी में गतिशील लटकन सूची है, फ्यूचर्स मुझे लगता है कि सबसे महत्वपूर्ण है, आप एक कॉन्ट्रैक्ट को केंद्रित करते हैं, फिक्स्ड प्वाइंट ब्लास्ट आप बहुत कम बिंदुओं को सूंघ सकते हैं और फिर तुरंत बाहर निकल सकते हैं, लाभ बहुत अधिक है, कभी-कभी कॉन्ट्रैक्ट्स में देरी होती है, लगभग दस मिनट गिर जाते हैं, लेकिन रोबोट थ्योरी में, कोई लटकन सूची

सीज्लियुजनहीं, मेरा मतलब है: यदि आपके पास 10,000 युआन है, तो अब दो ग्रिड हैं, प्रत्येक ग्रिड में नीचे की ओर 10 हैं, प्रत्येक ग्रिड में 1,000,000 हैं, यदि आप शुरू में ही लटक गए हैं, तो 10,000 युआन सभी जमे हुए हैं, और आप केवल एक ग्रिड को कॉपी कर सकते हैं, लेकिन यदि आप गतिशील हैं, तो आपको केवल ग्रिड के नीचे के मूल्य को जोड़ने की आवश्यकता है, ताकि 10,000 युआन में बहुत तरलता हो सके, और आप कई ग्रिडों को संचालित कर सकें।

a8269917मैं आपको जवाब देता हूं कि नेटवर्किंग लेनदेन में धन का उपयोग बहुत अधिक नहीं है, यह आपके द्वारा लंबित ऑर्डर की संख्या को संतुलित करने के लिए है।