寻找数组中第一个小于某值的连续组合

今天在实习中遇到了这样一个问题,对我来说有点复杂,连起标题都不知道该怎么起,拿来记录一下。

问题是这样的,有一个DataFrame,以日期为index,value值是一个有正有负的Series。

data = {

    'Date': ['2023-07-01', '2023-07-02', '2023-07-03', '2023-07-04', '2023-08-02', '2023-08-03', '2023-08-04'],

    'Values': [0.03, -0.02, -0.03, 0.01, 0.0, 0.01, 0.03]

}

df = pd.DataFrame(data)

我是做量化的,value值代表了根据我的策略买股票每日的收益率。为此我的目标是设置一个每月止损率,比如当我亏了0.04的时候,我就需要在当月出来,下个月再进入。所以我希望得到的是将每个月第一个小于止损率(-0.04)的组合,将组合中前面所有的值改为0,最后一个值直接改为止损率-0.04,将组合后当月数据也改为0。这样我预计得到的数组应该是 [0.03, 0, -0.04, 0, 0, 0.01, 0.03]。

话不多说,只要自己能看懂就可以哈哈,我的代码是这样的:

def findStop(df, col, stop_value=-0.0025):
    new_df = pd.DataFrame()

    for _, group_df in df.groupby(df.index.month): # 按照月份将dataframe分开
    
        dp, idx = 1000, 0                          # dp记录最大亏损,初设为一个很大的值
        group_df = group_df.reset_index(drop=True)
        mem = [0, 0]                               # mem记录亏损开始位置和结束位置
        for i in range(1, len(group_df)+1):
            if dp >= 0:
                idx = i-1;

            dp = min(dp, 0) + group_df.iat[i-1, 0]
            if dp <= stop_value:                   # 当最大亏损超过止损率,跳出循环
                mem[0] = idx
                mem[1] = i-1
                break

        if mem[0] + mem[1] != 0:                   # 如果当月没有亏超过亏损率的,不改变数值
            # 将亏损其他位置设为0
            group_df.loc[mem[0]:mem[1], col] = 0
            # 将亏损最后一个值置为stopvalue
            group_df.loc[mem[1], col] = stop_value
            # 将亏损后当月其他值设为0
            group_df.loc[mem[1]+1: len(group_df), col] = 0

        new_df = pd.concat([new_df, group_df])     # 将所有月份汇集到新的dataframe中
    return new_df[col].tolist()

结果如预期一样,得到:

 当然,如果不是dataframe也很好做,只要稍微改一改就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值