0

I need to decide whether a row of stock-quotes meet certain criteria. For this I use the function 'Trade_signal_calc' to test if MACD (one col in df) is positive (first if). Then if 'MACD' passes the 'MACDsig' (another col from df) from below (second if) - and finally if 'MACD' passes 'MACDsig' from above (third if).

These 2 cols 'MACD' and 'MACDsig' from my df must be passed as parameter-input into my f(). The resulting col is called 'Trade' and should show either 'Buy', 'Sell', or NaN.

I am comparing only same-tickers to each-other, so I use pd.groupby for this grouping. It works.

But I have struggled to get more than one input parameter (col) into my f(), so have finally found a solution in functools.partial mentioned here: How does the functools partial work in Python?

And it seems to work/run. However see my questions below my code and output

My code

import pandas as pd
import numpy as np
from io import StringIO
import functools

text = """Ticker Date Adj_Close Volume MACD emaSlw emaFst MACDsig MACDperc
A 18-07-2016 46.8 1362900.0 0.55 45.81 45.26 0.21 -0.9954
A 19-07-2016 46.98 2579000.0 0.6 45.99 45.39 0.29 -0.9937
AA 18-07-2016 10.92 16297800.0 0.32 10.27 9.94 0.1 -0.99
AA 19-07-2016 10.63 14316200.0 0.33 10.32 9.99 0.15 -0.9856
AAL 18-07-2016 36.03 8604200.0 1.15 32.84 31.69 -0.08 -10.023
AAL 19-07-2016 36.01 7928100.0 1.32 33.33 32.01 0.19 -0.9942
AAP 18-07-2016 164.4 516800.0 2.83 162.59 159.75 2.72 -0.9832
AAP 19-07-2016 163.7 854700.0 2.71 162.76 160.05 2.76 -0.983
AAPL 18-07-2016 99.83 36439900.0 0.5 97.36 96.86 -0.16 -10.017
AAPL 19-07-2016 99.87 23703900.0 0.67 97.75 97.08 -0.01 -10.001
ABBV 18-07-2016 63.56 6384800.0 0.9 63.06 62.16 0.71 -0.9887
ABBV 19-07-2016 63.32 5716800.0 0.86 63.1 62.25 0.78 -0.9876
ABC 18-07-2016 86.03 1113600.0 2.31 82.91 80.6 1.52 -0.9817
ABC 19-07-2016 85.92 1975400.0 2.38 83.38 81.0 1.7 -0.9796
ABT 18-07-2016 42.09 7524200.0 -1.05 41.14 40.09 0.75 -0.9818
ABT 19-07-2016 41.8 8395400.0 1.02 41.24 40.22 0.84 -0.9796"""

df = pd.read_csv(StringIO(text), delim_whitespace=1, parse_dates=[0], index_col=1)

df.drop(['Volume', 'emaSlw', 'emaFst', 'MACDperc'],inplace=True,axis=1)

#print('df to check numbering and cols. \n%s' %(df.iloc[0:4,0:6]))
#print('\ndf cols. 3-4 = MACD, MACDsig \n%s' %(df.iloc[0:4,2:4])) #rows, cols



def Trade_signal_calc(group, x, y):  # group
#def Trade_signal_calc(group):

    if df['MACD'].irow(-1) > 0: # MACD is pos. so trade (BUY/Sell)
        # BUY signals
        print('\n[MACD].irow(-1) > 0 PASSED 1st if\n Group: \n%s' %(group))
        # if todays MACD is higher than signal, AND yesturday's MACD was lower than signal
        if  (df['MACD'].irow(-1) > df['MACDsig'].irow(-1)) \
        & (df['MACD'].irow(-2) < df['MACDsig'].irow(-2)) :
            df['Trade'] = 'Buy'
            print('\n(df[MACD].irow(-1) > df[MACDsig].irow(-1)) \
        & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) \n== PASSED 2nd if\n Group: \n%s' %(group))
            return df
        # SELL signals
        # if todays MACD is lower than signal, AND yesturday's MACD was higher than signal - reverse the above
        elif  (df['MACD'].irow(-1) < df['MACDsig'].irow(-1)) \
        & ((df['MACD'].irow(-2)) > df['MACDsig'].irow(-2)) : 
            df['Trade'] = 'Sell'
            print('(df[MACD].irow(-1) < df[MACDsig].irow(-1)) \
        & (df[MACD].irow(-2) > df[MACDsig].irow(-2)) == PASSED 3rd (el)if\n MACD: \n%s, \nMACDsig: \n%s' %(x, y))
            return df
        else:   # No strong Buy or Sell signals
            print('No strong Buy or Sell signals')
            return df
    else:   # MACD is neg. so don't trade
        print('MACD is neg. so dont trade')
        return df



if __name__ == '__main__':

    # Multiindex Needed for my groupby to work properly ???
    df = df.set_index('Ticker', append=True)

    '''Testing functools.partial to manage the number of params for groupby to input 
    2 cols from df.'''

    fnc = functools.partial(Trade_signal_calc, x=df['MACD'], y=df['MACDsig'])
    df['Trade'] = df.groupby(level='Ticker').agg({'MACD': fnc, 'MACDsig': fnc})
#    df['Trade'] = df.groupby(level='Ticker').apply(lambda x: fcn())

    print ('\ndf with Buy & Sell signals & with multi-index (of Date and Ticker) \ndfTrade shows trades from MACD & MACDsig comparison (summary from df) (Output)\n%s\nSignals: \nBuy: (df(MACD[-1]) > df(MACDsig[-1])) & (df(MACD[-2]) < df(MACDsig[-2])) \nSell: (df(MACD[-1]) < df(MACDsig[-1])) & (df(MACD[-2]) > df(MACDsig[-2])) \n\n%s' %(75*'-',df))#[['Trade','MACD','MACDsig','Adj_Close','Date']]))

    # Resetting index from before doing groupby w. multi-index
    df = df.reset_index('Ticker')    

    # Test the first 3 rows of each group for 'Difference' col transgress groups...
    df = df.groupby('Ticker').head(3).reset_index().set_index('Date')
    print ('%s\ndf (summary from df - without multi-index) (Output)\n%s\n' %(75*'-',df))

Output (Stacktrace)

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  A         0.55
19-07-2016  A         0.60
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  A         0.55
19-07-2016  A         0.60
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AA        0.32
19-07-2016  AA        0.33
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AA        0.32
19-07-2016  AA        0.33
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AAL       1.15
19-07-2016  AAL       1.32
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AAL       1.15
19-07-2016  AAL       1.32
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AAP       2.83
19-07-2016  AAP       2.71
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AAP       2.83
19-07-2016  AAP       2.71
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AAPL      0.50
19-07-2016  AAPL      0.67
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AAPL      0.50
19-07-2016  AAPL      0.67
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  ABBV      0.90
19-07-2016  ABBV      0.86
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  ABBV      0.90
19-07-2016  ABBV      0.86
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  ABC       2.31
19-07-2016  ABC       2.38
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  ABC       2.31
19-07-2016  ABC       2.38
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  ABT      -1.05
19-07-2016  ABT       1.02
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  ABT      -1.05
19-07-2016  ABT       1.02
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  A         0.21
19-07-2016  A         0.29
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  A         0.21
19-07-2016  A         0.29
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AA        0.10
19-07-2016  AA        0.15
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AA        0.10
19-07-2016  AA        0.15
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AAL      -0.08
19-07-2016  AAL       0.19
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AAL      -0.08
19-07-2016  AAL       0.19
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AAP       2.72
19-07-2016  AAP       2.76
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AAP       2.72
19-07-2016  AAP       2.76
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AAPL     -0.16
19-07-2016  AAPL     -0.01
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AAPL     -0.16
19-07-2016  AAPL     -0.01
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  ABBV      0.71
19-07-2016  ABBV      0.78
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  ABBV      0.71
19-07-2016  ABBV      0.78
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  ABC       1.52
19-07-2016  ABC       1.70
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  ABC       1.52
19-07-2016  ABC       1.70
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  ABT       0.75
19-07-2016  ABT       0.84
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  ABT       0.75
19-07-2016  ABT       0.84
Name: MACDsig, dtype: float64

df with Buy & Sell signals & with multi-index (of Date and Ticker) 
dfTrade shows trades from MACD & MACDsig comparison (summary from df) (Output)
---------------------------------------------------------------------------
Signals: 
Buy: (df(MACD[-1]) > df(MACDsig[-1])) & (df(MACD[-2]) < df(MACDsig[-2])) 
Sell: (df(MACD[-1]) < df(MACDsig[-1])) & (df(MACD[-2]) > df(MACDsig[-2])) 

                   Adj_Close  MACD  MACDsig Trade
Date       Ticker                                
18-07-2016 A           46.80  0.55     0.21   NaN
19-07-2016 A           46.98  0.60     0.29   NaN
18-07-2016 AA          10.92  0.32     0.10   NaN
19-07-2016 AA          10.63  0.33     0.15   NaN
18-07-2016 AAL         36.03  1.15    -0.08   NaN
19-07-2016 AAL         36.01  1.32     0.19   NaN
18-07-2016 AAP        164.40  2.83     2.72   NaN  At least this should be marked 'Buy'
19-07-2016 AAP        163.70  2.71     2.76   NaN
18-07-2016 AAPL        99.83  0.50    -0.16   NaN
19-07-2016 AAPL        99.87  0.67    -0.01   NaN
18-07-2016 ABBV        63.56  0.90     0.71   NaN
19-07-2016 ABBV        63.32  0.86     0.78   NaN
18-07-2016 ABC         86.03  2.31     1.52   NaN
19-07-2016 ABC         85.92  2.38     1.70   NaN
18-07-2016 ABT         42.09 -1.05     0.75   NaN
19-07-2016 ABT         41.80  1.02     0.84   NaN
---------------------------------------------------------------------------
df (summary from df - without multi-index) (Output)
           Ticker  Adj_Close  MACD  MACDsig Trade
Date                                             
18-07-2016      A      46.80  0.55     0.21   NaN
19-07-2016      A      46.98  0.60     0.29   NaN
18-07-2016     AA      10.92  0.32     0.10   NaN
19-07-2016     AA      10.63  0.33     0.15   NaN
18-07-2016    AAL      36.03  1.15    -0.08   NaN
19-07-2016    AAL      36.01  1.32     0.19   NaN
18-07-2016    AAP     164.40  2.83     2.72   NaN  At least this should be marked 'Buy'
19-07-2016    AAP     163.70  2.71     2.76   NaN
18-07-2016   AAPL      99.83  0.50    -0.16   NaN
19-07-2016   AAPL      99.87  0.67    -0.01   NaN
18-07-2016   ABBV      63.56  0.90     0.71   NaN
19-07-2016   ABBV      63.32  0.86     0.78   NaN
18-07-2016    ABC      86.03  2.31     1.52   NaN
19-07-2016    ABC      85.92  2.38     1.70   NaN
18-07-2016    ABT      42.09 -1.05     0.75   NaN
19-07-2016    ABT      41.80  1.02     0.84   NaN
  1. My 2 last prints of the df (one with multi-index and one without it), do not show that actually the stock rows for AAP should be marked with 'Buy', but simply says NaN... This is wrong...
  2. I have made my if-statements print explicit results, so I can troubleshoot the if-tests. This is also not working according to my f(), as these print-outputs omit the second parameter 'MACDsig' col.

It looks as if my groupby works properly. Also the use of my fcn = .... runs, but in the upper print-output, it should print BOTH MACD AND MACDsig cols. This does not happen, but only the MACD specified as first input-parameter in the f() shows up as it should, why does the 'MACDsig' col not get printet in these outputs?

It most probably is also the cause for my if-statements to not work correctly.

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  A         0.55
19-07-2016  A         0.60
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  A         0.55
19-07-2016  A         0.60
Name: MACD, dtype: float64
Community
  • 1
  • 1
Excaliburst
  • 143
  • 1
  • 4
  • 15
  • The function `Trade_signal_calc(group, x, y)` doesn't use the arguments `group, x, y`. Can you explain what you want to do with this function. – HYRY Oct 08 '16 at 11:55
  • The function test if MACD is positive (first if). Then if MACD passes the MACDsig from below (second if) - and finally if MACD passes MACDsig from above (third if). – Excaliburst Oct 10 '16 at 12:10
  • I have explained it better in my question - Thanks @HYRY – Excaliburst Oct 10 '16 at 12:17

0 Answers0