1. THÔNG BÁO VỀ VIỆC TUÂN THỦ QUY ĐỊNH PHÁP LUẬT KHI THAM GIA DIỄN ĐÀN

    Đề nghị toàn thể thành viên diễn đàn nghiêm túc tuân thủ Luật Chứng khoán, các quy định của Ủy ban Chứng khoán Nhà nước, đồng thời tuân thủ các quy định pháp luật liên quan đến an ninh mạng, giao dịch điện tử và trách nhiệm cá nhân khi đăng tải, chia sẻ thông tin trên môi trường mạng, bao gồm các quy định tại Nghị định 174/2026/NĐ-CP. xem thêm

Nhờ Trợ giúp AFL coder

Chủ đề trong 'Thị trường chứng khoán' bởi khoang75, 21/03/2021.

Có 1824 người đang online, trong đó có 12 thành viên. 02:38 (UTC+07:00) Bangkok, Hanoi, Jakarta
  1. Có 1 người đang xem box này (Thành viên: 0, Khách: 1)
Chủ đề này đã có 806 lượt đọc và 0 bài trả lời
  1. khoang75

    khoang75 Thành viên gắn bó với f319.com

    Tham gia ngày:
    27/03/2006
    Đã được thích:
    776
    Hởi các cao nhân AFL xin chuyển đổi giúp đoạn code PINE sau thành AFL nhé:
    study(title="Delta-RSI Oscillator Strategy", shorttitle = "D-RSI", overlay = true)

    // ---Subroutines---
    matrix_get(_A,_i,_j,_nrows) =>
    // Get the value of the element of an implied 2d matrix
    //input:
    // _A :: array: pseudo 2d matrix _A = [[column_0],[column_1],...,[column_(n-1)]]
    // _i :: integer: row number
    // _j :: integer: column number
    // _nrows :: integer: number of rows in the implied 2d matrix
    array.get(_A,_i+_nrows*_j)

    matrix_set(_A,_value,_i,_j,_nrows) =>
    // Set a value to the element of an implied 2d matrix
    //input:
    // _A :: array, changed on output: pseudo 2d matrix _A = [[column_0],[column_1],...,[column_(n-1)]]
    // _value :: float: the new value to be set
    // _i :: integer: row number
    // _j :: integer: column number
    // _nrows :: integer: number of rows in the implied 2d matrix
    array.set(_A,_i+_nrows*_j,_value)

    transpose(_A,_nrows,_ncolumns) =>
    // Transpose an implied 2d matrix
    // input:
    // _A :: array: pseudo 2d matrix _A = [[column_0],[column_1],...,[column_(n-1)]]
    // _nrows :: integer: number of rows in _A
    // _ncolumns :: integer: number of columns in _A
    // output:
    // _AT :: array: pseudo 2d matrix with implied dimensions: _ncolums x _nrows
    var _AT = array.new_float(_nrows*_ncolumns,0)
    for i = 0 to _nrows-1
    for j = 0 to _ncolumns-1
    matrix_set(_AT, matrix_get(_A,i,j,_nrows),j,i,_ncolumns)
    _AT

    multiply(_A,_B,_nrowsA,_ncolumnsA,_ncolumnsB) =>
    // Calculate scalar product of two matrices
    // input:
    // _A :: array: pseudo 2d matrix
    // _B :: array: pseudo 2d matrix
    // _nrowsA :: integer: number of rows in _A
    // _ncolumnsA :: integer: number of columns in _A
    // _ncolumnsB :: integer: number of columns in _B
    // output:
    // _C:: array: pseudo 2d matrix with implied dimensions _nrowsA x _ncolumnsB
    var _C = array.new_float(_nrowsA*_ncolumnsB,0)
    int _nrowsB = _ncolumnsA
    float elementC= 0.0
    for i = 0 to _nrowsA-1
    for j = 0 to _ncolumnsB-1
    elementC := 0
    for k = 0 to _ncolumnsA-1
    elementC := elementC + matrix_get(_A,i,k,_nrowsA)*matrix_get(_B,k,j,_nrowsB)
    matrix_set(_C,elementC,i,j,_nrowsA)
    _C

    vnorm(_X,_n) =>
    //Square norm of vector _X with size _n
    float _norm = 0.0
    for i = 0 to _n-1
    _norm := _norm + pow(array.get(_X,i),2)
    sqrt(_norm)

    qr_diag(_A,_nrows,_ncolumns) =>
    //QR Decomposition with Modified Gram-Schmidt Algorithm (Column-Oriented)
    // input:
    // _A :: array: pseudo 2d matrix _A = [[column_0],[column_1],...,[column_(n-1)]]
    // _nrows :: integer: number of rows in _A
    // _ncolumns :: integer: number of columns in _A
    // output:
    // _Q: unitary matrix, implied dimenstions _nrows x _ncolumns
    // _R: upper triangular matrix, implied dimansions _ncolumns x _ncolumns
    var _Q = array.new_float(_nrows*_ncolumns,0)
    var _R = array.new_float(_ncolumns*_ncolumns,0)
    var _a = array.new_float(_nrows,0)
    var _q = array.new_float(_nrows,0)
    float _r = 0.0
    float _aux = 0.0
    //get first column of _A and its norm:
    for i = 0 to _nrows-1
    array.set(_a,i,matrix_get(_A,i,0,_nrows))
    _r := vnorm(_a,_nrows)
    //assign first diagonal element of R and first column of Q
    matrix_set(_R,_r,0,0,_ncolumns)
    for i = 0 to _nrows-1
    matrix_set(_Q,array.get(_a,i)/_r,i,0,_nrows)
    if _ncolumns != 1
    //repeat for the rest of the columns
    for k = 1 to _ncolumns-1
    for i = 0 to _nrows-1
    array.set(_a,i,matrix_get(_A,i,k,_nrows))
    for j = 0 to k-1
    //get R_jk as scalar product of Q_j column and A_k column:
    _r := 0
    for i = 0 to _nrows-1
    _r := _r + matrix_get(_Q,i,j,_nrows)*array.get(_a,i)
    matrix_set(_R,_r,j,k,_ncolumns)
    //update vector _a
    for i = 0 to _nrows-1
    _aux := array.get(_a,i) - _r*matrix_get(_Q,i,j,_nrows)
    array.set(_a,i,_aux)
    //get diagonal R_kk and Q_k column
    _r := vnorm(_a,_nrows)
    matrix_set(_R,_r,k,k,_ncolumns)
    for i = 0 to _nrows-1
    matrix_set(_Q,array.get(_a,i)/_r,i,k,_nrows)
    [_Q,_R]

    pinv(_A,_nrows,_ncolumns) =>
    //Pseudoinverse of matrix _A calculated using QR decomposition
    // Input:
    // _A:: array: implied as a (_nrows x _ncolumns) matrix _A = [[column_0],[column_1],...,[column_(_ncolumns-1)]]
    // Output:
    // _Ainv:: array implied as a (_ncolumns x _nrows) matrix _A = [[row_0],[row_1],...,[row_(_nrows-1)]]
    // ----
    // First find the QR factorization of A: A = QR,
    // where R is upper triangular matrix.
    // Then _Ainv = R^-1*Q^T.
    // ----
    [_Q,_R] = qr_diag(_A,_nrows,_ncolumns)
    _QT = transpose(_Q,_nrows,_ncolumns)
    // Calculate Rinv:
    var _Rinv = array.new_float(_ncolumns*_ncolumns,0)
    float _r = 0.0
    matrix_set(_Rinv,1/matrix_get(_R,0,0,_ncolumns),0,0,_ncolumns)
    if _ncolumns != 1
    for j = 1 to _ncolumns-1
    for i = 0 to j-1
    _r := 0.0
    for k = i to j-1
    _r := _r + matrix_get(_Rinv,i,k,_ncolumns)*matrix_get(_R,k,j,_ncolumns)
    matrix_set(_Rinv,_r,i,j,_ncolumns)
    for k = 0 to j-1
    matrix_set(_Rinv,-matrix_get(_Rinv,k,j,_ncolumns)/matrix_get(_R,j,j,_ncolumns),k,j,_ncolumns)
    matrix_set(_Rinv,1/matrix_get(_R,j,j,_ncolumns),j,j,_ncolumns)
    //
    _Ainv = multiply(_Rinv,_QT,_ncolumns,_ncolumns,_nrows)
    _Ainv

    norm_rmse(_x, _xhat) =>
    // Root Mean Square Error normalized to the sample mean
    // _x. :: array float, original data
    // _xhat :: array float, model estimate
    // output
    // _nrmse:: float
    float _nrmse = 0.0
    if array.size(_x) != array.size(_xhat)
    _nrmse := na
    else
    int _N = array.size(_x)
    float _mse = 0.0
    for i = 0 to _N-1
    _mse := _mse + pow(array.get(_x,i) - array.get(_xhat,i),2)/_N
    _xmean = array.sum(_x)/_N
    _nrmse := sqrt(_mse) /_xmean
    _nrmse


    diff(_src,_window,_degree) =>
    // Polynomial differentiator
    // input:
    // _src:: input series
    // _window:: integer: wigth of the moving lookback window
    // _degree:: integer: degree of fitting polynomial
    // output:
    // _diff :: series: time derivative
    // _nrmse:: float: normalized root mean square error
    //
    // Vandermonde matrix with implied dimensions (window x degree+1)
    // Linear form: J = [ [z]^0, [z]^1, ... [z]^degree], with z = [ (1-window)/2 to (window-1)/2 ]
    var _J = array.new_float(_window*(_degree+1),0)
    for i = 0 to _window-1
    for j = 0 to _degree
    matrix_set(_J,pow(i,j),i,j,_window)
    // Vector of raw datapoints:
    var _Y_raw = array.new_float(_window,na)
    for j = 0 to _window-1
    array.set(_Y_raw,j,_src[_window-1-j])
    // Calculate polynomial coefficients which minimize the loss function
    _C = pinv(_J,_window,_degree+1)
    _a_coef = multiply(_C,_Y_raw,_degree+1,_window,1)
    // For first derivative, approximate the last point (i.e. z=window-1) by
    float _diff = 0.0
    for i = 1 to _degree
    _diff := _diff + i*array.get(_a_coef,i)*pow(_window-1,i-1)
    // Calculates data estimate (needed for rmse)
    _Y_hat = multiply(_J,_a_coef,_window,_degree+1,1)
    float _nrmse = norm_rmse(_Y_raw,_Y_hat)
    [_diff,_nrmse]

    /// --- main ---
    degree = input(title="Polynomial Order", group = "Model Parameters:",
    inline = "linepar1", type = input.integer, defval=2, minval = 1)
    rsi_l = input(title = "RSI Length", group = "Model Parameters:",
    inline = "linepar1", type = input.integer, defval = 21, minval = 1,
    tooltip="The period length of RSI that is used as input.")
    window = input(title="Length ( > Order)", group = "Model Parameters:",
    inline = "linepar2", type = input.integer, defval=21, minval = 2)
    signalLength = input(title="Signal Length", group = "Model Parameters:",
    inline = "linepar2", type=input.integer, defval=9,
    tooltip="The signal line is a EMA of the D-RSI time series.")
    islong = input(title = "Buy", group = "Show Signals:",
    inline = "lineent",type = input.bool, defval = true)
    isshort = input(title = "Sell", group = "Show Signals:",
    inline = "lineent", type = input.bool, defval= true)
    showendlabels = input(title = "Exit", group = "Show Signals:",
    inline = "lineent", type = input.bool, defval= true)
    buycond = input(title="Buy", group = "Entry and Exit Conditions:",
    inline = "linecond",type = input.string, defval="Zero-Crossing",
    options=["Zero-Crossing", "Signal Line Crossing","Direction Change"])
    sellcond = input(title="Sell", group = "Entry and Exit Conditions:",
    inline = "linecond",type = input.string, defval="Zero-Crossing",
    options=["Zero-Crossing", "Signal Line Crossing","Direction Change"])
    endcond = input(title="Exit", group = "Entry and Exit Conditions:",
    inline = "linecond",type = input.string, defval="Zero-Crossing",
    options=["Zero-Crossing", "Signal Line Crossing","Direction Change"])
    usenrmse = input(title = "", group = "Filter by Means of Root-Mean-Square Error of RSI Fitting:",
    inline = "linermse",type = input.bool, defval = false)
    rmse_thrs = input(title = "RSI fitting Error Threshold, %", type = input.float,
    group = "Filter by Means of Root-Mean-Square Error of RSI Fitting:",
    inline = "linermse", defval = 10, minval = 0.0) /100


    src = rsi(close,rsi_l)
    [drsi,nrmse] = diff(src,window,degree)
    signalline = ema(drsi, signalLength)

    // Conditions and filters
    filter_rmse = usenrmse?nrmsedrsi[1]) and (drsi[1]drsi[2]) and drsi[1]>0.0
    crossup = crossover(drsi,0.0)
    crossdw = crossunder(drsi,0.0)
    crosssignalup = crossover(drsi,signalline)
    crosssignaldw = crossunder(drsi,signalline)

    //Signals
    golong = (buycond=="Direction Change"?dirchangeup:(buycond=="Zero-Crossing"?crossup:crosssignalup)) and filter_rmse
    goshort= (sellcond=="Direction Change"?dirchangedw:(sellcond=="Zero-Crossing"?crossdw:crosssignaldw)) and filter_rmse
    endlong = (endcond=="Direction Change"?dirchangedw:(endcond=="Zero-Crossing"?crossdw:crosssignaldw)) and filter_rmse
    endshort= (endcond=="Direction Change"?dirchangeup:(endcond=="Zero-Crossing"?crossup:crosssignalup)) and filter_rmse
    plotshape((golong and islong) ? low : na, location=location.belowbar, style=shape.labelup, color=#2E7C13, size=size.small, title='Buy')
    plotshape((goshort and isshort) ? high: na, location=location.abovebar, style=shape.labeldown, color=#BF217C, size=size.small, title='Sell')
    plotshape((showendlabels and endlong and islong) ? high: na, location=location.abovebar, style=shape.xcross, color=#2E7C13, size=size.tiny, title='Exit Long')
    plotshape((showendlabels and endshort and isshort) ? low : na, location=location.belowbar, style=shape.xcross, color=#BF217C, size=size.tiny, title='Exit Short')

    alertcondition(golong, title='Long Signal', message='D-RSI: Long Signal')
    alertcondition(goshort, title='Short Signal', message='D-RSI: Short Signal')
    alertcondition(endlong, title='Exit Long Signal', message='D-RSI: Exit Long')
    alertcondition(endshort, title='Exit Short Signal', message='D-RSI: Exit Short')

Chia sẻ trang này