Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lucid sar to Python #7

Open
illi4 opened this issue Apr 15, 2024 · 1 comment
Open

Lucid sar to Python #7

illi4 opened this issue Apr 15, 2024 · 1 comment

Comments

@illi4
Copy link

illi4 commented Apr 15, 2024

I am trying to refactor the pinescript code to have an ability to calculate lucid SAR in Python. I am not having success and need some guidance / advice. Could someone please advice what I am doing wrong here?

def sar_v2(data, initial=0.02, increment=0.02, maximum=0.2):
  """
  Calculates the Lucid SAR indicator for a given DataFrame.

  Args:
      data: DataFrame containing columns for high, close, open, and low prices.
      initial: Initial acceleration factor.
      increment: Increment for acceleration factor.
      maximum: Maximum value for acceleration factor.

  Returns:
      A new DataFrame with an additional column named 'SAR' containing the Lucid SAR values.
  """
  data['SAR'] = float(data.loc[1, 'low'])  # Initialize SAR column with NaNs
  data['EP'] = float(data.loc[1, 'high'])  # Initialize EP column with NaNs
  data['AF'] = float(initial)  # Initialize AF column with NaNs
  data['uptrend'] = True     # Initialize uptrend flag (assuming uptrend starts)
  data['new_trend'] = False  # Initialize new_trend flag
  reversal_state = 0

  # Start from the 3rd candle to avoid NaNs
  for i in range(2, len(data)):
    # Handle previous values (avoid indexing issues)
    prev_uptrend = data.loc[i-1, 'uptrend']
    prev_new_trend = data.loc[i-1, 'new_trend']
    prev_EP = data.loc[i-1, 'EP']
    prev_SAR = data.loc[i-1, 'SAR']
    prev_AF = data.loc[i-1, 'AF']

    # Check reversal state
    if reversal_state == 0:
        if prev_uptrend:
            data.loc[i, 'EP'] = max(data.loc[i, 'high'], prev_EP)
        else:
            data.loc[i, 'EP'] = min(data.loc[i, 'low'], prev_EP)

        if prev_new_trend:
            data.loc[i, 'AF'] = initial
        else:
            if data.loc[i, 'EP'] != prev_EP:
                data.loc[i, 'AF'] = min(maximum, prev_AF + increment)
            else:
                data.loc[i, 'AF'] = prev_AF

        data.loc[i, 'SAR'] = prev_SAR + data.loc[i, 'AF'] * (data.loc[i, 'EP'] - prev_SAR)

        if prev_uptrend:
            data.loc[i, 'SAR'] = min(data.loc[i, 'SAR'], data.loc[i-1, 'low'])
            data.loc[i, 'SAR'] = min(data.loc[i, 'SAR'], data.loc[i-2, 'low'])
            if data.loc[i, 'SAR'] > data.loc[i, 'low']:
                data.loc[i, 'uptrend'] = False
                data.loc[i, 'new_trend'] = True
                data.loc[i, 'SAR'] = max(data.loc[i, 'high'], data.loc[i-1, 'EP'])
                data.loc[i, 'EP'] = min(data.loc[i, 'low'], data.loc[i-1, 'low'])
                reversal_state = 2
            else:
                data.loc[i, 'uptrend'] = True
                data.loc[i, 'new_trend'] = False
        else: #99
            data.loc[i, 'SAR'] = max(data.loc[i, 'SAR'], data.loc[i-1, 'high'])
            data.loc[i, 'SAR'] = max(data.loc[i, 'SAR'], data.loc[i-2, 'high'])
            if data.loc[i, 'SAR'] < data.loc[i, 'high']:
                data.loc[i, 'uptrend'] = True
                data.loc[i, 'new_trend'] = True
                data.loc[i, 'SAR'] = min(data.loc[i, 'low'], data.loc[i-1, 'EP'])
                data.loc[i, 'EP'] = max(data.loc[i, 'high'], data.loc[i-1, 'high'])
                reversal_state = 1
            else:
                data.loc[i, 'uptrend'] = False
                data.loc[i, 'new_trend'] = False
    # 111
    else:
        if reversal_state == 1:
            data.loc[i, 'EP'] = data.loc[i, 'high']
            if data.loc[i, 'low'] < data.loc[i, 'SAR']:
                data.loc[i, 'SAR'] = data.loc[i, 'EP']
                data.loc[i, 'EP'] = data.loc[i, 'low']
                reversal_state = 2  
                data.loc[i, 'uptrend'] = False
        else:
            data.loc[i, 'EP'] = data.loc[i, 'low']
            if data.loc[i, 'high'] > data.loc[i, 'SAR']:
                data.loc[i, 'SAR'] = data.loc[i, 'EP']
                data.loc[i, 'EP'] = data.loc[i, 'high']
                reversal_state = 1
                data.loc[i, 'uptrend'] = True

  return data
@illi4
Copy link
Author

illi4 commented Apr 15, 2024

And another attempt that gives PSAR result rather than Lucid SAR even though the rule to never move the SAR into the previous day’s range or today’s range are in:

def get_psar(barsdata, iaf=0.02, maxaf=0.2):

    length = len(barsdata)
    high = list(barsdata['high'])
    low = list(barsdata['low'])
    close = list(barsdata['close'])
    psar = close[0:len(close)]
    psarbull = [None] * length
    psarbear = [None] * length
    bull = True
    af = iaf
    ep = low[0]
    hp = high[0]
    lp = low[0]

    for i in range(2,length):
        if bull:
            psar[i] = psar[i - 1] + af * (hp - psar[i - 1])
        else:
            psar[i] = psar[i - 1] + af * (lp - psar[i - 1])

        reverse = False

        if bull:
            if low[i] < psar[i]:
                bull = False
                reverse = True
                psar[i] = hp
                lp = low[i]
                af = iaf
        else:
            if high[i] > psar[i]:
                bull = True
                reverse = True
                psar[i] = lp
                hp = high[i]
                af = iaf

        if not reverse:
            if bull:
                if high[i] > hp:
                    hp = high[i]
                    af = min(af + iaf, maxaf)
                if low[i - 1] < psar[i]:
                    psar[i] = low[i - 1]
                if low[i - 2] < psar[i]:
                    psar[i] = low[i - 2]
            else:
                if low[i] < lp:
                    lp = low[i]
                    af = min(af + iaf, maxaf)
                if high[i - 1] > psar[i]:
                    psar[i] = high[i - 1]
                if high[i - 2] > psar[i]:
                    psar[i] = high[i - 2]

        if bull:
            psarbull[i] = psar[i]
            barsdata.loc[i, 'PSAR_direction'] = 1
            barsdata.loc[i, 'PSAR_val'] = psar[i]
        else:
            psarbear[i] = psar[i]
            barsdata.loc[i, 'PSAR_direction'] = -1
            barsdata.loc[i, 'PSAR_val'] = psar[i]

    return barsdata

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant