有没有办法在np.where上获得多个结果?

时间:2019-06-16 08:04:32

标签: python portfolio back-testing

因此,我决定最近学习python以便对产品组合进行回测,而我偶然发现了时间优化问题。

我编写的函数可以正常工作,但是要花很多时间才能计算出来。我读到这一定是由于不同的循环造成的。

因此,我想知道是否有一种优化此代码的方法。

在多个条件下的第一个条件下,我尝试使用np.where,但它给了我一个错误

编辑:
This is the error

data['cash'] = np.where((data['Position'] == 1) & (data['signal']==1), (data['positions']=data['cash'].iloc[row-1]/data['Close'].iloc[row]*0.9)&(data['cash'].iloc[row] =data['positions'].iloc[row] *data['Close'].iloc[row]), 0)

必要进口

import pandas as pd
import numpy as np

这是一种简单的平均分频策略

def smasig (data, fast_days,slow_days, threshold):
    data['FMA'] = data['Close'].rolling(center=False,window=fast_days, min_periods=fast_days).mean()
    data['SMA'] = data['Close'].rolling(center=False,window=slow_days, min_periods=slow_days).mean()

    data['FMA-SMA'] = data['FMA'] - data['SMA']
    Threshold = threshold
    data['Position']=0
    data['Position'] = np.where(data['FMA']>data['SMA'],1.0,0.0)

    data['signal']=data['Position'].diff()

此功能正常运行,但我想对其进行优化

def backtest(data, init):
    data['cash'] =0.0
    data['positions']=0
    initial = init

    for row in range(len(data)):


        if row == 1:
            data['cash']= initial
            row+=1
        if (data['Position'].iloc[row] == 1) and (data['signal'].iloc[row]==1):
            data['positions'].iloc[row]=data['cash'].iloc[row-1]/data['Close'].iloc[row]
            data['cash'].iloc[row] =data['positions'].iloc[row] *data['Close'].iloc[row]

        elif (data['Position'].iloc[row] == 1) and (data['signal'].iloc[row]==0):
            data['positions'].iloc[row] = data['positions'].iloc[row-1]
            data['cash'].iloc[row] =data['positions'].iloc[row] *data['Close'].iloc[row]
        elif (data['Position'].iloc[row] == 0) and (data['signal'].iloc[row]==-1):
            data['positions'].iloc[row] = 0
            data['cash'].iloc[row] = data['cash'].iloc[row-1]

        elif (data['Position'].iloc[row] == 0) and (data['signal'].iloc[row]==0):
            data['positions'].iloc[row] = 0
            data['cash'].iloc[row] = data['cash'].iloc[row-1]


    (data['Close'] / data['Close'].iloc[1]).plot()
    (data['cash']/initial).plot()

这是执行力

GSPC =pd.read_csv(r"C:\Users\****\^GSPC.csv",index_col = "Date",
                  parse_dates=True, na_values=['nan'])
smasig(GSPC, 7,28,0)
backtest(GSPC,1000)
print(GSPC[['Position','signal', 'cash']].tail(10))

This would be the output

我希望得到的结果是相同的结果,但是速度更快。有办法吗?

提前感谢您的时间,如果不清楚,请告诉我。

您可以在Yahoo下载每日价格数据,选择开始日期为2014年5月15日,结束日期为2019年5月15日

更新: 这是我想要的代码类型,但是此代码没有预期的结果

Expected results Results obtained

def backtest (data, init):
    data['cash'] =init
    data['positions']=0
    initial = init

    data['cash'] = np.where(
        (data['Position'] == 1) & (data['signal']==1),(
        data['positions']==data['cash'].shift(1)/data['Close'])&(
        data['cash'] ==data['positions'] *data['Close']),
        np.where((data['Position'] == 1) & (data['signal']==0),
        (data['positions'] == data['positions'].shift(1))&
         (data['cash'] ==data['positions'] *data['Close']), 
        (data['positions'] == 0)& (data['cash'] == data['cash'].shift(1))))


    (data['Close'] / data['Close'].iloc[1]).plot()
    (data['cash']/initial).plot()    

0 个答案:

没有答案