Chiến lược ATR-RSI

Tác giả:Một con dao, Ngày: 2022-02-13 17:17:17
Tags:

Chỉ số Atr

Phạm vi biến động trung bình (Average True Range), được gọi tắt là chỉ số ATR; được sử dụng chủ yếu để đo mức độ biến động của thị trường, cho thấy tỷ lệ thay đổi của thị trường, nhưng không thể phản ánh xu hướng giá và sự ổn định của xu hướng. Giá trị của chỉ số này càng cao, xu hướng thay đổi càng nhiều, xu hướng thay đổi càng ít.

Phương pháp tính toán

Phạm vi biến động trung bình thực sự được tính theo giá trị biến động thực sự và biến động thực sự trong ngày trên N ngày qua. Nguồn biến động thực sự trong một ngày được lấy từ giá lớn nhất giữa ba nhóm kết quả: giá cao nhất trong ngày - giá thấp nhất trong ngày, giá cao nhất trong ngày - giá đóng cửa hôm qua, giá đóng cửa hôm qua - giá đóng cửa hôm nay, để có được sự khác biệt giá trong phạm vi biến động lớn nhất.

Chỉ số Rsi

Chỉ số sức mạnh tương đối (RSI) là một chỉ số kỹ thuật để đánh giá xu hướng thị trường trong tương lai bằng cách so sánh sức mạnh mua bán của hai bên trong một khoảng thời gian.

Phương pháp tính toán

RSI = 100 - (100/ ((1+RS)); RS = tổng số ngày đóng cửa n và số ngày đóng cửa / n; RSI thông thường là 50 là đường trung bình, lớn hơn 50 được coi là thị trường đa đầu và nhỏ hơn 50 được coi là thị trường không đầu; RSI lớn hơn 70 được coi là mua quá mức, có thể có sự hồi phục hoặc chuyển hướng sau đó, thấp hơn 30 là bán quá mức, có thể có sự gia tăng sau đó.

Nguyên tắc chiến lược

ATR được sử dụng để lọc, khi ATR>ATRMa (ATR trung bình trong N ngày qua) cho thấy mức độ biến động của thị trường bắt đầu tăng lên và xu hướng đang tăng lên. RSI được sử dụng để tạo tín hiệu giao dịch.


/*backtest
start: 2021-02-11 00:00:00
end: 2022-02-10 23:59:00
period: 15m
basePeriod: 5m
exchanges: [{"eid":"Huobi","currency":"BCH_USDT"}]
args: [["rsi_period",12],["atrma_period",18]]
*/

/*
* rsi_period: 强弱指标计算周期
* atr_period: 平均真实波幅计算周期
* atrma_period: 平均真实波幅均值计算呢周期
* tick_interval: 时间间隔
* slide_price: 下单滑动值
*/

// RSI指示操作状态
var RSI_NONE = 0;
var RSI_BUY = 1;
var RSI_SELL = 2;

var last_rsi_staus;

// ATR活跃信号判断
function isAtrActive(records) {
    let atr = TA.ATR(records, atr_period);
    let atrma = atr[atr.length - 1];
    if (atr.length > atrma_period) {
        let tmp_atr = 0;
        for (let i = atr.length - atrma_period; i < atr.length; i++) {
            tmp_atr += atr[i];
        }
        atrma = tmp_atr / atr_period;
    }
    else {
        atrma = aval(atr.join("+")) / atr.length;
    }
    return atr[atr.length - 1] > atrma;
}

// 获取RSI操作状态
function getRsiStatus(records) {
    let rsi = TA.RSI(records, rsi_period)[records.length - 1];
    if (rsi < 30) {
        return RSI_BUY;
    }
    else if (rsi > 70) {
        return RSI_SELL;
    }
    else {
        return RSI_NONE;
    }
}

// 取消未成交下单
function canelPendingOrders() {
    while (true) {
        let orders = _C(exchange.GetOrders);
        if (orders.length == 0) {
            break;
        }
        for (let i = 0; i < orders.length; i++) {
            exchange.CancelOrder(orders[i].Id);
        }
    }
}

function onTick() {
    let records = _C(exchange.GetRecords, PERIOD_M15);
    let ticker = _C(exchange.GetTicker);
    if (records == null ||
        ticker == null ||
        records.length < rsi_period ||
        records.length < atr_period) {
        return;
    }

    if (isAtrActive(records)) {
        let rsi = getRsiStatus(records);
        if (rsi != RSI_NONE) {
            let account = _C(exchange.GetAccount);
            if (rsi == RSI_BUY && last_rsi_staus != RSI_BUY) {
                Log("买入信号");
                last_rsi_staus = RSI_BUY;
                canelPendingOrders();
                if(account.Balance>0){
                    let price = ticker.Last + slide_price;
                    let amount = account.Balance / price * 0.99;
                    exchange.Buy(price, amount);
                }
            } else if (rsi == RSI_SELL && last_rsi_staus != RSI_SELL) {
                Log("卖出信号");
                last_rsi_staus = RSI_SELL;
                canelPendingOrders();
                if (account.Stocks > 0) {
                    let price = ticker.Last - slide_price;
                    exchange.Sell(price, account.Stocks);
                }
            }
        }
    }
    last_records = records;
}

function main() {
    while (true) {
        onTick();
        Sleep(tick_interval * 1000);
    }
}

Thêm nữa

Alô.Trả lời: RuntimeError: abort ((undefined) at Error at jsStackTrace, đó là một thứ điên rồ.

Một con daoCó thông tin gì khác không?