我有一个交易系统,有几个买入和卖出信号。系统总是长或短。可以发生相同方向的多个信号,但只有给定方向(长或短)的第一个实例有效(一旦长一个长信号不被采用,因为系统已经拥有该股票)。
我正在使用Python和Pandas来解决这个问题。我排队购买并按日期在数据框中的一列中出售:
df['BuysandSells'] = [+1,+1,-1,+1,etc]
然后我根据第一列使用ffill创建第二列。
df['Column2'] = df['BuysandSells'].ffill()
然后我通过移动Column2来创建第三列:
df['Column3'] = df['Column2'].shift()
最后,我使用np.where将Column2与Column3进行比较,以找到买卖信号的新实例:
df['ValidNewSignal'] = np.where(df['Column2']<>df['Column3'],df['Column2'],np.nan)
这可以有效地创建精确购买和销售列表,省略冗余。然后我索引有效信号。一切正常。
但是,现在我想确定止损是否会改善我的结果。我的目标是,如果我的职位被阻止,退出&#39; (也就是当前价格高于/低于我预设的止损价值)。为了确定我的止损,我将我的入场点乘以固定金额(ex $ 100条目* 80%= 80.然后我使用.ffill()将这个金额填入列中。这就是问题所在。如上所述,如果我是没有停止在同一方向的辅助信号是无效的。但是,如果我确实被阻止后续信号(在相同的方向但在另一个方向的信号之前)变得有效。但是我写这个的方式创建了一个悖论。
我认为问题是我需要遍历行并创建一个回溯到前一行的新列。我已经在线查找了一些文档,并且已经看过iterows并且已经探索了列表推导,但是它们都没有深入支持/似乎解决了这个问题。我愿意使用循环或其他方法。
更多信息: csv文件看起来像这样:
Row, Date,BuysandSells,Close
1, 8/19/15,+1,100
2, 8/20/15,+1,101
3, 8/21/15,+1,100
4, 8/24/15,-1,99
5, 8/25/15,NaN,99
6, 8/26/15,-1,98
7, 8/27/15,+1,100
我会使用以下内容将其读入数据框:
df = pd.read_csv('C:\filename.csv')
首先,我想根据上面的评论确定唯一记录(即消除冗余 - 参见上面的代码)。
从那里我的目标是在每个新条目上设置止损。所以说我的规则是停止是条目的10%然后代码会读取:
stoplevel = 90%
df['Stop'] = np.where(df['ValidNewSignal'] == 1,df['Close']*stoplevel,np.nan)
这是事情变得有点混乱的地方。我用ffill填充了这个:
df['trailingstop'] = df['stop'].ffill()
df['stoppedout'] = np.where(df['Close']<=df['trailingstop'],-1,np.nan)
回顾上面的数据文件,系统会在第1行的100处变长(即买入股票)。止损将变为90.在这种情况下,第2行和第3行的后续买入将被忽略,因为止损不是& #39;击中。但是,例如,如果第2行中的关闭为75,则表示系统已停止运行,第3行中的买入将变为有效,从而导致设置新的止损。
最大的问题是我无法弄清楚如何确定是否接受后续信号,因为我不知道自己是否被阻止了。根据我的停止水平(90%,95%等),我可能会或可能不会被阻止,因此后续信号(以及相关的新止损)将取决于此。因此,思考迭代是必要的。我已经尝试了很多轮班,但却无法完成任何工作。
理想的产出将显示所有买入和卖出的条件是止损水平。
增加清晰度:
有两个主要问题:
如何在止损位置后动态重置止损金额。
如何在同一天处理信号和停止的一天
采取以下csv:
Row,Date,BuysandSells,Close,New Long (if yes 1 else 0),Stop(90%ofnewlong),trailingstop
1,8/19/15,+1,100,1,90,90
2,8/19/15,+1,101,0,NaN,90
3,8/19/15,+1,102,0,NaN,90
4,8/19/15,+1,101,0,NaN,90
5,8/19/15,+1,102,0,NaN,90
6,8/19/15,+1,101,0,NaN,90
7,8/19/15,+1,102,0,NaN,90
8,8/19/15,+1,101,0,NaN,90
9,8/19/15,+1,100,0,NaN,90
10,8/19/15,+1,101,0,NaN,90
11,8/19/15,+1,100,0,NaN,90
12,8/19/15,+1,101,0,NaN,90
13,8/19/15,+1,100,0,NaN,90
在这里,我们看到我们在第1行获得了新的买入,我们以90秒的价格进入100。接下来的每一天我们都会得到一个购买信号(buysandsells专栏),但由于我们已经很久了,我们会忽略这些。我们还看到新的停止级别被忽略(没有新条目)和原始停止跟踪(使用ffill())。这是为了说明基线。
接下来让我们假设一个与csv略有不同的停止:
Row,Date,BuysandSells,Close,New Long (if yes 1 else 0),Stop(90%ofnewlong),trailingstop,stopped (1=yes)
1,8/1/15,+1,100,1,90,90,NaN
2,8/2/15,+1,95,0,NaN,90,NaN
3,8/3/15,+1,91,0,NaN,90,NaN
4,8/4/15,0,89,0,NaN,90,1
5,8/5/15,0,90,0,NaN,NaN,NaN
6,8/8/15,+1,90,1,81,81,NaN
7,8/9/15,+1,102,0,NaN,81,NaN
8,8/10/15,+1,101,0,NaN,81,NaN
9,8/11/15,+1,100,0,NaN,81,NaN
10,8/12/15,+1,101,0,NaN,81,NaN
11,8/15/15,+1,100,0,NaN,81,NaN
12,8/16/15,+1,101,0,NaN,81,NaN
13,8/17/15,+1,100,0,NaN,81,NaN
在第1天,如上所述,我们将持续时间为100,止损为90.在第4天,我们看到价格跌至原始止损水平90以下,因此我们被阻止了。相应的追踪止损在下一行中不再存在(不确定如何在pandas中执行此操作)。然后在2015年8月8日的第6行,我们得到另一个购买信号,因为现在没有位置。这次价格是90,所以止损是81.这里我们忽略后续买入信号,直到我们再次停止(这没有发生)。这里固有的问题是需要基本上逐行确定停止,并且仅在前一个位置被停止时才采取后续购买。熊猫的能力(尽我所知)不允许这样做。如果我ffill()第一个实例,那么当我到达停止/新位置时,停止将保持原始值。如果我重置停止每个新信号并使用ffill()我实际上并没有跟踪正确的停止。
下一期(作为评论者提到)是当你在同一天停止和发出信号时会发生什么。从逻辑上讲这听起来很简单(如果没有位置接收信号,如果一个位置停止)但我知道如何使用Pandas的方式这不起作用,我无法弄清楚如何忽略停止后的停止最初停止(它们通常像买卖信号一样串起来)。鉴于所有这一切,似乎需要一些迭代方法吗?