MACD giảm mua bán tự động theo dõi trượt dừng lỗ (2018-03-27 15:48:24)

Tác giả:Không, Ngày: 2014-06-14 01:17:24
Tags:

Một cột trước sau khi giao dịch là giá trị của cột đầu tiên sau khi giao dịch, một cột trước khi giao dịch là giá trị của cột cuối trước khi giao dịch, giá trượt là giá được thêm vào khi đặt hàng, ví dụ: đơn đặt hàng sẽ trả giá tiền mặt cộng với giá này, đơn bán sẽ trừ giá này.



Fixed = function(v) {
    return Math.floor(v*1000)/1000;
};

// for orders
WaitOrder = function(exchange, orderId, timeoutToCancel) {
    var ts = (new Date()).getTime();
    while (true) {
        Sleep(3000);
        var orderInfo = exchange.GetOrder(orderId);
        if (!orderInfo) {
            continue;
        }
        if (orderInfo.Status == ORDER_STATE_CLOSED || orderInfo.Status == ORDER_STATE_CANCELED) {
            return orderInfo;
        }
        if (((new Date()).getTime() - ts) > timeoutToCancel) {
            exchange.CancelOrder(orderId);
        }
    }
};

Buy = function(exchange, maxPrice, slidePrice, balanceRatio, timeoutS) {
    var ts = (new Date()).getTime();
    var account;
    var dealAmount = 0.0;
    var usedBlance = 0.0;
    var maxBalanceUse = 0.0;
    var isFirst = true;
    do {
        if (isFirst) {
            isFirst = false;
        } else {
            Sleep(3000);
        }

        var ticker = exchange.GetTicker();
        if (!ticker) {
            continue;
        }

        var buyPrice = ticker.Sell + slidePrice;

        // Price too high, wait...
        if (buyPrice > maxPrice) {
            continue;
        }

        // Initialize at first
        if (!account) {
            account = exchange.GetAccount();
            if (!account) {
                continue;
            }
            // Initialize maxBalanceUse
            maxBalanceUse = account.Balance * balanceRatio;
        }

        var buyAmount = Fixed((maxBalanceUse - usedBlance) / buyPrice);
        if (buyAmount < exchange.GetMinStock()) {
            break;
        }

        orderId = exchange.Buy(buyPrice, buyAmount);
        if (!orderId) {
            Log(buyPrice, buyAmount, maxBalanceUse, usedBlance);
            continue;
        }

        var orderInfo = WaitOrder(exchange, orderId, timeoutS);
        dealAmount += orderInfo.DealAmount;
        usedBlance += orderInfo.Price * orderInfo.DealAmount;
        if (orderInfo.Status == ORDER_STATE_CLOSED) {
            break;
        }
    } while (((new Date()).getTime() - ts) < timeoutS);

    return {amount: dealAmount, price: (dealAmount > 0 ? usedBlance / dealAmount : 0)};
};

Sell = function(exchange, sellAmount, slidePrice) {
    // Account info must set
    var account = exchange.GetAccount();
    while (!account) {
        Sleep(2000);
        account = exchange.GetAccount();
    }

    sellAmount = Math.min(sellAmount, account.Stocks);

    var cash = 0.0;
    var remain = sellAmount;

    while (remain >= exchange.GetMinStock()) {
        var ticker = exchange.GetTicker();
        if (!ticker) {
            Sleep(2000);
            continue;
        }
        var sellPrice = ticker.Buy - slidePrice;
        var sellOrderId = exchange.Sell(sellPrice, remain);
        if (!sellOrderId) {
            Sleep(2000);
            continue;
        }
        var orderInfo = WaitOrder(exchange, sellOrderId, 10000);
        remain -= orderInfo.DealAmount;
        cash += orderInfo.Price * orderInfo.DealAmount;
    }
    return {amount: sellAmount, price: (sellAmount > 0 ? cash / sellAmount : 0)};
};

var BuyInfo;
var BanlanceRatio = 1.0;
var Profit = 0.0;
var timeAtBuy = 0;

function onTick(exchange) {
    var ticker = exchange.GetTicker();
    var records = exchange.GetRecords();
    if (!ticker || !records || records.length < 45) {
        return;
    }

    var ticks = [];
    for (var i = 0; i < records.length; i++) {
        ticks.push(records[i].Close);
    }

    var macd = TA.MACD(records, 12, 26, 9);
    var dif = macd[0];
    var dea = macd[1];
    var his = macd[2];
    
    var op = 0;
    if (!BuyInfo) {
        if (dif[ticks.length-1] > 0 && his[ticks.length-1] > ac1 && his[ticks.length-2] < bc1) {
            op = 1;
        }
    } else {
        if (records[records.length-2].Time > timeAtBuy && records[records.length-1].Close < records[records.length-1].Open - 0.5
                && records[records.length-2].Close < records[records.length-2].Open - 0.5
                && records[records.length-1].Close < records[records.length-2].Close - 0.5) {
            op = 2;
        } else if (records[records.length-2].Time > timeAtBuy && BuyInfo.price > records[records.length-1].Close && records[records.length-1].Close < records[records.length-1].Open - 0.5) {
            op = 2;
        } else if ((BuyInfo.price < ticker.Last || dif[ticks.length-1] < 0) && his[ticks.length-1] <= 0) {
            op = 2;
        } else if ((BuyInfo.price > ticker.Last) && ((BuyInfo.price - ticker.Last) / BuyInfo.price > TrailingStop)) {
            op = 2;
        }
    }

    if (op == 1) {
        var info = Buy(exchange, ticker.Sell + (SlidePrice * 3), SlidePrice, BanlanceRatio, orderTimeout * 1000);
        if (info.amount > 0) {
            BuyInfo = info;
            timeAtBuy = records[records.length-1].Time;
        }
    } else if (op == 2) {
        var info = Sell(exchange, BuyInfo.amount, SlidePrice);
        if (info.amount > 0) {
            Profit += info.amount * (info.price - BuyInfo.price);
            LogProfit(Profit);
            BuyInfo = null;
        }
    }
}

function main() {
    var account = exchange.GetAccount();
    if (account) {
        Log(exchange.GetName(), exchange.GetCurrency(), account);
    }
    
    while (true) {
        onTick(exchange);
        Sleep(30000);
    }
}

Thêm nữa