Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Cash, value, size, target orders, HELP T_T

    General Code/Help
    2
    4
    95
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Y
      Youssef 0 last edited by

      Hello everyone, the post is long but the questions very simple!

      In trying to understand what cash, portfolio value, data value and position size were, I've cooked up a simple strategy : buy at this date, sale at this date.
      The problem I don't understand at all what's happening.

      The way I understand it, correct me If I am wrong:

      -Cash: is the money I have to buy shares or contracts or whatever.
      -Portfolio value: is the cash plus the value of the assets I've bought or that I am shorting, in this regard portfolio value can be smaller than cash amount
      -Data value: is the value of the specific asset I am trading when I only have one asset, it can be negative if I am shorting the asset
      -Position : Am I involved with the market or not ? Am I buying or selling or whatever .
      -Position size : the number of shares, cryptocoins, contracts I am trading.

      The strategy :

      import backtrader as bt
      from datetime import datetime
      
      class shortStrat(bt.Strategy): 
          # Moving average parameters
          params = (('pfast',20),('pslow',50),)
      
      
      
          def __init__(self):
              self.dataclose = self.datas[0].close
              self.datahigh = self.datas[0].high
              self.datalow = self.datas[0].low
              # Order variable will contain ongoing order details/status
              self.order = None
      
      
          def log(self, txt, dt=None):
              dt = dt or self.datas[0].datetime.date(0)
              print(f'{dt.isoformat()} {txt}') 
      
          def notify_order(self, order):
              if order.status in [order.Submitted, order.Accepted]:
                  # An active Buy/Sell order has been submitted/accepted - Nothing to do
                  return
      
              # Check if an order has been completed
              # Attention: broker could reject order if not enough cash
              if order.status in [order.Completed]:
                  if order.isbuy():
                      self.log(f'BUY EXECUTED, {order.executed.price:.2f}')
                  elif order.issell():
                      self.log(f'SELL EXECUTED, {order.executed.price:.2f}')
                  self.bar_executed = len(self) #the bar at which the order is completd I guess
      
              elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                  self.log('Order Canceled/Margin/Rejected')
      
              # Reset orders
              self.order = None
      
          def next(self):
              if self.order:
                  return
              
              print('posistion : {}'.format(self.position.size))
              print('portvalue : {}'.format(self.broker.get_value()))
              print('cash : {}'.format(self.broker.get_cash()))
              print('dataval : {}'.format(self.broker.get_value([self.data])))
      
              # Check if we are in the market
              if not self.position:
                  # We are not in the market, look for a signal to OPEN trades
                  if self.datas[0].datetime.date()==datetime(2018,1,1).date() : 
                      self.order = self.order_target_percent(target=1)  
              # we are in the market
              elif self.datas[0].datetime.date()==datetime(2018,1,10).date() :
                  self.order = self.order_target_percent(target=-1)  
      
              elif self.datas[0].datetime.date()==datetime(2018,1,1).date() : 
                  self.order = self.order_target_percent(target=1)  
      
      
      

      The bot:

      from strategies.crossOver import MAcrossover
      import backtrader as bt
      import datetime
      import numpy as np
      from strategies.strat import barycentreStrat
      import csv
      from strategies.ShortStrat import shortStrat
      import pandas as pd
      dateOne="1 Jan, 2017"
      dateTwo="1 Jun, 2021"
      symbol="BNBUSDT"
      interval="1d"
      
      
      
      
      
      cerebro = bt.Cerebro(stdstats=True,optreturn=False,maxcpus=1)#optreturn=False
      data = bt.feeds.GenericCSVData(
          timeframe=bt.TimeFrame.Days,
          compression=1,
          dataname='data\crypto\ShortData.csv',
          nullvalue=0.0,
          dtformat=('%m/%d/%Y'), 
          datetime=0,
          open=1,
          high=2,
          low=3,
          close=4,
          time=-1,
          volume=-1,
          openinterest=-1 
          
      
      )
      
      dayData=cerebro.adddata(data)
       
      cerebro.addstrategy(shortStrat)  
       
      
      
      
      if __name__ == '__main__':
        
          cerebro.broker.set_cash(90000)
          start_portfolio_value = cerebro.broker.getvalue()
          game=cerebro.run()
          end_portfolio_value = cerebro.broker.getvalue()
          pnl = end_portfolio_value - start_portfolio_value
          print(f'Starting Portfolio Value: {start_portfolio_value:2f}')
          print(f'Final Portfolio Value: {end_portfolio_value:2f}')
          print(f'PnL: {pnl:.2f}')
          cerebro.plot(style="candlestick", volume=False)
      
      exit()
      

      the log :

      posistion : 0
      portvalue : 90000.0
      cash : 90000.0     
      dataval : 0.0      
      posistion : 0      
      portvalue : 90000.0
      cash : 90000.0     
      dataval : 0.0      
      posistion : 0      
      portvalue : 90000.0
      cash : 90000.0     
      dataval : 0.0      
      posistion : 0      
      portvalue : 90000.0
      cash : 90000.0     
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      2018-01-02 BUY EXECUTED, 100.00
      posistion : 473
      portvalue : 90000.0
      cash : 42700.0
      dataval : 47300.0
      posistion : 473
      portvalue : 142030.0
      cash : 42700.0
      dataval : 99330.0
      posistion : 473
      portvalue : 146760.0
      cash : 42700.0
      dataval : 104060.0
      posistion : 473
      portvalue : 151490.0
      cash : 42700.0
      dataval : 108790.0
      posistion : 473
      portvalue : 156220.0
      cash : 42700.0
      dataval : 113520.0
      posistion : 473
      portvalue : 160950.0
      cash : 42700.0
      dataval : 118250.0
      posistion : 473
      portvalue : 165680.0
      cash : 42700.0
      dataval : 122980.0
      posistion : 473
      portvalue : 170410.0
      cash : 42700.0
      dataval : 127710.0
      posistion : 473
      portvalue : 175140.0
      cash : 42700.0
      dataval : 132440.0
      2018-01-11 SELL EXECUTED, 190.00
      posistion : -625
      portvalue : 76320.0
      cash : 251320.0
      dataval : -175000.0
      posistion : -625
      portvalue : 82570.0
      cash : 251320.0
      dataval : -168750.0
      posistion : -625
      portvalue : 88820.0
      cash : 251320.0
      dataval : -162500.0
      posistion : -625
      portvalue : 95070.0
      cash : 251320.0
      dataval : -156250.0
      posistion : -625
      portvalue : 101320.0
      cash : 251320.0
      dataval : -150000.0
      posistion : -625
      portvalue : 107570.0
      cash : 251320.0
      dataval : -143750.0
      posistion : -625
      portvalue : 113820.0
      cash : 251320.0
      dataval : -137500.0
      posistion : -625
      portvalue : 120070.0
      cash : 251320.0
      dataval : -131250.0
      posistion : -625
      portvalue : 126320.0
      cash : 251320.0
      dataval : -125000.0
      posistion : -625
      portvalue : 132570.0
      cash : 251320.0
      dataval : -118750.0
      posistion : -625
      portvalue : 132570.0
      cash : 251320.0
      dataval : -118750.0
      2018-01-02 BUY EXECUTED, 110.00
      posistion : 697
      portvalue : 245300.0
      cash : 105900.0
      dataval : 139400.0
      posistion : 697
      portvalue : 252270.0
      cash : 105900.0
      dataval : 146370.0
      posistion : 697
      portvalue : 259240.0
      cash : 105900.0
      dataval : 153340.0
      posistion : 697
      portvalue : 266210.0
      cash : 105900.0
      dataval : 160310.0
      posistion : 697
      portvalue : 273180.0
      cash : 105900.0
      dataval : 167280.0
      posistion : 697
      portvalue : 280150.0
      cash : 105900.0
      dataval : 174250.0
      posistion : 697
      portvalue : 287120.0
      cash : 105900.0
      dataval : 181220.0
      posistion : 697
      portvalue : 294090.0
      cash : 105900.0
      dataval : 188190.0
      posistion : 697
      portvalue : 301060.0
      cash : 105900.0
      dataval : 195160.0
      2018-01-11 SELL EXECUTED, 190.00
      posistion : -1075
      portvalue : 141580.0
      cash : 442580.0
      dataval : -301000.0
      posistion : -1075
      portvalue : 152330.0
      cash : 442580.0
      dataval : -290250.0
      posistion : -1075
      portvalue : 163080.0
      cash : 442580.0
      dataval : -279500.0
      posistion : -1075
      portvalue : 173830.0
      cash : 442580.0
      dataval : -268750.0
      posistion : -1075
      portvalue : 184580.0
      cash : 442580.0
      dataval : -258000.0
      posistion : -1075
      portvalue : 195330.0
      cash : 442580.0
      dataval : -247250.0
      posistion : -1075
      portvalue : 206080.0
      cash : 442580.0
      dataval : -236500.0
      posistion : -1075
      portvalue : 216830.0
      cash : 442580.0
      dataval : -225750.0
      posistion : -1075
      portvalue : 227580.0
      cash : 442580.0
      dataval : -215000.0
      posistion : -1075
      portvalue : 238330.0
      cash : 442580.0
      dataval : -204250.0
      Starting Portfolio Value: 90000.000000
      Final Portfolio Value: 238330.000000
      PnL: 148330.00
      

      the test data (notice the dates are bogus and repeat themeselves):

      1/2/2018,110,210,100,200
      1/3/2018,120,220,110,210
      1/4/2018,130,230,120,220
      1/5/2018,140,240,130,230
      1/6/2018,150,250,140,240
      1/7/2018,160,260,150,250
      1/8/2018,170,270,160,260
      1/9/2018,180,280,170,270
      1/10/2018,190,290,180,280
      1/11/2018,190,290,180,280
      1/12/2018,180,280,170,270
      1/13/2018,170,270,160,260
      1/14/2018,160,260,150,250
      1/15/2018,150,250,140,240
      1/16/2018,140,240,130,230
      1/17/2018,130,230,120,220
      1/18/2018,120,220,110,210
      1/19/2018,110,210,100,200
      1/20/2018,100,200,90,190
      1/1/2018,100,200,90,190
      1/2/2018,100,300,0,100
      1/3/2018,120,220,110,210
      1/4/2018,130,230,120,220
      1/5/2018,140,240,130,230
      1/6/2018,150,250,140,240
      1/7/2018,160,260,150,250
      1/8/2018,170,270,160,260
      1/9/2018,180,280,170,270
      1/10/2018,190,290,180,280
      1/11/2018,190,290,180,280
      1/12/2018,180,280,170,270
      1/13/2018,170,270,160,260
      1/14/2018,160,260,150,250
      1/15/2018,150,250,140,240
      1/16/2018,140,240,130,230
      1/17/2018,130,230,120,220
      1/18/2018,120,220,110,210
      1/19/2018,110,210,100,200
      1/20/2018,100,200,90,190
      1/1/2018,100,200,90,190
      1/2/2018,110,210,100,200
      1/3/2018,120,220,110,210
      1/4/2018,130,230,120,220
      1/5/2018,140,240,130,230
      1/6/2018,150,250,140,240
      1/7/2018,160,260,150,250
      1/8/2018,170,270,160,260
      1/9/2018,180,280,170,270
      1/10/2018,190,290,180,280
      1/11/2018,190,290,180,280
      1/12/2018,180,280,170,270
      1/13/2018,170,270,160,260
      1/14/2018,160,260,150,250
      1/15/2018,150,250,140,240
      1/16/2018,140,240,130,230
      1/17/2018,130,230,120,220
      1/18/2018,120,220,110,210
      1/19/2018,110,210,100,200
      1/20/2018,100,200,90,190
      

      I understand nothing :
      if we focus on the first buy order :

          # Check if we are in the market
              if not self.position:
                  # We are not in the market, look for a signal to OPEN trades
                  if self.datas[0].datetime.date()==datetime(2018,1,1).date() : 
                      self.order = self.order_target_percent(target=1)  
      

      the log :

      posistion : 0
      portvalue : 90000.0
      cash : 90000.0
      dataval : 0.0
      2018-01-02 BUY EXECUTED, 100.00
      posistion : 473
      portvalue : 90000.0
      cash : 42700.0
      dataval : 47300.0
      

      why is it buying only 473 SHARES and not using all my cash when I specified 1 in the target percent order ?

      next the second order :

      here, I am trying to reverse my position, obviously doing a bad job...

              # we are in the market
              elif self.datas[0].datetime.date()==datetime(2018,1,10).date() :
                  self.order = self.order_target_percent(target=-1)  
      
      posistion : 473
      portvalue : 175140.0
      cash : 42700.0
      dataval : 132440.0
      2018-01-11 SELL EXECUTED, 190.00
      posistion : -625
      portvalue : 76320.0
      cash : 251320.0
      dataval : -175000.0
      

      What I understand is that before the sell, the size is 473, this is valued to 132440 which is approximately 0.75 * portvalue, so since I want my position to become -1, cerebro does something like -1/0.75*473 =630 to compute the new position. Once calculated it sells my 423 shares at the close price of the current bar ( since I did not use a limit order ?) which is 280 and not 190 as specified by order.executed.price ??? and it shorts approximately 630 SHARES, the best it can which gives a -625 size???
      What is this 251320 cash value ?? why do I have so much cash after closing my position ? shouldn't i be 132440+42700 ?

      As you understood, I am a newbie trader/ programmer, but I really tried reading the docs..

      Please help me !!!

      dev590t 2 Replies Last reply Reply Quote 0
      • dev590t
        dev590t @Youssef 0 last edited by

        @youssef-0 I have a similar problem. The cash become very big, and I don't unerstand why.
        I add this notification into my strategy

            def notify_trade(self, trade):
                self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f, size %.2f, price %.2f, value %.2f' %
                         (trade.pnl, trade.pnlcomm, trade.size, trade.price, trade.value))
        
            def notify_cashvalue(self,cash, value):
                self.log('cash %.2f, portfolio %.2f' %
                         (cash, value))
        
            def order_log(self,order):
                return ('EXECUTED ref :%.2f, Price: %.2f, Value: %.2f, Comm %.2f, pnl: %.2f, size: %.2f' %
                    (order.ref,
                     order.executed.price,
                     order.executed.value,
                     order.executed.comm,
                     order.executed.pnl,
                     order.executed.size
                     ))
        
            def notify_order(self, order):
                if order.status in [order.Submitted, order.Accepted]:
                    # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                    return
        
                # Check if an order has been completed
                # Attention: broker could reject order if not enough cash
                if order.status in [order.Completed]:
                    if order.isbuy():
                        self.log('BUY' + self.order_log(order))
                        self.buyprice = order.executed.price
                        self.buycomm = order.executed.comm
                    else:  # Sell
                        self.log('SELL' + self.order_log(order))
                    self.bar_executed = len(self)
        
                elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                    self.log('Order Canceled/Margin/Rejected')
        
                # Write down: no pending order
                self.order = None
        
        
        2021-08-13 cash 1676.61, portfolio 30263.15
        2021-08-16 BUYEXECUTED ref :5.00, Price: 114.90, Value: 114.90, Comm 0.00, pnl: 0.00, size: 1.00
        2021-08-16 BUYEXECUTED ref :6.00, Price: 22.87, Value: 22.87, Comm 0.00, pnl: 0.00, size: 1.00
        2021-08-16 BUYEXECUTED ref :7.00, Price: 114.90, Value: 114.90, Comm 0.00, pnl: 0.00, size: 1.00
        2021-08-16 BUYEXECUTED ref :8.00, Price: 22.87, Value: 22.87, Comm 0.00, pnl: 0.00, size: 1.00
        2021-08-16 BUYEXECUTED ref :9.00, Price: 114.90, Value: 114.90, Comm 0.00, pnl: 0.00, size: 1.00
        2021-08-16 BUYEXECUTED ref :10.00, Price: 114.90, Value: 114.90, Comm 0.00, pnl: 0.00, size: 1.00
        2021-08-16 SELLEXECUTED ref :11.00, Price: 22.87, Value: 22.44, Comm 0.00, pnl: 0.43, size: -1.00
        2021-08-16 BUYEXECUTED ref :12.00, Price: 114.90, Value: 229.80, Comm 0.00, pnl: 0.00, size: 2.00
        2021-08-16 SELLEXECUTED ref :13.00, Price: 22.87, Value: 67.32, Comm 0.00, pnl: 1.29, size: -3.00
        2021-08-16 BUYEXECUTED ref :14.00, Price: 114.90, Value: 229.80, Comm 0.00, pnl: 0.00, size: 2.00
        2021-08-16 SELLEXECUTED ref :15.00, Price: 22.87, Value: 67.32, Comm 0.00, pnl: 1.29, size: -3.00
        2021-08-16 cash 871.76, portfolio 30256.88
        

        I can observe some relation between the numbres:

        tmp@ val sell_1 = 7662.03 * 2 + 5683.00 + 3 * -7659.00  // from the Value of SELLEXECUTED above
        sell_1: Double = -1969.9400000000023
        
        tmp@ val sell_2 = 7662.03 * 2 + 5683.00 + 3 * 7659.00 // from the Value of SELLEXECUTED above
        sell_2: Double = 43984.06
        
        tmp@ val cash_init = 4837.12 
        cash_init: Double = 4837.12
        
        tmp@ val cash_final = 50746.72 
        cash_final: Double = 50746.72
        
        tmp@ val change = cash_final - cash_init 
        change: Double = 45909.6
        

        size = 45 // from size of trade above
        sell_2 - sell_1
        = (7662.03 * 2 + 5683.00 + 3 * 7659.00) - (7662.03 * 2 + 5683.00 + 3 * -7659.00)
        = 3 * 7659 - 3 * -7659
        = 3 * 7659 + (3 * 7659)
        = 6 * 7659
        = 45954
        = change + size

        But I can't understand the logic

        dev590t 1 Reply Last reply Reply Quote 0
        • dev590t
          dev590t @dev590t last edited by

          @dev590t I have use the wrong output in my message above. This is the right ouput:

          2021-08-23 cash 4837.12, portfolio 30015.36
          ..
          2021-08-24 SELLEXECUTED ref :75.00, Price: 22.20, Value: 7662.03, Comm 0.00, pnl: -25.23, size: -344.00
          2021-08-24 SELLEXECUTED ref :77.00, Price: 22.20, Value: 7662.03, Comm 0.00, pnl: -25.23, size: -344.00
          2021-08-24 SELLEXECUTED ref :79.00, Price: 22.20, Value: 5683.00, Comm 0.00, pnl: -22.00, size: -345.00
          2021-08-24 SELLEXECUTED ref :81.00, Price: 22.20, Value: -7659.00, Comm 0.00, pnl: 0.00, size: -345.00
          2021-08-24 SELLEXECUTED ref :83.00, Price: 22.20, Value: -7659.00, Comm 0.00, pnl: 0.00, size: -345.00
          2021-08-24 SELLEXECUTED ref :85.00, Price: 22.20, Value: -7659.00, Comm 0.00, pnl: 0.00, size: -345.00
          2021-08-24 OPERATION PROFIT, GROSS -105.16, NET -105.16, size 0.00, price 22.27, value 0.00
          2021-08-24 OPERATION PROFIT, GROSS 0.00, NET 0.00, size -45.00, price 22.20, value -999.00
          2021-08-24 cash 50746.72, portfolio 30017.04
          
          1 Reply Last reply Reply Quote 0
          • dev590t
            dev590t @Youssef 0 last edited by

            @youssef-0 If I add cerebro.broker.set_shortcash(False) the cash will not become very big : https://www.backtrader.com/blog/posts/2016-12-06-shorting-cash/shorting-cash/#in-action.

            I still don't know why, but it seems this instructions solve my problem:

            • without cerebro.broker.set_shortcash(False):
            2021-08-17 SELLEXECUTED ref :18.00, Price: 22.82, Value: 57152.13, Comm 0.00, pnl: -124.95, size: -2499.00
            2021-08-17 SELLEXECUTED ref :22.00, Price: 22.82, Value: -462.86, Comm 0.00, pnl: -62.00, size: -2503.00
            2021-08-17 SELLEXECUTED ref :26.00, Price: 22.82, Value: -57141.28, Comm 0.00, pnl: 0.00, size: -2504.00
            2021-08-17 SELLEXECUTED ref :30.00, Price: 22.82, Value: -57186.92, Comm 0.00, pnl: 0.00, size: -2506.00
            2021-08-17 SELLEXECUTED ref :34.00, Price: 22.82, Value: -85323.98, Comm 0.00, pnl: 0.00, size: -3739.00
            2021-08-17 BUYEXECUTED ref :35.00, Price: 127.52, Value: 28181.92, Comm 0.00, pnl: 0.00, size: 221.00
            2021-08-17 SELLEXECUTED ref :39.00, Price: 22.82, Value: -57209.74, Comm 0.00, pnl: 0.00, size: -2507.00
            2021-08-17 OPERATION PROFIT, GROSS -186.95, NET -186.95, size 0.00, price 22.87, value 0.00
            2021-08-17 OPERATION PROFIT, GROSS 0.00, NET 0.00, size -1263.00, price 22.82, value -28821.66
            2021-08-17 OPERATION PROFIT, GROSS 0.00, NET 0.00, size 221.00, price 127.52, value 28181.92
            2021-08-17 cash 343864.16, portfolio 29343.80
            
            • with cerebro.broker.set_shortcash(False):
            2021-08-17 SELLEXECUTED ref :15.00, Price: 120.63, Value: 28468.68, Comm 0.00, pnl: 0.00, size: -236.00
            2021-08-17 BUYEXECUTED ref :16.00, Price: 22.82, Value: 28433.72, Comm 0.00, pnl: 0.00, size: 1246.00
            2021-08-17 Order Canceled/Margin/Rejected
            2021-08-17 Order Canceled/Margin/Rejected
            2021-08-17 Order Canceled/Margin/Rejected
            2021-08-17 Order Canceled/Margin/Rejected
            2021-08-17 Order Canceled/Margin/Rejected
            2021-08-17 Order Canceled/Margin/Rejected
            2021-08-17 Order Canceled/Margin/Rejected
            2021-08-17 Order Canceled/Margin/Rejected
            2021-08-17 Order Canceled/Margin/Rejected
            2021-08-17 Order Canceled/Margin/Rejected
            2021-08-17 OPERATION PROFIT, GROSS 0.00, NET 0.00, size 0.00, price 120.63, value 0.00
            2021-08-17 OPERATION PROFIT, GROSS 0.00, NET 0.00, size 1246.00, price 22.82, value 28433.72
            2021-08-17 cash 1548.99, portfolio 29995.17
            
            1 Reply Last reply Reply Quote 0
            • 1 / 1
            • First post
              Last post
            Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors