from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random import math author = 'Your name here' doc = """ Your app description """ def build_report(name, success, cost): desc = str(name) + ", 準確率 " + str(success) + "%, 費用 " + str(cost) + " 萬" return { "name": name, "cost": cost, "success": success, "desc": desc } def make_index_field(num): index_list = ["EPS", "本益比", "股價/淨值比", "最近現金股利", "股本", "現金流量", "毛利率", "股東權益率", "資產報酬率", "營益率", "負債比率", "淨值", "MA", "RSI", "MTM", "KD", "MACD", "BIAS", "外資買超", "投信買超", "主力買超", "自營商買超", "外資賣超", "投信賣超", "主力賣超", "自營商賣超", "券資比", "產業別", "上下游產業鍊", "主要產品" ] return models.BooleanField( label = index_list[num-1], widget = widgets.CheckboxInput(), ) def draw_report(rp_choose, rp_source): num = random.randint(1,100) if rp_choose == 1: if num <= rp_source["success"]: if rp_source["name"] == "親朋好友消息": content = str(rp_source["name"]) + "(準確率未知): X 是好商品" else: content = str(rp_source["name"]) + "(準確率 " + str(rp_source["success"]) + "%): X 是好商品" else: if rp_source["name"] == "親朋好友消息": content = str(rp_source["name"]) + "(準確率未知): X 是壞商品" else: content = str(rp_source["name"]) + "(準確率 " + str(rp_source["success"]) + "%): X 是壞商品" if rp_choose == 0: content = str(rp_source["name"]) + ": 未取得" return content class Constants(BaseConstants): name_in_url = 'tsailan' players_per_group = None num_rounds = 1 lineratio = 25 good_inv = 260 bad_inv = 100 principal = 180 max_index_num = 30 postiveindexratio = 0.6 source_unknown = {"name": "親朋好友消息", "cost": 0, "success": 50, "desc": "親朋好友消息, 準確率未知, 費用 0 萬"} source_fb = build_report("FB 證券研究粉絲頁" , 60, 5) source_line = build_report("LINE 證券研究群組" , 60, 5) source_consultant = build_report("投顧老師報告" , 70, 15) source_profession = build_report("專業投顧公司報告" , 80, 25) outside_report = ['report_unknown', 'report_fb', 'report_line','report_consultant', 'report_profession'] class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): report_unknown = models.BooleanField(label = Constants.source_unknown["desc"],widget = widgets.CheckboxInput()) report_fb = models.BooleanField(label = Constants.source_fb["desc"], widget = widgets.CheckboxInput()) report_line = models.BooleanField(label = Constants.source_line["desc"], widget = widgets.CheckboxInput()) report_consultant = models.BooleanField(label = Constants.source_consultant["desc"], widget = widgets.CheckboxInput()) report_profession= models.BooleanField(label = Constants.source_profession["desc"], widget = widgets.CheckboxInput()) index_1 = make_index_field(1) index_2 = make_index_field(2) index_3 = make_index_field(3) index_4 = make_index_field(4) index_5 = make_index_field(5) index_6 = make_index_field(6) index_7 = make_index_field(7) index_8 = make_index_field(8) index_9 = make_index_field(9) index_10 = make_index_field(10) index_11 = make_index_field(11) index_12 = make_index_field(12) index_13 = make_index_field(13) index_14 = make_index_field(14) index_15 = make_index_field(15) index_16 = make_index_field(16) index_17 = make_index_field(17) index_18 = make_index_field(18) index_19 = make_index_field(19) index_20 = make_index_field(20) index_21 = make_index_field(21) index_22 = make_index_field(22) index_23 = make_index_field(23) index_24 = make_index_field(24) index_25 = make_index_field(25) index_26 = make_index_field(26) index_27 = make_index_field(27) index_28 = make_index_field(28) index_29 = make_index_field(29) index_30 = make_index_field(30) content_unknown = models.StringField() content_fb = models.StringField() content_line = models.StringField() content_consultant = models.StringField() content_profession = models.StringField() email = models.StringField() mobile = models.StringField() reportCost = models.IntegerField() remainInv = models.IntegerField() invdecision = models.StringField(widget = widgets.RadioSelect()) chip = models.IntegerField() totalindex = models.IntegerField() positive_index = models.IntegerField() negative_index = models.IntegerField() finalchip = models.IntegerField() linepoint = models.IntegerField() def get_cumchip(self): self.participant.vars["cum_chip"] = self.participant.vars["cum_chip"] + self.chip self.finalchip = self.participant.vars["cum_chip"] self.linepoint = math.ceil(self.finalchip/Constants.lineratio/10)*10 def invresult(self): if self.invdecision == "要投資": self.chip = Constants.good_inv - self.reportCost if self.invdecision == "不投資了": self.chip = self.remainInv def showreport(self): self.reportCost = (self.report_fb * Constants.source_fb["cost"] + self.report_line * Constants.source_line["cost"] + self.report_consultant * Constants.source_consultant["cost"] + self.report_profession * Constants.source_profession["cost"]) self.remainInv = Constants.principal - self.reportCost self.content_unknown = draw_report(self.report_unknown, Constants.source_unknown) self.content_fb = draw_report(self.report_fb, Constants.source_fb) self.content_line = draw_report(self.report_line, Constants.source_line) self.content_consultant = draw_report(self.report_consultant, Constants.source_consultant) self.content_profession = draw_report(self.report_profession, Constants.source_profession) self.totalindex = 0 for i in [self.index_1, self.index_2, self.index_3, self.index_4, self.index_5, self.index_6, self.index_7, self.index_8, self.index_9, self.index_10, self.index_11, self.index_12, self.index_13, self.index_14, self.index_15, self.index_16, self.index_17, self.index_18, self.index_19, self.index_20, self.index_21, self.index_22, self.index_23, self.index_24, self.index_25, self.index_26, self.index_27, self.index_28, self.index_29, self.index_30, ]: self.totalindex = self.totalindex + i red_ball = math.ceil(Constants.max_index_num * Constants.postiveindexratio) balls_in_bag = [1]*red_ball + [0]*(Constants.max_index_num - red_ball) balls_draw = random.sample(balls_in_bag, self.totalindex) self.positive_index = sum(balls_draw) self.negative_index = self.totalindex - self.positive_index