리소스 로딩... 로딩...

ATR-RSI 포트폴리오 전략

저자:, 날짜: 2022-02-13 17:17:17
태그:

Atr 지표

평균 진실 범위 (Average True Range), ATR 지표 (ATR 지표) 는 주로 시장의 변동성을 측정하는 지표로 사용되며 시장의 변동률을 보여줍니다. 그러나 가격 방향과 트렌드의 안정성을 반영하지는 않습니다. 이 지표의 값이 높을수록 트렌드 변화가 가능하며 트렌드 변화가 가능성은 적습니다.

계산 방법

지난 N일 동안의 실제 변동과 당일의 실제 변동 계산에 기초한 평균 실제 변동 범위. 일일 실제 변동 뿌리는 ((오늘의 최고 가격-오늘의 최저 가격) ; ((오늘의 최고 가격-오늘의 폐쇄 가격) ; ((오늘의 폐쇄 가격-오늘의 최저 가격)) 세 가지 결과 집합 중 가장 큰 값을 취하여 최대 변동 범위의 가격 차이를 얻으려는 것이다.

Rsi 지표

상대적 강도 지표 (Relative Strength Index), RSI 지표 (Relative Strength Index) 는 장기간에 걸쳐 양측의 구매력과 판매력의 강도와 약도를 비교하여 미래의 시장 흐름을 판단하는 기술 지표이다.

계산 방법

RSI = 100 - (100/(1+RS)); RS = n일 마감 수와/n일 마감 하락 수의 합; 일반적으로 RSI는 50을 중점으로, 50보다 큰 것은 다중 시장으로, 50보다 작은 것은 빈 시장으로 간주됩니다. RSI 70 이상은 과잉 구매 상태로 간주되며, 후속 시장이 회전 또는 전환될 수 있으며, 30 이하는 과잉 판매 상태로 간주되며, 후속 시장이 상승할 수 있습니다.

전략적 원칙

ATR은 필터링을 위해 사용되며, ATR>ATRMa (지난 N 일간의 평균 ATR) 가 시장 변동의 폭이 증가하기 시작하여 추세가 강화되고 있음을 나타냅니다. RSI는 거래 신호를 생성하는 데 사용됩니다.


/*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);
    }
}

더 많은

알레JSStackTrace에서 오류가 발생했습니다.

다른 정보가 있나요?