0

我正在尝试将此策略从 pinescript 转换为 python,但是当我对其进行回测时,我得到了巨大的输出值,有人可以发现是否有问题?谢谢你

class WaveTrendStrategy(bt.Strategy):
    
    def __init__(self) :
        n1 = 21
        n2 = 14
        obLevel1 = 60
        obLevel1 = 60
        obLevel2 = 53
        osLevel1 = -60
        osLevel2 = -53
        hlc3 = (self.data.high+self.data.low+self.data.close)/3
        ap = hlc3 
        esa = bt.ind.EMA(ap,period=n1)
        d = bt.ind.EMA(abs(ap - esa), period=n1)
        ci = (ap - esa) / (0.015 * d)
        tci = bt.ind.EMA(ci, period=n2)
        wt1 = tci
        wt2 = bt.ind.SMA(wt1,period=4)
        self.longCondition  = bt.ind.CrossUp(wt2,osLevel2)
        self.shortCondition = bt.ind.CrossDown(wt2,obLevel2)
        
        
    def next(self):
        if self.longCondition:
                self.buy()
        
        elif self.shortCondition:
            self.sell()
4

1 回答 1

0

我不确定你为什么会遇到问题。我已经复制了你的代码,它运行良好。也许您的数据提要有问题?

我唯一添加的是假设你想做多和做空。您当前的代码要么长到平,要么短到平。我在空头/多头交易之前添加了平仓交易。

if self.getposition().size != 0:
                self.close()

这是您刚刚添加到我的外壳中的代码。看看并运行它。它适用于 yfinance,因此可以解决任何数据问题。如果您仍有问题,请告诉我们。

import datetime
import backtrader as bt

class WaveTrendStrategy(bt.Strategy):

    def log(self, txt, dt=None):
        """ Logging function fot this strategy"""
        dt = dt or self.data.datetime[0]
        if isinstance(dt, float):
            dt = bt.num2date(dt)
        print("%s, %s" % (dt.date(), txt))

    def print_signal(self):
        self.log(
            f"o {self.datas[0].open[0]:7.2f} "
            f"h {self.datas[0].high[0]:7.2f} "
            f"l {self.datas[0].low[0]:7.2f} "
            f"c {self.datas[0].close[0]:7.2f} "
            f"v {self.datas[0].volume[0]:7.0f} "
            # f"rsi {self.rsi[0]:5.0f}"
        )

    def notify_order(self, order):
        """ Triggered upon changes to orders. """

        # Suppress notification if it is just a submitted order.
        if order.status == order.Submitted:
            return

        # Print out the date, security name, order number and status.
        dt, dn = self.datetime.date(), order.data._name
        type = "Buy" if order.isbuy() else "Sell"
        self.log(
            f"{order.data._name:<6} Order: {order.ref:3d}\tType: {type:<5}\tStatus"
            f" {order.getstatusname():<8} \t"
            f"Size: {order.created.size:9.4f} Price: {order.created.price:9.4f} "
            f"Position: {self.getposition(order.data).size}"
        )
        if order.status == order.Margin:
            return

        # Check if an order has been completed
        if order.status in [order.Completed]:
            self.log(
                f"{order.data._name:<6} {('BUY' if order.isbuy() else 'SELL'):<5} "
                # f"EXECUTED for: {dn} "
                f"Price: {order.executed.price:6.2f} "
                f"Cost: {order.executed.value:6.2f} "
                f"Comm: {order.executed.comm:4.2f} "
                f"Size: {order.created.size:9.4f} "
            )

    def notify_trade(self, trade):
        """Provides notification of closed trades."""
        if trade.isclosed:
            self.log(
                "{} Closed: PnL Gross {}, Net {},".format(
                    trade.data._name,
                    round(trade.pnl, 2),
                    round(trade.pnlcomm, 1),
                )
            )

    def __init__(self):
        n1 = 21
        n2 = 14
        obLevel1 = 60
        obLevel1 = 60
        obLevel2 = 53
        osLevel1 = -60
        osLevel2 = -53
        hlc3 = (self.data.high + self.data.low + self.data.close) / 3
        ap = hlc3
        esa = bt.ind.EMA(ap, period=n1)
        d = bt.ind.EMA(abs(ap - esa), period=n1)
        ci = (ap - esa) / (0.015 * d)
        tci = bt.ind.EMA(ci, period=n2)
        wt1 = tci
        wt2 = bt.ind.SMA(wt1, period=4)
        self.longCondition = bt.ind.CrossUp(wt2, osLevel2)
        self.shortCondition = bt.ind.CrossDown(wt2, obLevel2)

    def next(self):
        # Print OHLCV
        self.print_signal()

        if self.longCondition:
            if self.getposition().size != 0:
                self.close()
            self.buy()

        elif self.shortCondition:
            if self.getposition().size != 0:
                self.close()
            self.sell()



if __name__ == "__main__":

    cerebro = bt.Cerebro()

    data = bt.feeds.YahooFinanceData(
        dataname="FB",
        timeframe=bt.TimeFrame.Days,
        fromdate=datetime.datetime(2018, 1, 1),
        todate=datetime.datetime(2021, 4, 1),
        reverse=False,
    )

    cerebro.adddata(data, name="FB")

    cerebro.addstrategy(WaveTrendStrategy)

    # Execute
    cerebro.run()
    print(f"Final Value: {cerebro.broker.getvalue():5.2f}")

    cerebro.plot()

于 2021-05-14T13:31:24.420 回答