我正在尝试对我的交易进行投资组合分析,并尝试计算调整后的成本基础价格。我几乎尝试了一切,但似乎没有任何效果。我能够计算调整后的数量,但无法获得调整后的购买价格有人可以帮忙吗?
这是交易日志原始数据示例
import pandas as pd
import numpy as np
raw_data = {'Date': ['04-23-2020', '05-05-2020', '05-05-2020', '05-11-2020', '05-11-2020',
'05-12-2020', '05-12-2020', '05-27-2020', '06-03-2020', '06-03-2020',
'06-03-2020', '06-03-2020', '06-03-2020'],
'Type': ['Buy', 'Buy', 'Buy', 'Buy', 'Buy', 'Buy', 'Buy',
'Sell', 'Sell', 'Sell', 'Buy', 'Sell', 'Sell'],
'Symbol': ['TSE:AC', 'TSE:AC', 'TSE:HEXO', 'TSE:BPY.UN', 'TSE:BPY.UN',
'TSE:BPY.UN', 'TSE:AC', 'TSE:BPY.UN', 'TSE:AC', 'TSE:BPY.UN',
'TSE:AC', 'TSE:BPY.UN', 'TSE:HEXO'],
'Quantity': [75, 100, 1450, 200, 50, 80, 150, 100, 125, 100, 100, 50, 1450],
'Amount per unit': [18.04, 17.29, 0.73, 13.04, 13.06, 12.65, 15.9, 15.01,
18.05, 14.75, 15.8, 14.7, 1.07],
'Turnover': [1353, 1729, 1058.5, 2608, 653, 1012, 2385, 1501, 2256.25, 1475, 1580, 735, 1551.5],
}
df = pd.DataFrame (raw_data, columns = ['Date','Type','Symbol','Quantity','Amount per unit', 'Turnover']).sort_values(['Date','Symbol']).reset_index(drop = True)
我能够毫无问题地获得调整后的数量,但我无法获得正确的调整后的每单位价格。这里的条件是,如果我出售股票,我的调整后的每单位价格不应改变,并保持与购买该股票时的最后调整价格相同。
#to calculate adjusted quantity. this works as expected
df['Adjusted Quantity'] = df.apply(lambda x: ((x.Type == "Buy") - (x.Type == "Sell")) * x['Quantity'], axis = 1)
df['Adjusted Quantity'] = df.groupby('Symbol')['Adjusted Quantity'].cumsum()
#section where I am having problem. Works good until I reach the row where sell was made
df['Adjusted Price Per Unit'] = df.apply(lambda x: ((x.Type == "Buy") - (x.Type == "Sell")) * x['Turnover'], axis = 1)
df['Adjusted Price Per Unit'] = df.groupby('Symbol')['Adjusted Price Per Unit'].cumsum().div(df['Adjusted Quantity'])
运行此代码将产生以下结果
例如:,索引 7 处的行的调整后价格应为 12.948(与索引 6 处的行相同),而不是 12.052。另外,最后一行调整后的价格应该是 0.73(与索引 2 的行相同),因为我买卖相同数量的股票。
例 2:在指数 6 处,我以 12.65 的价格买入 80 股 BPY,这使我的平均价格降至 12.94,总共 330 股(250+80)。现在,我以 15.01(指数 7)卖出 100 股。我的代码将调整后的成本调整为 12.05。我需要调整后的成本为 12.94,而不是 12.05。简单来说,如果交易类型是卖出,则忽略调整价格。使用该特定股票的最后购买类型交易中的最后调整价格。
我的代码的最后两行不正确。您能帮我正确计算调整后的每单位价格吗?谢谢:)
如果您没有像您评论的那样计算销售的调整价格,那么您可以将销售行处理为 NA 并用同一股票的前一个值填充它。作为代码中的确认,您在开始计算“调整数量”时是否不需要考虑相同的股票?
df.sort_values(['Symbol','Date','Type'], ascending=[True, True, True], inplace=True)
# your code
df['Adjusted Quantity'] = df.apply(lambda x: ((x.Type == "Buy") - (x.Type == "Sell")) * x['Quantity'], axis = 1)
df['Adjusted Quantity'] = df.groupby('Symbol')['Adjusted Quantity'].cumsum()
df['Adjusted Price Per Unit'] = df.apply(lambda x: ((x.Type == "Buy") - (x.Type == "Sell")) * x['Turnover'], axis = 1)
df['Adjusted Price Per Unit'] = df.groupby('Symbol')['Adjusted Price Per Unit'].cumsum().div(df['Adjusted Quantity'])
df.loc[df['Type'] == 'Sell',['Adjusted Price Per Unit']] = np.NaN
df.fillna(method='ffill', inplace=True)
| | Date | Type | Symbol | Quantity | Amount per unit | Turnover | Adjusted Quantity | Adjusted Price Per Unit |
|---:|:-----------|:-------|:-----------|-----------:|------------------:|-----------:|--------------------:|--------------------------:|
| 0 | 04-23-2020 | Buy | TSE:AC | 75 | 18.04 | 1353 | 75 | 18.04 |
| 1 | 05-05-2020 | Buy | TSE:AC | 100 | 17.29 | 1729 | 175 | 17.6114 |
| 5 | 05-12-2020 | Buy | TSE:AC | 150 | 15.9 | 2385 | 325 | 16.8215 |
| 9 | 06-03-2020 | Buy | TSE:AC | 100 | 15.8 | 1580 | 425 | 16.5812 |
| 8 | 06-03-2020 | Sell | TSE:AC | 125 | 18.05 | 2256.25 | 300 | 16.5812 |
| 3 | 05-11-2020 | Buy | TSE:BPY.UN | 200 | 13.04 | 2608 | 200 | 13.04 |
| 4 | 05-11-2020 | Buy | TSE:BPY.UN | 50 | 13.06 | 653 | 250 | 13.044 |
| 6 | 05-12-2020 | Buy | TSE:BPY.UN | 80 | 12.65 | 1012 | 330 | 12.9485 |
| 7 | 05-27-2020 | Sell | TSE:BPY.UN | 100 | 15.01 | 1501 | 230 | 12.9485 |
| 10 | 06-03-2020 | Sell | TSE:BPY.UN | 100 | 14.75 | 1475 | 130 | 12.9485 |
| 11 | 06-03-2020 | Sell | TSE:BPY.UN | 50 | 14.7 | 735 | 80 | 12.9485 |
| 2 | 05-05-2020 | Buy | TSE:HEXO | 1450 | 0.73 | 1058.5 | 1450 | 0.73 |
| 12 | 06-03-2020 | Sell | TSE:HEXO | 1450 | 1.07 | 1551.5 | 0 | 0.73 |
@r-beginners 的上述答案没有正确处理数量为 0 后的新购买,正如 @guialmachado 和 @Rene Chan 所观察到的。因此,这是我的代码,它使用 Rene Chan 的示例正确计算了它。
import pandas as pd
import numpy as np
raw_data = {'Date': ['04-23-2020', '05-05-2020', '05-05-2020', '05-11-2020', '05-11-2020',
'05-12-2020', '05-12-2020', '05-27-2020', '06-03-2020', '06-03-2020',
'06-03-2020', '06-03-2020', '06-03-2020', '06-05-2020'],
'Type': ['Buy', 'Buy', 'Buy', 'Buy', 'Buy', 'Buy', 'Buy',
'Sell', 'Sell', 'Sell', 'Buy', 'Sell', 'Sell', 'Buy'],
'Symbol': ['TSE:AC', 'TSE:AC', 'TSE:HEXO', 'TSE:BPY.UN', 'TSE:BPY.UN',
'TSE:BPY.UN', 'TSE:AC', 'TSE:BPY.UN', 'TSE:AC', 'TSE:BPY.UN',
'TSE:AC', 'TSE:BPY.UN', 'TSE:HEXO', 'TSE:HEXO'],
'Quantity': [75, 100, 1450, 200, 50, 80, 150, 100, 125, 100, 100, 50, 1450, 3000],
'Amount per unit': [18.04, 17.29, 0.73, 13.04, 13.06, 12.65, 15.9, 15.01,
18.05, 14.75, 15.8, 14.7, 1.07, 2.50],
'Turnover': [1353, 1729, 1058.5, 2608, 653, 1012, 2385, 1501, 2256.25, 1475, 1580, 735, 1551.5, 7500],
}
df = pd.DataFrame (raw_data, columns = ['Date','Type','Symbol','Quantity','Amount per unit', 'Turnover']).sort_values(['Date','Symbol']).reset_index(drop = True)
df.sort_values(['Symbol','Date','Type'], ascending=[True, True, True], inplace=True)
df['Adjusted Quantity'] = df.apply(lambda x: ((x.Type == "Buy") - (x.Type == "Sell")) * x['Quantity'], axis = 1)
df['Adjusted Quantity'] = df.groupby('Symbol')['Adjusted Quantity'].cumsum()
def calculate_adjusted_price_per_unit(group):
group['Adjusted Turnover'] = group.apply(lambda x: ((x.Type == "Buy") - (x.Type == "Sell")) * x['Turnover'], axis = 1)
group['Adjusted Price Per Unit'] = 0
last_entry_price = 0
current_turnover = 0
for index, row in group.iterrows():
current_turnover += row['Adjusted Turnover']
if row['Type'] == 'Buy':
group.at[index, 'Adjusted Price Per Unit'] = current_turnover / row['Adjusted Quantity']
if row['Type'] == 'Sell':
group.at[index, 'Adjusted Price Per Unit'] = last_entry_price
if row['Adjusted Quantity'] == 0:
current_turnover = 0
group.at[index, 'Adjusted Price Per Unit'] = last_entry_price
last_entry_price = group.at[index, 'Adjusted Price Per Unit']
return group
df = df.groupby('Symbol').apply(calculate_adjusted_price_per_unit)
df.drop(columns=['Adjusted Turnover'], inplace=True)
正确输出
Date Type Symbol Quantity Amount per unit Turnover Adjusted Quantity Adjusted Price Per Unit
0 04-23-2020 Buy TSE:AC 75 18.04 1353.00 75 18.040000
1 05-05-2020 Buy TSE:AC 100 17.29 1729.00 175 17.611429
5 05-12-2020 Buy TSE:AC 150 15.90 2385.00 325 16.821538
9 06-03-2020 Buy TSE:AC 100 15.80 1580.00 425 16.581176
8 06-03-2020 Sell TSE:AC 125 18.05 2256.25 300 16.581176
3 05-11-2020 Buy TSE:BPY.UN 200 13.04 2608.00 200 13.040000
4 05-11-2020 Buy TSE:BPY.UN 50 13.06 653.00 250 13.044000
6 05-12-2020 Buy TSE:BPY.UN 80 12.65 1012.00 330 12.948485
7 05-27-2020 Sell TSE:BPY.UN 100 15.01 1501.00 230 12.948485
10 06-03-2020 Sell TSE:BPY.UN 100 14.75 1475.00 130 12.948485
11 06-03-2020 Sell TSE:BPY.UN 50 14.70 735.00 80 12.948485
2 05-05-2020 Buy TSE:HEXO 1450 0.73 1058.50 1450 0.730000
12 06-03-2020 Sell TSE:HEXO 1450 1.07 1551.50 0 0.730000
13 06-05-2020 Buy TSE:HEXO 3000 2.50 7500.00 3000 2.500000