尝试使用Python编写过滤器功能,但出现了一些错误

时间:2019-02-26 23:40:50

标签: python pandas

最近,我试图编写一个Python程序来过滤并确定交易方向。基本逻辑是,如果该交易的价格等于报价的买入价,则将其指定为's',代表卖出。如果该交易的价格等于报价的卖价,则将其指定为'b',代表购买。如果该交易的价格不等于买价或要价,则将价格与以前的交易一一比较。如果价格高于之前的交易,则将其指定为'b',如果价格小于's'。如果找不到明显的买入或卖出的先前价格,则返回最后一个价格之前的价格以找到它。如果不满意,请返回其他价格。这样做直到找到明确的买或卖。

此外,由于数据集中有多个公司的数据,如果最后一笔交易的价格属于另一家公司,那么我认为这是不可能的,并将其分配为null。我使用20个滞后作为先前的价格,看是否可以找到明确的买入或卖出。如果在20点后仍无法确定交易方向,则我认为这是不可能的,并将其分配为空。

为此,我编写了以下函数。

def bid_ask_direct(a,b,c,d,e):
if a-b == 0:
    return 's'
elif a-c == 0:
    return 'b'
else:
    for i in e:
        for j in np.arange(1,21):
            if d[i] == d[i-j]:
                if a[i] - a[i-j] > 0: 
                    return 'b'
                elif a[i] - a[i-j] < 0:
                    return 's'
                else:
                    pass
            else:
                return None 

df1['Trade Direct'] = bid_ask_direct(df1['Price'],df1['Bid Price'],df1['Ask Price'],df1['#RIC'],df1.index)

运行此函数时,出现以下错误:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

我在该网站上进行了很多搜索,但仍然可以找到任何可以帮助我的答案或问题。

下面是此功能的示例数据。

          #RIC   Price  Volume  Bid Price  Ask Price
3    WTB.L   998.0   300.0      998.0      999.5
6    WTB.L   998.0   900.0      997.0      998.0
9    WTB.L   998.0    45.0      997.0      999.5
14   WTB.L   998.0   400.0      997.0      998.0
17   WTB.L   998.0    18.0      997.0      999.0
30   WTB.L   998.0  1500.0      997.5     1000.0
39   WTB.L   998.5   300.0      995.0     1000.0
59   WTB.L   999.0  1100.0      999.0     1001.0
69   WTB.L   999.5   300.0      999.5     1001.0
70   WTB.L   999.5   300.0      999.5     1001.0
94   WTB.L  1001.0   967.0     1001.0     1002.0
95   WTB.L  1001.0  1800.0     1001.0     1002.0
98   WTB.L  1001.0  1000.0     1001.0     1002.0
100  WTB.L  1001.0   118.0     1001.0     1002.0
103  WTB.L  1002.0  1600.0     1001.0     1002.0
106  WTB.L  1004.0   865.0     1001.0     1004.0
113  WTB.L  1001.0   600.0     1001.0     1004.0
126  WTB.L  1003.0   400.0     1003.0     1005.0
128  WTB.L  1003.0   945.0     1002.0     1003.0
145  WTB.L  1003.0  1200.0     1002.0     1004.0
147  WTB.L  1003.0   200.0     1003.0     1004.0
149  WTB.L  1003.0    25.0     1003.0     1004.0
151  WTB.L  1003.0    13.0     1003.0     1004.0
155  WTB.L  1002.0  1500.0     1001.0     1004.0
156  WTB.L  1002.0  2338.0     1001.0     1004.0
157  WTB.L  1002.0  1200.0     1001.0     1004.0
183  WTB.L  1004.0   300.0     1002.0     1004.0
184  WTB.L  1004.0   480.0     1002.0     1004.0
185  WTB.L  1004.0    86.0     1002.0     1004.0
188  WTB.L  1002.0   280.0     1002.0     1004.0

1 个答案:

答案 0 :(得分:0)

以这种方式对数据使用pandas数据帧总是更好。您不应该使用纯Python。如果我理解您的要求:

我重新创建了您的数据,如下所示:

df = pd.read_clipboard()

df.set_index('index', inplace=True)
df.head()

    #RIC    Price   Volume  Bid_Price   Ask_Price
index                   
3   WTB.L   998.0   300.0   998.0   999.5
6   WTB.L   998.0   900.0   997.0   998.0
9   WTB.L   998.0   45.0    997.0   999.5
14  WTB.L   998.0   400.0   997.0   998.0
17  WTB.L   998.0   18.0    997.0   999.0

插入一列以表示购买/出售/持有:

df.insert(1,'Signal', '')

过滤价格= Bid_Price,并使“信号”等于“卖出”

df.loc[df['Price'] == df['Bid_Price'], ['Signal']] = 'sell'

过滤价格= Ask_Price,并使“信号”等于“购买”

df.loc[df['Price'] == df['Ask_Price'], ['Signal']] = 'buy'

结果

df.head()

    #RIC    Signal  Price   Volume  Bid_Price   Ask_Price
index                       
3   WTB.L   sell    998.0   300.0   998.0   999.5
6   WTB.L   buy     998.0   900.0   997.0   998.0
9   WTB.L   hold    998.0   45.0    997.0   999.5
14  WTB.L   buy     998.0   400.0   997.0   998.0

您表示,如果使用这种方法在交易日中没有明确的买入卖出信号,那么您想将每天的价格与前一个价格进行比较(返回20天),以获得交易信号。

# restrict data to 20 records
df_20 = df.iloc[:20,:].copy()

# make a column with the price difference between this transaction and previous
df_20.loc[:, 'trailing_diff'] = (df_20.loc[:,'Price'] - df.loc[:,'Price'].shift(-1))

# use a mask to filter the dataframe eliminating zero values
mask = df_20['trailing_diff'] != 0
trade_signal = df_20[mask]['trailing_diff'].iloc[0]

最后,使用if条件逻辑选择正确的买入/卖出信号。

if df.iloc[0, :]['Signal'] != 'hold':
    signal = df.iloc[0, :]['Signal']
elif trade_signal > 0: 
    signal = 'buy'
elif trade_signal < 0: 
    signal = 'sell'
else: 
    signal = 'hold'

print('signal')
sell

将其完全运行在具有多个证券的更大数据框上,请参见下文。我没有运行此程序,因为我没有更多数据,希望没有错误。

def make_decision(df):
    df.loc[df['Price'] == df['Bid_Price'], ['Signal']] = 'sell'
    df.loc[df['Price'] == df['Ask_Price'], ['Signal']] = 'buy'

    # restrict data to 20 records
    df_20 = df.iloc[:20,:].copy()

    # make a column with the price difference between this transaction and previous
    df_20.loc[:, 'trailing_diff'] = (df_20.loc[:,'Price'] - df.loc[:,'Price'].shift(-1))

    # use a mask to filter the dataframe eliminating zero values
    mask = df_20['trailing_diff'] != 0
    trade_signal = df_20[mask]['trailing_diff'].iloc[0]

    if df.iloc[0, :]['Signal'] != 'hold':
        signal = df.iloc[0, :]['Signal']
    elif trade_signal > 0: 
        signal = 'buy'
    elif trade_signal < 0: 
        signal = 'sell'
    else: 
        signal = 'hold'
    return signal


for sec in df['#RIC'].unique():
    df_sec = df[df['#RIC'] == sec]
    print('Security', sec, '    ', make_decision(df_sec))