twopirllc / pandas-ta

Technical Analysis Indicators - Pandas TA is an easy to use Python 3 Pandas Extension with 150+ Indicators
https://twopirllc.github.io/pandas-ta/
MIT License
5.31k stars 1.04k forks source link

Placing Trades Using the PSAR script #721

Closed pq219 closed 9 months ago

pq219 commented 1 year ago

First, i would like to give a shout out to the creator of this because I have been trying every avenue to get a psar script that works. This one does!

I am very new to coding and python so bare with me: In file psar.py, it works great in finding the PSAR but i am unable to move forward from this point and get robin-stocks to use this information to actually place a trade. any help or suggestions would be appreciated!

This is what I have in VSC:

from numpy import nan as npNaN
from pandas import DataFrame, Series
from pandas_ta.utils import get_offset, verify_series, zero
import robin_stocks.robinhood as rs

# Get your username and password from your Robinhood account
username = "xxxxxxx"
password = "xxxxxxx"

# Create a session with the Robinhood API
session = rs.login(username, password)

# Get the current stock price for KOLD
kold_price = rs.stocks.get_stock_quote_by_symbol("kold")

# Print the stock price
print(kold_price)

def psar(high, low, close=None, af0=0.0026, af=0.23, max_af=.483, offset=None, **kwargs):
    """Indicator: Parabolic Stop and Reverse (PSAR)"""
    # Validate Arguments
    high = verify_series(high)
    low = verify_series(low)
    af = float(af) if af and af > 0 else 0.02
    af0 = float(af0) if af0 and af0 > 0 else af
    max_af = float(max_af) if max_af and max_af > 0 else 0.2
    offset = get_offset(offset)

    def _falling(high, low, drift:int=1):
        """Returns the last -DM value"""
        # Not to be confused with ta.falling()
        up = high - high.shift(drift)
        dn = low.shift(drift) - low
        _dmn = (((dn > up) & (dn > 0)) * dn).apply(zero).iloc[-1]
        return _dmn > 0

    # Falling if the first NaN -DM is positive
    falling = _falling(high.iloc[:2], low.iloc[:2])
    if falling:
        sar = high.iloc[0]
        ep = low.iloc[0]
    else:
        sar = low.iloc[0]
        ep = high.iloc[0]

    if close is not None:
        close = verify_series(close)
        sar = close.iloc[0]

    long = Series(npNaN, index=high.index)
    short = long.copy()
    reversal = Series(0, index=high.index)
    _af = long.copy()
    _af.iloc[0:2] = af0

    # Calculate Result
    m = high.shape[0]
    for row in range(1, m):
        high_ = high.iloc[row]
        low_ = low.iloc[row]

        if falling:
            _sar = sar + af * (ep - sar)
            reverse = high_ > _sar

            if low_ < ep:
                ep = low_
                af = min(af + af0, max_af)

            _sar = max(high.iloc[row - 1], high.iloc[row - 2], _sar)
        else:
            _sar = sar + af * (ep - sar)
            reverse = low_ < _sar

            if high_ > ep:
                ep = high_
                af = min(af + af0, max_af)

            _sar = min(low.iloc[row - 1], low.iloc[row - 2], _sar)

        if reverse:
            _sar = ep
            af = af0
            falling = not falling # Must come before next line
            ep = low_ if falling else high_

        sar = _sar # Update SAR

        # Seperate long/short sar based on falling
        if falling:
            short.iloc[row] = sar
        else:
            long.iloc[row] = sar

        _af.iloc[row] = af
        reversal.iloc[row] = int(reverse)

    # Offset
    if offset != 0:
        _af = _af.shift(offset)
        long = long.shift(offset)
        short = short.shift(offset)
        reversal = reversal.shift(offset)

    # Handle fills
    if "fillna" in kwargs:
        _af.fillna(kwargs["fillna"], inplace=True)
        long.fillna(kwargs["fillna"], inplace=True)
        short.fillna(kwargs["fillna"], inplace=True)
twopirllc commented 1 year ago

Hello @pq219,

Thanks!

Also, can you tell us more about your environment?

Do you have TA Lib also installed in your environment?

$ pip list

Have you tried the development version?

$ pip install -U git+https://github.com/twopirllc/pandas-ta.git@development

I am very new to coding and python so bare with me: In file psar.py, it works great in finding the PSAR but i am unable to move forward from this point and get robin-stocks to use this information to actually place a trade. any help or suggestions would be appreciated!

Whenever I am learning something new, I spend some time familiarizing myself with the documentation. Since you are using robin_stocks, I would start with their documentation and examples.



Try this to calculate psar with robin_stocks. It's not perfect because I do not use Robinhood, so you may need a little tweaking. Additionally, you will need to do some post analysis of your psar calculation to determine when to buy/sell etc.

from numpy import nan as npNaN
from pandas import DataFrame, Series
from pandas_ta.utils import get_offset, verify_series, zero
import robin_stocks.robinhood as rs

# Get your username and password from your Robinhood account
username, password = "xxxxxxx", "xxxxxxx"

# Asset ticker/symbol to retreive
ticker = "kold"

# Create a session with the Robinhood API
session = rs.login(username, password)

# Get the current stock price for KOLD as a single Python dictionary
# kold_price = rs.stocks.get_stock_quote_by_symbol("kold")

# Instead, use get_stock_historicals() which returns a list of dictionaries
# so it can be converted to a Pandas DataFrame
data = rs.stocks.get_stock_historicals(ticker, interval="day", span="year", bounds="regular")

# Convert data into a Pandas DataFrame
assetdf = DataFrame(data)
print(f"{assetdf.size=}")

assetdf.ta.psar(append=True)  # Appends `psar` to assetdf 
print(f"{assetdf.size=}")  # Should be larger than the prior size 
print(f"{ticker=}\n{assetdf}")

Kind Regards, KJ

See also

twopirllc commented 1 year ago

Hello @pq219,

I assume by no response that the solution provided was sufficient. Thus I will be closing this issue in a few days.

Kind Regards, KJ