2013-10-20 2 views
1

저는 모델링을 시도하는 간단한 주식 포트폴리오 시뮬레이션을 가지고 있지만, 일부 시도에도 불구하고이를 벡터화하는 방법을 찾을 수 없습니다. 어쩌면 불가능할 수도 있지만, 거기에있는 사람 중에 어떤 생각이 있는지 알고 싶었습니다.팬더에서이 절차를 벡터화하는 방법이 있습니까?

내 요령은 특정 날짜의 공유가 2 일전의 계정 가격과 주가의 함수라는 것입니다. 그러나 하루의 계정 값은 전날의 계정 값과 오늘의 주식 및 주식 가격 수의 함수입니다. 따라서 공유와 계좌 가치 사이에는 앞뒤로 벡터화하는 방법을 생각할 수 없기 때문에 아래의 유일한 해결책은 for 루프입니다.

미리 감사드립니다.

import pandas as pd 
import numpy as np 
stats = pd.DataFrame(index = range(0,10)) 

stats['Acct Val'] = 0.0 
stats['Shares'] = 0.0 
stats['Stock Px'] = pd.Series([23,25,24,26,22,23,25,25,26,24],index=stats.index) 
# Wgt is the percentage of the account value that should be invested in the stock on a given day 
stats['Wgt'] = pd.Series([0.5,0.5,0.5,0.5,0.3,0.4,0.4,0.2,0.2,0.0,],index=stats.index) 
stats['Daily PNL'] = 0.0 
# Start the account value at $10,000.00 
stats.ix[0:1, 'Acct Val'] = 10000.0 
stats.ix[0:1, 'Wgt'] = 0 
for date_loc in range(2, len(stats.index)): 
    # Keep shares the same unless 'wgt' column changes 
    if stats.at[date_loc,'Wgt'] != stats.at[date_loc-1,'Wgt']: 
     # Rebalanced shares are based on the acct value and stock price two days before 
     stats.at[date_loc,'Shares'] = stats.at[date_loc-2,'Acct Val'] * stats.at[date_loc,'Wgt']/stats.at[date_loc-2,'Stock Px'] 
    else: 
     stats.at[date_loc,'Shares'] = stats.at[date_loc-1,'Shares'] 
    # Daily PNL is simply the shares owned on a day times the change in stock price from the previous day to the next 
    stats.at[date_loc,'Daily PNL'] = stats.at[date_loc,'Shares'] * (stats.at[date_loc,'Stock Px'] - stats.at[date_loc-1,'Stock Px']) 
    # Acct value is yesterday's acct value plus today's PNL 
    stats.at[date_loc,'Acct Val'] = stats.at[date_loc-1,'Acct Val'] + stats.at[date_loc,'Daily PNL'] 


In [44]: stats 
Out[44]: 
     Acct Val  Shares Stock Px Wgt Daily PNL 
0 10000.000000 0.000000  23 0.0 0.000000 
1 10000.000000 0.000000  25 0.0 0.000000 
2 9782.608696 217.391304  24 0.5 -217.391304 
3 10217.391304 217.391304  26 0.5 434.782609 
4 9728.260870 122.282609  22 0.3 -489.130435 
5 9885.451505 157.190635  23 0.4 157.190635 
6 10199.832776 157.190635  25 0.4 314.381271 
7 10199.832776 85.960448  25 0.2 0.000000 
8 10285.793224 85.960448  26 0.2 85.960448 
9 10285.793224 0.000000  24 0.0 -0.000000 

In [45]: 

편집 : 오후 11시 1분 2013년 10월 19일 :

내가 foobarbecue의 코드를 사용하여 시도했지만 내가 거기에 가져올 수 없습니다 :

import pandas as pd 
import numpy as np 
stats = pd.DataFrame(index = range(0,10)) 
stats['Acct Val'] = 10000.0 
stats['Shares'] = 0.0 
stats['Stock Px'] = pd.Series([23,25,24,26,22,23,25,25,26,24],index=stats.index) 
# Wgt is the percentage of the account value that should be invested in the stock on a given day 
stats['Wgt'] = pd.Series([0.5,0.5,0.5,0.5,0.3,0.4,0.4,0.2,0.2,0.0,],index=stats.index) 
stats['Daily PNL'] = 0.0 
# Start the account value at $10,000.00 
#stats.ix[0:1, 'Acct Val'] = 10000.0 
stats.ix[0:1, 'Wgt'] = 0 

def function1(df_row): 
    #[stuff you want to do when Wgt changed] 
    df_row['Shares'] = df_row['Acct Val'] * df_row['Wgt2ahead']/df_row['Stock Px'] 
    return df_row 

def function2(df_row): 
    #[stuff you want to do when Wgt did not change] 
    df_row['Shares'] = df_row['SharesPrevious'] 
    return df_row 

#Find where the Wgt column changes 
stats['WgtChanged']=stats.Wgt.diff() <> 0 # changed ">" to "<>" 
#Using boolean indexing, choose all rows where Wgt changed and apply a function 
stats['Wgt2ahead'] = stats['Wgt'].shift(-2) 
stats = stats.apply(lambda df_row: function1(df_row) if df_row['WgtChanged'] == True else df_row, axis=1) 
stats['Shares'] = stats['Shares'].shift(2) 
#Likewise, for rows where Wgt did not change 
stats['SharesPrevious'] = stats['Shares'].shift(1) 
stats = stats.apply(lambda df_row: function2(df_row) if df_row['WgtChanged'] == False else df_row, axis=1) 

답변

0
def function1(df_row): 
    [stuff you want to do when Wgt changed] 

def function2(df_row): 
    [stuff you want to do when Wgt did not change] 

#Find where the Wgt column changes 
stats['WgtChanged']=stats.Wgt.diff() > 0 
#Using boolean indexing, choose all rows where Wgt changed and apply a function 
stats[stats['WgtChanged']].apply(function1, axis=1) 
#Likewise, for rows where Wgt did not change 
stats[~stats['WgtChanged']].apply(function2, axis=1) 
+0

감사합니다,하지만 난 노력하여 메서드를 호출하고 함수 1에서 오늘날의 PNL을 어제의 ACT 값에 더함으로써 오늘날의 ACT 값을 계산해야한다는 사실에 매료되었습니다. function1은 한 번에 하나의 행으로 작동하기 때문에 그렇게하는 방법을 모르겠습니다. 어쩌면 내가 뭔가를 놓친 것 같아. 코드 사용에 대한 나의 시도는 위의 질문 편집에 게시됩니다. – geronimo

+1

오, 죄송합니다. 질문에 대한 나의 독서는 불완전했다. 나머지 문제는 셀의 출력이 다른 열과 다른 행에 의존한다는 것입니다. 나는 이것을 다단계 프로세스 (축 = 0으로 적용한 다음 다시 축 = 1로 적용)로 분해하여 수행 할 수 있다고 생각합니다. 중간 열 또는 2 개가 필요할 수 있습니다. 지금 당장은 알아낼 시간이 없지만, 여전히 문제가 있고 아무도 알아 내지 못하면 다시 돌아올 것입니다. – foobarbecue

관련 문제