Как создать столбец данных на основе условного расчета - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь создать новый столбец, который будет выполнять одну или другую функцию в зависимости от значения в строке в столбце df ['Call / Put']. У меня возникают трудности с выполнением вычислений на основе определенных значений строк, а также определения того, какую функцию выполнять. Ниже приведена последняя функция, которую я пробовал, но, похоже, она не выполняет формулу должным образом. Я пробовал несколько способов, но безрезультатно, но это последний, который я пробовал.

Я пытаюсь создать новый столбец под названием «Черные Шоулз» и выполнить bs_call, если df ['Call / Put'] = = 'Call' в этой строке или выполнить bs_put, если df ['Call / Put'] == 'Put' в этой строке.

for index, value in df.iterrows():
        df['Black Scholes'][index]=np.where((df['Call/Put']=='Call')|(df['Call/Put']==' Put'),bs_call(df['Close'][index],df['Strike Price'][index],df['Days to Expiry'][index],rf,df['Volatility'][index]),bs_put(df['Close'][index],df['Strike Price'][index],df['Days to Expiry'][index],rf,df['Volatility'][index]))

Ниже приведены функции, которые я использую для расчета по с фреймом данных, который содержит 3 строки

def bs_call(S,K,T,r,sigma):
    T=T/365
    d1=(log(S/K)+(r+sigma**2/2)*T)/(sigma*sqrt(T))
    d2= d1-sigma*sqrt(T)
    ans = S*norm.cdf(d1)-K*exp(-r*T)*norm.cdf(d2)
    return ans

def bs_put(S,K,T,r,sigma):
    T=T/365
    d1=(log(S/K)+(r+sigma**2/2)*T)/(sigma*sqrt(T))
    d2= d1-sigma*sqrt(T)
    ans = S*norm.cdf(d1)-K*exp(-r*T)*norm.cdf(d2)
    return K*exp(-r*T)-S+ans

df = [{'Close': 27.3,
  'Company': 'Barrick Gold Corporation (ABX)',
  'Ticker': 'ABX',
  'Yahoo Ticker': 'ABX.TO',
  'Expiry Date': Timestamp('2020-03-01 00:00:00'),
  'Strike Price': 19.5,
  'Call/Put': 'Put',
  'Days to Expiry': 2,
  'Volume': 1,
  'Bid Price': 0.0,
  'Ask Price': 0.11,
  'Open Interest': 24,
  'Implied Volatility': 2.4757,
  'Spread %': 100.0,
  'Volatility': 0.41140252083455864},
 {'Close': 27.3,
  'Company': 'Barrick Gold Corporation (ABX)',
  'Ticker': 'ABX',
  'Yahoo Ticker': 'ABX.TO',
  'Expiry Date': Timestamp('2020-03-01 00:00:00'),
  'Strike Price': 23.0,
  'Call/Put': 'Call',
  'Days to Expiry': 2,
  'Volume': 5,
  'Bid Price': 4.1,
  'Ask Price': 5.9,
  'Open Interest': 5,
  'Implied Volatility': 3.0017,
  'Spread %': 30.508474576271194,
  'Volatility': 0.41140252083455864},
 {'Close': 27.3,
  'Company': 'Barrick Gold Corporation (ABX)',
  'Ticker': 'ABX',
  'Yahoo Ticker': 'ABX.TO',
  'Expiry Date': Timestamp('2020-03-01 00:00:00'),
  'Strike Price': 24.0,
  'Call/Put': 'Put',
  'Days to Expiry': 2,
  'Volume': 5,
  'Bid Price': 0.06,
  'Ask Price': 0.17,
  'Open Interest': 5,
  'Implied Volatility': 1.3371,
  'Spread %': 64.70588235294117,
  'Volatility': 0.41140252083455864}]

1 Ответ

1 голос
/ 30 марта 2020

Я думаю, что вы могли бы go с apply:

df["Black Scholes"] = df.apply(lambda r : bs_call(r) if r["Call/Put"] == "Call" else bs_put(r),axis=1)

Это бы хорошо работало, если у вас есть только два возможных значения для столбца "Call / Put", но если вы планируете иметь больше , вы должны определить функцию, которая делает это:

def foo(row) :
   if row["Call/put"] == "value_1" : 
        return func_1(r)
   elif ...
df["Black Scholes"] = df.apply(foo,axis=1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...