backtest.py里的holt模型预测结果转化买入信号

使用backtest.py遇到一些困难,现在已经训练出一个模型,但是要怎么把预测结果转化为买入卖出信号,对init和next函数不熟悉

def EXP(values, n):
    """
    Return simple moving average of `values`, at
    each step taking into account `n` previous values.
    """
    data_train1=values.Close[-n:]
    hs_1 = Holt(data_train1).fit()

    return  hs_1.forecast(1)[0]
def HIS(values,n):
    return pd.series(values).rolling(n).mean()

from backtesting import Strategy
from backtesting.lib import crossover


class SmaCross(Strategy):
    # Define the two MA lags as *class variables*
    # for later optimization
    
    
    def init(self):
        self.n1=10
        self.n2=1
        self.exp_predict = self.I(EXP, self.data.Close,self.n1)
        self.history_data = self.I(HIS, self.data.Close,self.n2)

    
    def next(self):
        

        if self.exp_predict[0]>self.history_data:
            self.position.close()
            self.buy()


        elif self.exp_predict[0]<self.history_data:
            self.position.close()
            self.sell()

TechWhizKid参考GPT回答:

  • 你的在next()方法中,你应该使用self.exp_predict[-1]和self.history_data[-1]来访问最新的预测和历史数据,而不是self.exp_predict[0]和self.history_data。

以下是修复后的代码:

def EXP(values, n):
    data_train1=values[-n:]
    hs_1 = Holt(data_train1).fit()
    return  hs_1.forecast(1)[0]

def HIS(values,n):
    return pd.Series(values).rolling(n).mean()

from backtesting import Strategy
from backtesting.lib import crossover

class SmaCross(Strategy):
    def init(self):
        self.n1=10
        self.n2=1
        self.exp_predict = self.I(EXP, self.data.Close,self.n1)
        self.history_data = self.I(HIS, self.data.Close,self.n2)

    def next(self):
        if self.exp_predict[-1]>self.history_data[-1]:
            self.position.close()
            self.buy()
        elif self.exp_predict[-1]<self.history_data[-1]:
            self.position.close()
            self.sell()


修改后的代码中,next()方法中使用的是最新的exp_predict和history_data数据。self.I()方法返回的是一个序列,可以通过用[-1]来获取最新的值。

基于new bing部分指引作答:
根据你提供的代码,我看到你使用了Holt模型进行预测,并希望将预测结果转化为买入和卖出信号。在你的代码中,你已经定义了一个EXP函数,它使用Holt模型对给定的数据进行预测。在init函数中,你将这个预测结果赋值给了self.exp_predict。此外,你还定义了一个HIS函数用于计算历史数据的移动平均。

在next函数中,你可以根据self.exp_predict和self.history_data的比较结果来确定买入和卖出信号。根据你的代码逻辑,如果self.exp_predict[0]大于self.history_data,则发出买入信号;如果self.exp_predict[0]小于self.history_data,则发出卖出信号。

然而,需要注意的是,在初始化阶段,你只计算了一次预测值和历史数据的移动平均,然后在每个next步骤中使用相同的值进行比较。这意味着你的策略只会在初始化时发出一次信号,并且在接下来的每个步骤中保持不变。如果你希望在每个步骤中都重新计算预测值和移动平均值,你需要将这些计算放在next函数中。

以下是修改后的代码示例:

def EXP(values, n):
    """
    Return simple moving average of `values`, at
    each step taking into account `n` previous values.
    """
    data_train1 = values.Close[-n:]
    hs_1 = Holt(data_train1).fit()
    return hs_1.forecast(1)[0]

def HIS(values, n):
    return pd.Series(values).rolling(n).mean()

from backtesting import Strategy
from backtesting.lib import crossover

class SmaCross(Strategy):
    def init(self):
        self.n1 = 10
        self.n2 = 1

    def next(self):
        exp_predict = self.I(EXP, self.data.Close, self.n1)
        history_data = self.I(HIS, self.data.Close, self.n2)

        if exp_predict[0] > history_data:
            self.position.close()
            self.buy()

        elif exp_predict[0] < history_data:
            self.position.close()
            self.sell()

在这个修改后的代码中,我将计算预测值和历史数据移动平均值的代码从init函数中移动到了next函数中,这样每个步骤都会重新计算这些值,并根据新的结果发出买入和卖出信号。

这只是一个示例代码,可能还需要根据你的具体情况进行进一步的调整和修改。此外,确保在代码中导入必要的库(如pandas和Holt)以及正确设置回测环境。

来自GPT的回答:


根据你提供的代码,你正在使用backtest.py库进行回测,并且已经训练出了一个Holt模型来预测结果。你想要将预测结果转化为买入卖出信号,并在next函数中实现这个逻辑。

根据你的代码,self.exp_predict是通过Holt模型预测的结果,self.history_data是通过简单移动平均计算的历史数据。

在next函数中,你可以使用if语句来判断买入和卖出的条件,然后执行相应的操作。以下是一个示例代码,展示如何根据预测结果生成买入信号:

python
Copy code
def next(self):
    if self.exp_predict[0] > self.history_data:
        if self.position.is_empty():
            self.buy()
    elif self.exp_predict[0] < self.history_data:
        if self.position.is_long():
            self.sell()
在上述代码中,如果预测结果大于历史数据,且当前持仓为空,则执行买入操作。如果预测结果小于历史数据,且当前持仓为多头(即已买入),则执行卖出操作。

你可以根据你的具体需求和策略逻辑进行修改和优化。同时,你还可以添加其他的买入卖出条件,例如设置止损止盈条件、加入技术指标等等,以更好地实现你的交易策略。

请注意,这只是一个示例代码,你需要将其与你的完整策略代码结合使用,并根据你的需求进行适当的调整。另外,确保你对backtest.py的Strategy类和相关函数有一定的了解,以便正确地使用库中的功能。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    我很抱歉,作为一个AI语言模型,我不具备编写代码的能力。但我可以根据您提供的问题,给出一些可能的解决方案和步骤供您参考。

    首先,针对问题的具体性质,我假设您已经了解Holt模型的基本原理以及如何在backtest.py中进行训练和预测,所以以下重点介绍如何将Holt模型的预测结果转化为买入和卖出信号。

    步骤如下:

    1. 在backtest.py中的init函数中,初始化一些辅助变量和指标,例如初始资金、持仓情况、买卖点的阈值、停损设置等。

    2. 在next函数中,根据模型预测结果,结合辅助变量和指标,进行买卖信号的判断。例如:

    def next(self):
        # 使用Holt模型进行预测
        pred = self.model.predict()
        # 获取当前时刻的实际价格
        price = self.data.get_latest_price()
        # 以一定阈值为界限来判断买卖点
        if pred > price * (1 + self.threshold):
            # 如果预测价格高于阈值,且当前未持仓,则进行买入操作
            if not self.position:
                self.buy()
        elif pred < price * (1 - self.threshold):
            # 如果预测价格低于阈值,且当前持仓,则进行卖出操作
            if self.position:
                self.sell()
        # 如果价格符合停损条件,则进行卖出操作
        if price < self.stoploss:
            if self.position:
                self.sell()
    
    1. 在buy和sell函数中,实现买入和卖出的操作。例如:
    def buy(self):
        # 计算买入数量
        size = self.capital * self.risk_factor / (self.data.get_latest_price() * (1 + self.slippage))
        # 更新持仓情况和可用资金
        self.position = size
        self.cash -= size * self.data.get_latest_price() * (1 + self.slippage)
    
    1. 在backtest.py的main函数中,设置回测的起始日期、终止日期、数据源等参数,并运行回测。例如:
    if __name__ == '__main__':
        # 设置回测参数
        start_date = datetime.datetime(2020, 1, 1)
        end_date = datetime.datetime(2021, 1, 1)
        data_source = 'yahoo'
        # 初始化回测对象并运行
        backtest = Backtest(strategy=HoltStrategy, start=start_date, end=end_date, data_source=data_source)
        backtest.run()
        # 显示回测结果
        backtest.plot()
    

    请注意,以上代码片段只是示例,具体实现方式和细节取决于您的模型和数据特点,需要根据实际情况进行调整和优化。

    最后,如果您还有其他问题和疑问,可以进一步参考backtest.py文档和其他相关资料,或者请教您的同行和专家。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

向量回测工具pybacktest的使用
可以借鉴下
https://blog.csdn.net/turui/article/details/127523051

根据你提供的代码,你已经定义了一个继承自backtesting库中Strategy类的SmaCross类。在init函数中,你初始化了两个移动平均线的参数n1和n2,并使用self.I方法计算了exp_predict和history_data。

在next函数中,你可以根据exp_predict和history_data的值来生成买卖信号。根据你的代码逻辑,如果exp_predict的值大于history_data的值,则执行买入操作;如果exp_predict的值小于history_data的值,则执行卖出操作。

在next函数中,你已经正确地使用了self.position.close()来平掉之前的持仓,然后根据条件执行买入或卖出操作。

请确保你已经正确导入了必要的库(如backtesting和pandas),并且数据已经正确加载到self.data中。

另外,你还可以根据需要添加其他的条件来改进你的策略,比如加入止损和止盈条件等。希望这能帮助到你,祝你成功运行你的策略!

init方法在回测开始时被调用,用于初始化策略。在该方法中,通过调用self.I方法计算了两个移动平均线,其中self.n1表示第一个MA的滞后值,self.n2表示第二个MA的滞后值。self.exp_predict表示第一个MA的值,self.history_data表示第二个MA的值。

next方法在每个交易日更新时被调用,用于执行交易决策。在该方法中,首先判断第一个MA的值是否大于第二个MA的值。如果大于,则关闭当前持有的头寸,并执行买入操作;如果小于,则关闭当前持有的头寸,并执行卖出操作。

def get_signal(prediction):
    if prediction > threshold:
        return 'buy'
    else:
        return 'sell'

# 在init函数中设置阈值
def init(model, data, threshold):
    model.threshold = threshold
    ...

# 在next函数中获取预测结果,并调用get_signal函数转换为信号
def next(model, data):
    prediction = model.predict(data)
    signal = get_signal(prediction)
    ...

init函数: 在策略启动时执行一次,用于初始化一些参数和变量。这里初始化了两个MA的窗口大小n1和n2,以及分别调用EXP和HIS函数计算两条移动平均线。init函数在策略启动时计算两条MA。
next函数: 在每一步执行,用于生成买入卖出信号。这里是当快速MA(EXPpredict)上穿慢速MA(history_data)时发出买入信号,下穿时发出卖出信号。
next函数在每步检查快MA和慢MA的相互关系。