Pinecsript to Python conversion

1.2k Views Asked by At

i'm trying to convert this strategy from pinescript to python but im getting enormous output value when i backtest it, someone can find if there's something wrong? thank tou

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()
1

There are 1 best solutions below

0
On

I'm not sure why you are having problems. I've copied your code and it's running fine. Perhaps your data feed has someting wrong?

The only thing I added in was assuming you wanted to go long AND short. Your current code goes either long to flat, or short to flat. I've added in a close trade before the short/long trades.

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

Here's your code just added to my shell. Have a look and run this. It works of yfinance so will go around any data issues. Let us know if you still have problems.

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()