daveskis
daveskis

Reputation: 153

Python - Portfolio Open Position Flag

I have a dataframe below:

 ticker       date  buy_fg  sell_fg
50      ABC 2010-01-01     0.0      2.0
51      ABC 2010-01-08     0.0      2.0
52      ABC 2010-01-15     0.0      2.0
53      ABC 2010-01-22     0.0      2.0
1512    ABC 2010-01-29     1.0      0.0
54      ABC 2010-02-05     0.0      2.0
55      ABC 2010-02-12     0.0      2.0
56      ABC 2010-02-19     0.0      2.0
57      ABC 2010-02-26     0.0      2.0
58      ABC 2010-03-05     0.0      2.0
59      ABC 2010-03-12     0.0      2.0
60      ABC 2010-03-19     0.0      2.0
61      ABC 2010-03-26     0.0      2.0
1417    ABC 2010-04-02     1.0      0.0
1409    ABC 2010-04-09     1.0      0.0
62      ABC 2010-04-23     0.0      2.0
63      ABC 2010-05-07     0.0      2.0
64      ABC 2010-05-14     0.0      2.0
65      ABC 2010-05-21     0.0      2.0
66      ABC 2010-05-28     0.0      2.0

I am trying to develop a column that provides a summary of the action that my script needs to take. I have tried to develop a cumulative score approach and haven't been able to get it to work. I have also tried lambda, however the logic isn't right as it just repeats the buy_fg column.

# Initiate the global, default buy flag
hold_flag =  False
 
# Custom function to flick the global flag based on `buy_fg` column
def hold(value):
    global hold_flag 
    if value == 1:
        if hold_flag is False:
            hold_flag = True
            return '3'
        if hold_flag is True:
            hold_flag = False
            return '1'
    else:
        return '0'

new_report['hold_fg'] = new_report['buy_fg'].apply(hold)

This created hold_fg column. But now I need to expand upon this to consider all three *_fg columns to provide the final action.

      ticker       date  buy_fg  sell_fg  action hold_fg
50      ABC 2010-01-01     0.0      2.0       0       0
51      ABC 2010-01-08     0.0      2.0       0       0
52      ABC 2010-01-15     0.0      2.0       0       0
53      ABC 2010-01-22     0.0      2.0       0       0
1512    ABC 2010-01-29     1.0      0.0       0       1
54      ABC 2010-02-05     0.0      2.0       0       0
55      ABC 2010-02-12     0.0      2.0       0       0
56      ABC 2010-02-19     0.0      2.0       0       0
57      ABC 2010-02-26     0.0      2.0       0       0
58      ABC 2010-03-05     0.0      2.0       0       0
59      ABC 2010-03-12     0.0      2.0       0       0
60      ABC 2010-03-19     0.0      2.0       0       0
61      ABC 2010-03-26     0.0      2.0       0       0
1417    ABC 2010-04-02     1.0      0.0       0       1
1409    ABC 2010-04-09     1.0      0.0       0       3
62      ABC 2010-04-23     0.0      2.0       0       0
63      ABC 2010-05-07     0.0      2.0       0       0
64      ABC 2010-05-14     0.0      2.0       0       0
65      ABC 2010-05-21     0.0      2.0       0       0
66      ABC 2010-05-28     0.0      2.0       0       0

I have tried the following, but this doesn't work:

new_report['action'] = 0

buy_flag = False

def action(value):
    global buy_flag
    if new_report['hold_fg'] == 1:
        buy_flag = True
        return 'BUY'
    if new_report['hold_fg'] == 3:
        buy_flag = True
        return 'HOLD'
    if new_report['sell_fg'] == 2:
        buy_flag = False
        return 'SELL'
    else:
        return '0'

Any ideas on how I can solve this?

updated expected output:

     ticker       date  buy_fg  sell_fg action hold_fg
50      ABC 2010-01-01     0.0      2.0    NIL       0
51      ABC 2010-01-08     0.0      2.0    NIL       0
52      ABC 2010-01-15     0.0      2.0    NIL       0
53      ABC 2010-01-22     0.0      2.0    NIL       0
1512    ABC 2010-01-29     1.0      0.0    BUY       1
54      ABC 2010-02-05     0.0      2.0   SELL       0
55      ABC 2010-02-12     0.0      2.0    NIL       0
56      ABC 2010-02-19     0.0      2.0    NIL       0
57      ABC 2010-02-26     0.0      2.0    NIL       0
58      ABC 2010-03-05     0.0      2.0    NIL       0
59      ABC 2010-03-12     0.0      2.0    NIL       0
60      ABC 2010-03-19     0.0      2.0    NIL       0
61      ABC 2010-03-26     0.0      2.0    NIL       0
1417    ABC 2010-04-02     1.0      0.0    BUY       1
1409    ABC 2010-04-09     1.0      0.0    HOLD      3
62      ABC 2010-04-23     0.0      2.0    SELL      0
63      ABC 2010-05-07     0.0      2.0    NIL       0
64      ABC 2010-05-14     0.0      2.0    NIL       0
65      ABC 2010-05-21     0.0      2.0    NIL       0
66      ABC 2010-05-28     0.0      2.0    NIL       0

Upvotes: 0

Views: 107

Answers (1)

Danail Petrov
Danail Petrov

Reputation: 1875

I think you'd need to keep track of the status and apply your required logic based on that. Here is an example using a custom function to do that. Hope this helps!

 # Initiate the global, default buy flag
 >>> buy_flag =  False
 
 # Custom function to flick the global flag based on `buy_fg` column
 >>> def sell_or_buy(value):
    global buy_flag 
    if value == 1:
        if buy_flag is False:
            buy_flag = True
            return 'BUY'
        if buy_flag is True:
            return 'HOLD'
    if value == 0:
        if buy_flag == 1:
            buy_flag = False
            return 'SELL'
        if buy_flag == 0:
            return 'NIL'

>>> df['action'] = df['buy_fg'].apply(sell_or_buy)

>>> df
    ticker            date  buy_fg  sell_fg action
0       50  ABC 2010-01-01     0.0      2.0    NIL
1       51  ABC 2010-01-08     0.0      2.0    NIL
2       52  ABC 2010-01-15     0.0      2.0    NIL
3       53  ABC 2010-01-22     0.0      2.0    NIL
4     1512  ABC 2010-01-29     1.0      0.0    BUY
5       54  ABC 2010-02-05     0.0      2.0   SELL
6       55  ABC 2010-02-12     0.0      2.0    NIL
7       56  ABC 2010-02-19     0.0      2.0    NIL
8       57  ABC 2010-02-26     0.0      2.0    NIL
9       58  ABC 2010-03-05     0.0      2.0    NIL
10      59  ABC 2010-03-12     0.0      2.0    NIL
11      60  ABC 2010-03-19     0.0      2.0    NIL
12      61  ABC 2010-03-26     0.0      2.0    NIL
13    1417  ABC 2010-04-02     1.0      0.0    BUY
14    1409  ABC 2010-04-09     1.0      0.0   HOLD
15      62  ABC 2010-04-23     0.0      2.0   SELL
16      63  ABC 2010-05-07     0.0      2.0    NIL
17      64  ABC 2010-05-14     0.0      2.0    NIL
18      65  ABC 2010-05-21     0.0      2.0    NIL
19      66  ABC 2010-05-28     0.0      2.0    NIL

EDIT: This is to accommodate your latest requirement. As it gets a bit messy now with the way you've updated the question, I will just modify my answer to add to the above dataframe.

>>> d={'NIL': 0, 'BUY': 1, 'SELL': 2, 'HOLD' : 3}
>>> df['hold_fg'] = df.action.map(d)
>>> df
    ticker            date  buy_fg  sell_fg action  hold_fg
0       50  ABC 2010-01-01     0.0      2.0    NIL        0
1       51  ABC 2010-01-08     0.0      2.0    NIL        0
2       52  ABC 2010-01-15     0.0      2.0    NIL        0
3       53  ABC 2010-01-22     0.0      2.0    NIL        0
4     1512  ABC 2010-01-29     1.0      0.0    BUY        1
5       54  ABC 2010-02-05     0.0      2.0   SELL        2
6       55  ABC 2010-02-12     0.0      2.0    NIL        0
7       56  ABC 2010-02-19     0.0      2.0    NIL        0
8       57  ABC 2010-02-26     0.0      2.0    NIL        0
9       58  ABC 2010-03-05     0.0      2.0    NIL        0
10      59  ABC 2010-03-12     0.0      2.0    NIL        0
11      60  ABC 2010-03-19     0.0      2.0    NIL        0
12      61  ABC 2010-03-26     0.0      2.0    NIL        0
13    1417  ABC 2010-04-02     1.0      0.0    BUY        1
14    1409  ABC 2010-04-09     1.0      0.0   HOLD        3
15      62  ABC 2010-04-23     0.0      2.0   SELL        2
16      63  ABC 2010-05-07     0.0      2.0    NIL        0
17      64  ABC 2010-05-14     0.0      2.0    NIL        0
18      65  ABC 2010-05-21     0.0      2.0    NIL        0
19      66  ABC 2010-05-28     0.0      2.0    NIL        0

Upvotes: 1

Related Questions