For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Convert close to json so it can be sent through POST request



  • I am trying to make my first indicator using backtrader. The main issue is that close vector of size period should be send via POST request and than do some calculation on returned object and. in the end, return value to line. The first problem is that self.datas[0].close is not json serializable. Here is my try:

    class Radf(bt.Indicator):
        lines = ('radf',)
        params = dict(period=600, adf_lag=2)
        
        def __init__(self):
            self.close_slice = self.data0.close.get(size=self.p.period)  # Here I want to take last 'period' close prices
            
        def next(self):
            # here I want to prepare data for requests POST request
            x = {
                'x': self.close_slice,
                'adf_lag': self.p.adf_lag
            }
            # x = json.dumps(x)  # ERROR HERE: TypeError: Object of type array is not JSON serializable
    
            # SHOULD WORK AFTER
            # res = requests.post("http://46.101.219.193/plumber_test/radf", data=x)
            # res_json = res.json()
            # bsadf = res_json['bsadf']
            # bsadf = pd.DataFrame.from_dict(bsadf)
            # bsadf_last = bsadf.iloc[-1]
            # self.lines.radf = bsadf_last
            # self.lines.radf = self.close_slice
    

    I am not sure what is the type of the datas0.close



  • I made some progress:

    # Define indicator
    class Radf(bt.Indicator):
        lines = ('radf',)
        params = dict(period=200, adf_lag=2)
        
        def __init__(self):
            self.close_slice = self.data0.close.get(size=self.p.period, ago=-1)
            
        def next(self):
            x = {
                'x': self.close_slice.tolist(),
                'adf_lag': self.p.adf_lag
            }
            x = json.dumps(x)
            res = requests.post("http://46.101.219.193/plumber_test/radf", data=x)
            res_json = res.json()
            bsadf = res_json['bsadf']
            bsadf = pd.DataFrame.from_dict(bsadf)
            bsadf_last = bsadf.iloc[-1]
            print(bsadf_last[0])
            self.lines.radf = bsadf_last[0]
            # self.lines.radf = self.close_slice
    

    but now I get an error because numpy array is not callable. And returned values fro request are always the same. It seems like self.close_slice returns always the same slice. Why aggingning the flat to lines doesnt work, why it says it is not callable?



  • I will try to describe my goal more clearly. I want to take last 600 or less close prices (close line has length 600) and send this close price via POST request:

    res = requests.post("http://46.101.219.193/plumber_test/radf", data=x)
    

    where x contains x (600 last close prices) and adf_lag (some integer, say 2). You can check my prevous code.

    Than I want to extract bsadf element of json, which is an array. From that array I extract last element, and than this last element, this float I want to add to indicator line.

    If I execute code above, I have 2 problems:

    1. I get an error: TypeError: 'numpy.float64' object is not callable (I tried it to convert it to list, but that doesnt help)
    2. I always get the same number back, which means I always send same close lines to server, not 600 last?


  • I think I have found the solution. I had to use addminperiod function to set minimum period for my Indicator and I had to calculate close slice in next() method and not the __init__ method. I had to assign float value to [0] of my line and the line itself. Here is the code:

    Define indicator

    class Radf(bt.Indicator):
    lines = ('radf',)
    params = dict(period=600, adf_lag=2)

    def __init__(self):
        self.addminperiod(self.params.period)
    
    def next(self):
        self.close_slice = self.data0.close.get(size=self.p.period)
        x = {
            'x': self.close_slice.tolist(),
            'adf_lag': self.p.adf_lag
        }
        x = json.dumps(x)
        res = requests.post("http://46.101.219.193/plumber_test/radf", data=x)
        res_json = res.json()
        bsadf = res_json['bsadf']
        bsadf = pd.DataFrame.from_dict(bsadf)
        bsadf_last = bsadf.iloc[-1]
        # print(f'{bsadf_last}')
        self.lines.radf[0] = bsadf_last.item()

Log in to reply
 

});