简体   繁体   中英

More efficient way of calculating data from pandas dataframe (stock)

I was wondering if there is a more efficient/cleaner way of doing the following. Say I have a dataframe that contains 2 columns, the percentage, (base on previous price) and the action, play/buy (1) or not play/sell (-1). Its basically about stocks.

For simplicity, consider the example df:

Percent    Action
1.25       1
1.20       1
0.50       -1
0.75       1

I would like to generate the following. I only care about the final money amount, I am just showing this table for reference. Say we started with $100 and a state of not playing. Thus we should get the money amount of:

Playing    Percent    Action    Money
No         1.25       1         $100
Yes        1.20       1         $120
Yes        0.50       -1        $60
No         0.75       1         $60
Yes        ...        ...       ...

The amount didnt change in the first row since we weren't playing yet. Since the action is 1, we will play the next one. The percentage went up 20%, thus we get $120. The next action is still a 1, so we'll still be in the next one. The percentage went down to 50% so we end up with $60. Next action is -1, thus we will not play. The percentage went down to 75%, but since we weren't playing, our money stayed the same. And so on.

Currently, I have the code below. It works fine, but just wondering if there is a more efficient way using numpy/pandas functions. Mine basically iterates through each row and calculate the value.

playing = False
money = 10000

for index, row in df.iterrows():
   ## UPDATE MONEY IF PLAYING
   if index > 0 and playing == True:
      money = float(format(money*row['Percent'],'.2f'))

   ## BUY/SELL
   if row['Action'] == 1:
      if playing == False:
         playing = True         ## Buy, playing after this
      elif row['Action'] == -1:
         if playing == True:
            playing = False   ## Sell, not playing after this

You could try this:

# decide whether to play based on action
df['Playing'] = df.Action.shift().eq(1)

# replace Percent for not playing row with 1 and then calculate the cumulative product
df['Money'] = '$' + df.Percent.where(df.Playing, 1).cumprod().mul(100).astype(str)

df
#Percent  Action  Playing    Money
#0  1.25       1    False   $100.0
#1  1.20       1     True   $120.0
#2  0.50      -1     True    $60.0
#3  0.75       1    False    $60.0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM