2017-02-21 6 views
1


Я вернулся к тестированию торговых стратегий, и я хочу видеть прибыль и убытки день ото дня, исходя из результатов стратегии.Как получить скользящую прибыль и убытки в столбце Pandas DataFrame в день?

подход
Я хранение данных о запасах с торговыми сигналами, которые говорят «NoTrade», «Win» и «потеря». NoTrade означает, что сделка не была куплена, Win означает, что сделка была сделана, и это было выгодно, а потеря означает сделку, но она была невыгодной. Я написал цикл, чтобы проверить, есть ли сигнал или нет. если была победа или убыток, то мой баланс счета обновлен, чтобы отразить прибыль или убыток.

DataFrame

  WinLoss ProfitAndLossPofChg AccountBalance 
D 
2010-12-08 NoTrade    0.000000   2000.0 
2010-12-09 NoTrade    0.000000   2000.0 
2010-12-10 NoTrade    0.000000   2000.0 
2010-12-13 NoTrade    0.000000   2000.0 
2010-12-14 NoTrade    0.000000   2000.0 
2010-12-15  Loss   -0.030842   2000.0 
2010-12-16  Win    0.000539   2000.0 
2010-12-17 NoTrade    0.000000   2000.0 
2010-12-20 NoTrade    0.000000   2000.0 
2010-12-21 NoTrade    0.000000   2000.0 
2010-12-22  Win    0.014686   2000.0 
2010-12-23 NoTrade    0.000000   2000.0 
2010-12-27 NoTrade    0.000000   2000.0 
2010-12-28  Loss   -0.006190   2000.0 
2010-12-29 NoTrade    0.000000   2000.0 
2010-12-30 NoTrade    0.000000   2000.0 
2010-12-31 NoTrade    0.000000   2000.0 
2011-01-03  Loss   -0.055686   2000.0 
2011-01-04  Loss   -0.025471   2000.0 
2011-01-05  Loss   -0.051420   2000.0 
2011-01-06  Loss   -0.000299   2000.0 
2011-01-07 NoTrade    0.000000   2000.0 
2011-01-10 NoTrade    0.000000   2000.0 
2011-01-11  Win    0.003719   2000.0 
2011-01-12 NoTrade    0.000000   2000.0 
2011-01-13  Loss   -0.041218   2000.0 
2011-01-14  Win    0.033365   2000.0 
2011-01-18  Win    0.018628   2000.0 
2011-01-19 NoTrade    0.000000   2000.0 
2011-01-20  Loss   -0.020820   2000.0 

Код

def ProfitAndLoss(DataFrame): 

    df = DataFrame 

    for i in df.WinLoss: 

     if i == "NoTrade": 
      df.AccountBalance = df.AccountBalance.shift(-1) 

     elif i == "Win": 
      df.AccountBalance = df.AccountBalance.shift(-1) * df.ProfitAndLossPofChg 

     elif i == "Loss": 
      df.AccountBalance = df.AccountBalance.shift(-1) * df.ProfitAndLossPofChg 

Выход

  WinLoss ProfitAndLossPofChg AccountBalance 
D 
2010-12-08 NoTrade    0.000000    0.0 
2010-12-09 NoTrade    0.000000    0.0 
2010-12-10 NoTrade    0.000000    0.0 
2010-12-13 NoTrade    0.000000    0.0 
2010-12-14 NoTrade    0.000000    0.0 
2010-12-15  Loss   -0.030842   -0.0 
2010-12-16  Win    0.000539    0.0 
2010-12-17 NoTrade    0.000000    0.0 
2010-12-20 NoTrade    0.000000    0.0 
2010-12-21 NoTrade    0.000000    0.0 
2010-12-22  Win    0.014686    0.0 
2010-12-23 NoTrade    0.000000    0.0 
2010-12-27 NoTrade    0.000000    0.0 
2010-12-28  Loss   -0.006190   -0.0 
2010-12-29 NoTrade    0.000000    0.0 
2010-12-30 NoTrade    0.000000    0.0 
2010-12-31 NoTrade    0.000000    0.0 
2011-01-03  Loss   -0.055686   -0.0 
2011-01-04  Loss   -0.025471   -0.0 
2011-01-05  Loss   -0.051420   -0.0 
2011-01-06  Loss   -0.000299   -0.0 
2011-01-07 NoTrade    0.000000    0.0 
2011-01-10 NoTrade    0.000000    0.0 
2011-01-11  Win    0.003719    0.0 
2011-01-12 NoTrade    0.000000    0.0 
2011-01-13  Loss   -0.041218   -0.0 
2011-01-14  Win    0.033365    0.0 
2011-01-18  Win    0.018628    0.0 
2011-01-19 NoTrade    0.000000    0.0 
2011-01-20  Loss   -0.020820   -0.0 

Задача
Как вы можете видеть, баланс моего счета равен нулю; не отображая скользящую прибыль и убытки с балансом стартового счета в размере 2000,00 долларов США. В своей функции я полагал, что если не было торговли, то просто взять баланс предыдущего дня и сделать его сегодняшним балансом, или если это была победа или проигрышная сделка, взятие баланса предыдущих дней и умножение на текущую прибыль или убыток. Я полагал, что это показало бы бегущую сумму прибыли и убытков, но, полагаю, я ошибался. Это длинный способ сказать, что я не знаю.

ответ

1
def ProfitAndLoss(df): 

    df = df.copy() 
    df = df.reset_index() 
    for index,row in df.iterrows(): 
     if index == 0: 
      continue 
     if row['WinLoss'] == "NoTrade": 
      df['AccountBalance'][index] = df['AccountBalance'][index-1] 

     elif row['WinLoss'] in ["Win", "Loss"]: 
      df['AccountBalance'][index] = df['AccountBalance'][index-1] * (1 + df['ProfitAndLossPofChg'][index]) 

    return df 

print(ProfitAndLoss(df).set_index('D')) 

Выход:

  WinLoss ProfitAndLossPofChg AccountBalance 
D 
2010-12-08 NoTrade    0.000000  2000.000000 
2010-12-09 NoTrade    0.000000  2000.000000 
2010-12-10 NoTrade    0.000000  2000.000000 
2010-12-13 NoTrade    0.000000  2000.000000 
2010-12-14 NoTrade    0.000000  2000.000000 
2010-12-15  Loss   -0.030842  1938.316000 
2010-12-16  Win    0.000539  1939.360752 
2010-12-17 NoTrade    0.000000  1939.360752 
2010-12-20 NoTrade    0.000000  1939.360752 
2010-12-21 NoTrade    0.000000  1939.360752 
2010-12-22  Win    0.014686  1967.842204 
2010-12-23 NoTrade    0.000000  1967.842204 
2010-12-27 NoTrade    0.000000  1967.842204 
2010-12-28  Loss   -0.006190  1955.661261 
2010-12-29 NoTrade    0.000000  1955.661261 
2010-12-30 NoTrade    0.000000  1955.661261 
2010-12-31 NoTrade    0.000000  1955.661261 
2011-01-03  Loss   -0.055686  1846.758308 
2011-01-04  Loss   -0.025471  1799.719527 
2011-01-05  Loss   -0.051420  1707.177949 
2011-01-06  Loss   -0.000299  1706.667503 
2011-01-07 NoTrade    0.000000  1706.667503 
2011-01-10 NoTrade    0.000000  1706.667503 
2011-01-11  Win    0.003719  1713.014599 
2011-01-12 NoTrade    0.000000  1713.014599 
2011-01-13  Loss   -0.041218  1642.407564 
2011-01-14  Win    0.033365  1697.206492 
2011-01-18  Win    0.018628  1728.822055 
2011-01-19 NoTrade    0.000000  1728.822055 
2011-01-20  Loss   -0.020820  1692.827979 
+0

Вы код работает, но скорость кажется быть проблемой, но она работает, поэтому я собираюсь пойти с ней – ZacAttack

1

Нет необходимости перебирать рамку данных. Применение shift к серии pd «df.AccountBalance» создает еще одну серию. Попробуйте это:

df['AccountBalance'] += df['AccountBalance'].shift(-1) * df['ProfitAndLossPofChg'] 
+0

Я не читал и не использовать петлю на DataFrame, но я просто не мог понять – ZacAttack

+0

Приму вы ответите, когда она позволяет мне – ZacAttack

+0

Я ваш код работал, но он не дает мне общий итог, т. Е. Если я сделаю 10% при первой сделке, мой баланс на счете должен быть 2200,00, а затем на моей второй сделке я сделаю еще 10%, это должно быть 2420,00. Я просто получаю два 2200 – ZacAttack

Смежные вопросы