房地产企业类的设计

属于房地产研究的一部分,这个研究希望能模拟地产公司、地方政府、居民和金融部门的互动关系,用面向对象的方法制作一个地产公司类以模拟地产企业的重要行为。

  一、总体思考

        会计报表能够反映企业的经营信息,因此我们打算使用一些会计科目来帮助我们设计房地产企业类(当然这些科目不是那么严格地对应于实际使用的会计科目的)。 我们主要使用资产负债表和利润表,不使用现金流量表(因为我们假设所有的交易都是使用现金交易的,即收付实现制)。

        考虑一个典型的地产开发企业的业务就是从政府部门获取土地形成土地储备,使用土地储备生产商品房(库存商品),向居民销售商品房获取收入。其负债部分包括两部分:(1)向金融部门借入的有息负债(2)无息负债:主要是对供应商的应付账款和对居民的合同负债。

        以下是简化的资产负债表和利润表图示:

二、属性与方法       

依据这个框架,我们来设计地产公司类的主要属性。

地产公司类的主要属性
名称说明
name公司编号
endure存续状态,默认为True,根据某些标准可以判为破产
risk_preference风险偏好,即公司的冒险心态,分为HIGH/MIDDLE/LOW三个等级
assets总资产
currency_asset银行存款
land_reserve_num土地储备数量,单位是平方米
land_reserve_price土地储备的平均价格,由历史成本法计算移动平均数
land_reserve_value土地储备的总价值
store_num库存商品数量,单位是平方米
store_price库存商品的平均价格
store_value库存商品的总价值
debt_pool由字典组成的列表,每个字典都是一条目前存续的负债信息,包括三个字段:(1)debt_exist_year:债务剩余年限 (2)debt_num:债务本金 (3)debt_rate:债务利率
bank_debt有息负债总额
other_debt无息负债总额
total_debt总负债
reserve_profit留存收益
company_income销售收入
construction_cost为生产库存商品付出的建设成本,不包括土地储备转来的成本而和土地储备成本成一定比例
store_cost库存商品结转的成本
other_cost其他成本,一般指的是销售费用、管理费用等,与销售收入成一定比例
interst_cost利息费用
profit净利润
init_construction_rate初始的建设速率,是土地储备转库存商品的比例,可以在经营过程中调整(即企业可以决定本期将多少的土地储备投入生产)
construction_cost_ration相比于土地储备成本的建设成本支出(人工、物料等)
other_cost_ratio相比于销售收入的其他成本支出
plot_ratio容积率,按照这个比率将土地储备数量转为库存商品数量,例如一平米的土地储备可以生产三平米的商品房
init_bank_vs_other初始化的新增债务在有息负债和无息负债之间的比例分配,可以在运营过程中调整
deviation_rate与风险偏好程度决定的偏离率
expected_income_growth_rate_increse由财务风险水平对预期收入增长率的调整力度
rank按照收入计算的本公司在所有公司中的排名情况
doa资产负债率
roi净利率
ebit利息保障倍数
inv_tur_rate存货周转率
avg_debt_rate加权平均借款利率,反映公司的融资成本
is_balanced检查财务报表是否平衡

        公司类进行初始化的时候是依据一个给定的总资产数量以及一系列的比例进行初始化的,此外还需要一些其他的参数,这些参数中不变的部分放入parameter_pool中,会变动的部分放入total_info中。     

接下来我们考虑地产公司的主要行为/方法:

        

地产公司类的主要方法
名称

说明

generate_land_quotation产生对政府部门的土地报价(包括价格和数量),影响因素是本年市场景气指数、公司风险偏好、上一年度排名、上一年度ebit、库存商品量和土地储备量。公司需要预估今年的销售量和库存以确定土地的意愿购买量,公司风险偏好越高,则给出的意愿价格就越高。
update_sheet_by_land接受由土地交易函数(即专栏中的交易系统设计部分)返回的土地订单信息,据此更新财务信息
update_sheet_by_produce由于使用土地储备生产库存商品导致的财务信息变动
generate_rs_quotation生成对居民部门的商品房报价,包括意愿提供的数量和价格
update_sheet_by_sale接受来自商品房交易函数返回的销售订单信息,据此更新财务信息
update_sheet_by_debt支付债务的本息,假设是期间支付利息,最后一期支付本金和利息
increase_debt检查货币资金是否为负数,如果是,则新增债务,并在有息负债和无息赌债之间分配
profit_carried_forward结转利润并判断账目是否平衡
update_finance更新doa/ebit/roi/inv_tur_rate信息,并判断企业是否破产

三、代码实现

class Company():
    def __init__(self,company_dict):
        #需要从company_dict传递过来的只需要name/总资产/风险偏好,其他项目都按照总资产的相应比例自行构造
        self.endure = True
        self.name = company_dict['name']
        self.assets = company_dict['assets']
        self.risk_preference = company_dict['risk_preference']
        principle=self.assets*parameter_pool['init_bank_debt_ratio']
        self.debt_pool = [
            {
                'debt_exist_year':parameter_pool['loan_year'],
                'debt_num':principle,
                'debt_rate':parameter_pool['init_company_loan_rate']
            }
        ]
        #------------主要资产的分配------------
        self.currency_asset = self.assets*parameter_pool['init_currency_asset_ratio']
        self.land_reserve_value = self.assets*parameter_pool['init_land_reserve_value_ratio']
        self.land_reserve_price = parameter_pool['init_land_reserve_price']
        self.land_reserve_num = self.land_reserve_value/self.land_reserve_price
        self.store_value = self.assets*parameter_pool['init_store_value_ratio']
        self.store_price = parameter_pool['init_store_price']
        self.store_num = self.store_value/self.store_price
        #-----------负债和所有者权益的分配----------------
        self.bank_debt = self.assets*parameter_pool['init_bank_debt_ratio']
        self.other_debt = self.assets*parameter_pool['init_other_debt_ratio']
        self.total_debt = self.bank_debt + self.other_debt
        self.reserve_profit = self.assets*parameter_pool['init_reserve_profit_ratio']
        
        #------------利润表相关项目全部可以置为0-------------
        # 上一年度期末利润表
        self.company_income = self.assets*parameter_pool['init_company_income_ratio']  #主营业务收入
        self.construction_cost = 0 #中转性质的科目,置为0
        self.store_cost = self.assets*parameter_pool['init_store_cost_ratio'] #存货结转的成本
        self.other_cost = self.assets*parameter_pool['init_other_cost_ratio']#其他的成本
        self.interst_cost = self.assets*parameter_pool['init_interst_cost_ratio'] #利息支出
        self.profit = self.company_income-self.store_cost-self.other_cost-self.interst_cost #本年利润
        self.rank = total_info['reserved_company_income_ls'].index(self.company_income)+1
#         # 上一年度现金流量表
#         self.operating_in = 0 #经营活动现金收入,主来自产品销售
#         self.operating_out = 0 #经营活动现金流出,主要是购置土地和生产库存商品中的现金支出
#         self.financing_in = 0 #融资活动现金流入,来自银行负债和其他负债
#         self.financing_out = 0 #融资活动现金支出,主要是支付负债利息
        
        #财务信息汇总
        self.doa = self.total_debt/self.assets #资产负债率
        self.ebit = (self.profit+self.interst_cost)/self.interst_cost  #利息保障倍数
        self.roi = self.profit/self.company_income  #净利率
        self.inv_tur_rate = self.company_income/self.store_value #存货周转率,收入/存货
        self.is_banlanced = (self.assets-self.total_debt-self.reserve_profit)<5
        self.avg_debt_rate = parameter_pool['init_company_loan_rate'] #平均借款利率
        
        #做一个记录历史信息的表格
        self.history = pd.DataFrame(columns=[
            'is_balanced',
                        'land_reserve_num',
                       'land_reserve_price',
                       'land_reserve_value',
                       'currency_asset',
                        'store_num',
                        'store_price',
                        'store_value',
                        'bank_debt',
                        'other_debt',
                        'reserve_profit',
                        'company_income',
                        'construction_cost',
                        'other_cost',
                        'store_cost',
                        'interst_cost',
                        'profit',
                        'avg_debt_rate',
                        'assets',
                        'debt',
                         'doa'
        ])
        
    #根据本年市场景气指数、风险偏好、上一年度排名、上一年度ebit
    #因为需要用到上一年度收入信息,因此,这个函数的调用在获得实际收入之前
    def generate_land_quotation(self):
        #计算按照上一年度收入的排名状况
        rank = total_info['reserved_company_income_ls'].index(self.company_income)+1
        #将排名映射为动力,要求最低的排名的动力增长为50%,最高的排名为0,共有100家公司
        expansion_motivation = rank**0.85/100
        expected_income_growth_rate = 0
        #按照财务状况对景气指数进行更改
        if self.ebit>= 1.5 and self.ebit<2.5: #财务状况正常
            expected_income_growth_rate = total_info['prosperity_index_price']
        elif self.ebit>=2.5: #财务状况良好
            expected_income_growth_rate = total_info['prosperity_index_price'] + parameter_pool['expected_income_growth_rate_increse']
        elif self.ebit < 1.5: #财务状况不良
            expected_income_growth_rate = total_info['prosperity_index_price'] - parameter_pool['expected_income_growth_rate_increse']
        #根据排名扩张动力、预期收入增长率确定预期销售收入
        expected_income = self.company_income*(1+expansion_motivation)*(1+expected_income_growth_rate)
        #计算预期销售量,由预期销售收入、市场景气指数、上期地产平均价格决定
        expected_sale_num = expected_income/(total_info['last_rs_price']*(1+total_info['prosperity_index_price']))
        #预期销售量-库存-可生产的潜力得到需要购买的土地量,不能小于0
        land_willing_mount = max((expected_sale_num-self.store_num-self.land_reserve_num*parameter_pool['plot_ratio'])/parameter_pool['plot_ratio'],0)#如果小于0,则取0
        #土地价格根据房产价格预期和风险倾向沟通决定
        deviation_rate = 0
        if self.risk_preference == 'HIGH':
            deviation_rate = parameter_pool['deviation_rate']
        else:
            deviation_rate = -parameter_pool['deviation_rate']
        #风险倾向越高,则喜欢出高价买地
        land_willing_price = total_info['last_land_price']*(1+total_info['prosperity_index_price'])*(1+deviation_rate)
        return {'name':self.name,'land_willing_price':land_willing_price,'land_willing_mount':land_willing_mount}

    #由于土地购买导致的财务变动
    def update_sheet_by_land(self,land_info):
        #land_info是个字典组成的列表,包括了需求方名字、土地购买的量和价格,可能存在多笔土地成交记录,也可能啥也没有
        try:
            for info in land_info:
                land_cost = info['land_num']*info['land_price']
                self.land_reserve_num = self.land_reserve_num + info['land_num'] #新增土地储备数量
                self.land_reserve_value = self.land_reserve_value + land_cost #新增土地储备价值
                self.land_reserve_price = self.land_reserve_value/self.land_reserve_num #更新土地储备平均成本
                self.currency_asset = self.currency_asset - land_cost #支付银行存款
        except Exception:
            print(str(self.name)+"号企业没有土地订单")

    #由于实际生产导致的财务信息变动
    def update_sheet_by_produce(self):
         ##1.借:库存商品 贷:土地储备 土地储备按照construction_rate转为库存商品
        #construction_rate按照预期的收入增长率在init_construction_rate基础上改变
        construction_num = self.land_reserve_num*parameter_pool['init_construction_rate']*(1+total_info['prosperity_index_price']) #本年度转为库存商品的土地储备数量
        construction_value = construction_num*self.land_reserve_price #本年度土地储备转库存商品的值
        self.land_reserve_num = self.land_reserve_num - construction_num  #更新土地储备量
        self.land_reserve_value = self.land_reserve_num*self.land_reserve_price #更新土地储备价值
        self.store_num = self.store_num + construction_num*parameter_pool['plot_ratio']  #增加库存商品量,仅包括土地储备转来的那一部分
        self.store_value = self.store_value + construction_value# 增加库存商品价值,仅包括土地储备转来的部分
        ##2.借:建设成本 贷:银行存款
        construction_cost = construction_value*parameter_pool['construction_cost_ration']
        self.construction_cost = self.construction_cost+construction_cost
        self.currency_asset = self.currency_asset-construction_cost
        ##3.借:库存商品 贷:建设成本
        self.construction_cost = self.construction_cost-construction_cost
        self.store_value = self.store_value+construction_cost
        self.store_price = self.store_value/self.store_num  #更新库存商品价格
        ##4.其他成本由收入比例确定,在最后结转成本的时候记录

    #进行地产市场报价
    def generate_rs_quotation(self):
        deviation_rate=0
        if self.risk_preference=='HIGH':
            deviation_rate=parameter_pool['deviation_rate']
        elif self.risk_preference=='LOW':
            deviation_rate=-parameter_pool['deviation_rate']
        #计算按照上一年度收入的排名状况
        rank = total_info['reserved_company_income_ls'].index(self.company_income)+1
        #将排名映射为动力,要求最低的排名的动力增长为50%,最高的排名为0,共有100家公司
        expansion_motivation = rank**0.85/100
        expected_income_growth_rate = 0
        #按照财务状况对景气指数进行更改
        if self.ebit>= 0.5 and self.ebit<1: #财务状况正常
            expected_income_growth_rate = total_info['prosperity_index_price']
        elif self.ebit>=1: #财务状况良好
            expected_income_growth_rate = total_info['prosperity_index_price'] + parameter_pool['expected_income_growth_rate_increse']
        elif self.ebit < 0.5: #财务状况不良
            expected_income_growth_rate = total_info['prosperity_index_price'] - parameter_pool['expected_income_growth_rate_increse']
        #根据排名扩张动力、预期收入增长率确定预期销售收入
        expected_income = self.company_income*(1+expansion_motivation)*(1+expected_income_growth_rate)
        #计算预期销售量,由预期销售收入、市场景气指数、上期地产平均价格决定
        expected_sale_num = expected_income/(total_info['last_rs_price']*(1+total_info['prosperity_index_price']))
        rs_willing_price = total_info['last_rs_price']*(1+total_info['prosperity_index_price'])/(1+deviation_rate)
        #意愿的销售量不能超过实际库存
        rs_willing_num = max(expected_sale_num,self.store_num)
        return {'name':self.name,'rs_willing_price':rs_willing_price,'rs_willing_num':rs_willing_num}

    #根据地产撮合系统返回的信息获取收入、结转成本,sale_info是包括字典的列表
    def update_sheet_by_sale(self,sale_info):
        self.company_income = 0  #存在多笔销售,那么就需要累计了
        self.store_cost = 0
        self.other_cost = 0
        try:
            for info in sale_info:
                #允许出现负数
            ##1.销售商品 借:银行存款 贷:主营业务收入
                income = info['sell_num']*info['sell_price']
                self.currency_asset = self.currency_asset + income
                self.company_income =self.company_income + income

                ##2.借:存货成本 贷:库存商品
                store_cost = info['sell_num']*self.store_price
                self.store_cost =self.store_cost+ store_cost #借:存货结转成本
                self.store_num = self.store_num -  info['sell_num'] #更新库存数量
                self.store_value = self.store_num*self.store_price #更新库存商品价值
                ##3.借:其他成本 贷:银行存款
                other_cost = income*parameter_pool['other_cost_ratio']
                self.other_cost = self.other_cost + other_cost
                self.currency_asset = self.currency_asset - other_cost 
  
        except Exception:
            print(str(self.name)+'缺少销售订单信息')
        #如果库存被击穿,就通过银行存款购买库存商品,将其补充为0
        if self.store_num < 0:
            self.currency_asset -= -self.store_num*self.store_price
            self.store_num = 0
        

    #支付利息
    def update_sheet_by_debt(self):
        ## 支付利息和本金,这是年末发生的事情
        interst_cost = 0
        principle_cost = 0  #本金支出
        total_debt_num = 0
        debt_num_list = []
        debt_rate_list = []
        try:
            for single_debt_info in self.debt_pool:
                single_interst = single_debt_info['debt_num']*single_debt_info['debt_rate']
                total_debt_num = total_debt_num + single_debt_info['debt_num']
                debt_num_list.append(single_debt_info['debt_num'])
                debt_rate_list.append(single_debt_info['debt_rate'])
                interst_cost += single_interst  #计算总利息支出
                single_debt_info['debt_exist_year'] -= 1 #削减贷款年限
                if single_debt_info['debt_exist_year']==0:  #最后一年的话要归还本金
                    principle_cost += single_debt_info['debt_num']
                    self.debt_pool.remove(single_debt_info)  #从贷款信息池子里面删除这条信息

            ##记录对报表的影响
            self.bank_debt = self.bank_debt - principle_cost  #归还本金减少负债
            self.currency_asset = self.currency_asset - principle_cost - interst_cost
            self.interst_cost =interst_cost

            #更新公司平均借款利率,按照权重计算
            debt_num_array = np.array(debt_num_list)/total_debt_num
            debt_rate_array = np.array(debt_rate_list)
            self.avg_debt_rate = sum(debt_num_array*debt_rate_array) 
        except Exception:
            print(str(self.name)+'没有负债!')

    #根据银行存款余额确定债务的增加额度,如果银行存款为负数,则新增债务,并按照比值在有息债务和无息债务之间分配
    #这个比例和有息负债成本(平均借款利率成反比)
    def increase_debt(self):
        if self.currency_asset<0:
            num = -self.currency_asset
            ##借:银行存款 贷:银行负债
            bank_debt = num*parameter_pool['init_bank_vs_other']*(1-self.avg_debt_rate)
            self.currency_asset = self.currency_asset + bank_debt
            self.bank_debt = self.bank_debt + bank_debt
            ##借:银行存款  贷:其他负债
            other_debt = num*(1-parameter_pool['init_bank_vs_other']*(1-self.avg_debt_rate))
            self.currency_asset = self.currency_asset + other_debt
            self.other_debt = self.other_debt + other_debt
            ## 更新贷款池子信息
            new_debt = {
            'debt_exist_year':parameter_pool['loan_year'],
            'debt_num':num,
            'debt_rate':total_info['company_bank_debt_rate']
            }
            self.debt_pool.append(new_debt)

    #结转利润,并判断账务是否平衡
    def profit_carried_forward(self):
        # 进行利润结转,假设盈余或者亏损全部进入留存收益项目
        profit_num = self.company_income - self.store_cost-self.other_cost - self.interst_cost
        self.profit = profit_num
        self.reserve_profit = self.reserve_profit + profit_num
        self.total_debt = self.bank_debt + self.other_debt
        self.assets = self.land_reserve_value + self.store_value + self.currency_asset
        self.is_banlanced = (self.assets-self.total_debt-self.reserve_profit)<5

    #更新财务信息,并根据财务信息判断是否破产
    def update_finiance(self):
        self.doa = self.total_debt/self.assets #资产负债率
        self.ebit = (self.profit+self.interst_cost)/self.interst_cost  #利息保障倍数
        self.roi = self.profit/self.company_income  #净利率
        self.inv_tur_rate = self.company_income/self.store_value #存货周转率,收入/存货
        #如果资产负债率大于0.8,且利息保障倍数小于1,则破产
        if self.doa>=0.8 and self.ebit<=1:
            self.endure = False
    def make_com_table(self):
        ##测试用函数
        se = pd.Series({
             'is_balanced':self.is_banlanced,
            'land_reserve_num':self.land_reserve_num,
                       'land_reserve_price':self.land_reserve_price,
                       'land_reserve_value':self.land_reserve_value,
                       'currency_asset':self.currency_asset,
                        'store_num':self.store_num,
                        'store_price':self.store_price,
                        'store_value':self.store_value,
                        'bank_debt':self.bank_debt,
                        'other_debt':self.other_debt,
                        'reserve_profit':self.reserve_profit,
                        'company_income':self.company_income,
                        'construction_cost':self.construction_cost,
                        'other_cost':self.other_cost,
                        'store_cost':self.store_cost,
                        'interst_cost':self.interst_cost,
                        'profit':self.profit,
                        'avg_debt_rate':self.avg_debt_rate,
                        'assets':self.currency_asset+self.store_value+self.land_reserve_value,
                        'debt':self.bank_debt+self.other_debt,
                     'doa':self.doa
                       })
        self.history = self.history.append(se,ignore_index=True)
                                                       

四、效果检测

公司初始化和运行所需要的一些参数如下:

parameter_pool={
    'loan_year':3,#有息贷款年限
    'init_construction_rate':0.8,#初始的建设速率,是土地储备转库存商品的比例
    'construction_cost_ration':0.7,#相比于土地购置成本的建设成本支出
    'other_cost_ratio':0.2,#相比于营业收入的其他成本支出
    'plot_ratio':3,#容积率,按照这个比率将土地储备数量转为库存商品数量
    'init_currency_asset_ratio':0.2,#初始化现金比率
    'init_land_reserve_value_ratio':0.2, #初始化土地储备价值比例
     'init_land_reserve_price':5000,#初始化的土地储备价格
    'init_store_value_ratio':0.6,#初始化库存价值比例
    'init_store_price':8000,#初始化库存价格
    'init_bank_debt_ratio':0.3, #初始化银行负债比例
    'init_other_debt_ratio':0.5, #其他负债比例
    'init_reserve_profit_ratio':0.2,#初始化留存收益比例
    'init_company_loan_rate':0.1,#初始化公司贷款利率
    'init_company_income_ratio':0.1, #相对于资产的初始化收入比例
    'init_store_cost_ratio':0.06, #初始化存货成本比例
    'init_other_cost_ratio':0.02, #初始化其他成本比例
    'init_interst_cost_ratio':0.01, #初始化利息成本比例
    'deviation_rate':0.1, #由风险偏好程度决定的偏离率
    'expected_income_growth_rate_increse':0.02, #由财务风险水平对预期收入增长率的调整力度
    'init_bank_vs_other':0.5 #初始化新增债务在银行负债和其他负债之间的比例
}

total_info = {
    'company_bank_debt_rate':0.08,#企业贷款利率
    'rs_price':10000,#本年房地产成交价,
    'last_rs_price':9000,#上年房地产成交价
    'rs_roa':0.01,
    'land_price':30000, #本年土地市场成交均价
    'last_land_price':5000,#上年土地成交均价
    #-----------------景气指数-------------------
    'prosperity_index_price':0.05,
    #----------------运行中的其他数据--------------(可以不放在这里面的,但是写出来吧)
    'reserved_company_income_ls':ccc,#一个地产公司收入的集合,需要倒序
}

我们让公司持续运行10年 ,并且假设每年收入都不变(这样的话self.rank就可以根据同一个收入列表来计算了),看看最后的self.history的信息,它记录了财务信息的历史变动,重点关注账目是否平衡,这个history属性在最后的总体研究中是不需要保留的。

#初始化一个公司
com = Company({'name':1,'assets':139733628.6,'risk_preference':'HIGH'})
#让它运行十年
for i in range(10):
    com.update_sheet_by_land([{'land_num':20000,'land_price':1000}])
    com.update_sheet_by_produce()
    com.update_sheet_by_sale([{'sell_price':1397336.286,'sell_num':10}])
    com.update_sheet_by_debt()
    com.increase_debt()
    com.profit_carried_forward()
    com.update_finiance()
    com.make_com_table()

最后的history信息:

可见的确实现了账目平衡。

如果多设计一些会计科目的话,我们也可以用这个类实现会计做账的功能哦。

  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值