diff --git a/econ/agents/base_aquire_agent.py b/econ/agents/base_aquire_agent.py index 7b32a16..92f5cc4 100644 --- a/econ/agents/base_aquire_agent.py +++ b/econ/agents/base_aquire_agent.py @@ -63,6 +63,7 @@ class Base_Aquire_Agent(BaseAgent,ABC): self.business.balance-=total_price cx.add_to_account(self.id,"balance",total_price) # prepaid charge account for cx + cx.register_account(self.id,self.business.id) order=cx.submit_order(self.id,self.resource,amount,price_per,Side.BUY) if order==None: # Order failed return None diff --git a/econ/agents/base_distribution_agent.py b/econ/agents/base_distribution_agent.py index 9b1e208..e945a9c 100644 --- a/econ/agents/base_distribution_agent.py +++ b/econ/agents/base_distribution_agent.py @@ -69,6 +69,7 @@ class Base_Distribution_Agent(BaseAgent,ABC): self.business.inventory[self.resource]-=amount cx.add_to_account(self.id,self.resource,amount) # prepaid charge account for cx + cx.register_account(self.id,self.business.id) order=cx.submit_order(self.id,self.resource,amount,price_per,Side.SELL) if order==None: # Order failed return False diff --git a/econ/agents/price_believe_distribute.py b/econ/agents/price_believe_distribute.py index 2a7836d..4bd8772 100644 --- a/econ/agents/price_believe_distribute.py +++ b/econ/agents/price_believe_distribute.py @@ -10,18 +10,21 @@ class Price_Believe_Distribiute_Agent(Base_Distribution_Agent): def __init__(self, simulation, business, resource, exchanges: list, lr,at_sales, max_price_adj_rate) -> None: super().__init__(simulation, business, resource, exchanges) self.lr = lr + self.lr_at_sales=at_sales self.max_price_adj_rate = max_price_adj_rate self.price_believe = {i: 1 for i in range(len(self.exchanges))} + self.lr_moment={i: 0 for i in range(len(self.exchanges))} self.open_orders = {i: [] for i in range(len(self.exchanges))} self.open_qty = 0 + self.beta=0.6 self.lp_threshold=0.05 self.hp_threshold=0.80 def tick(self, step, episode): order_error = self.target_error() - if order_error > 0: + if (order_error > 0) & (self.open_qty==0): # aquire based on current price belive cx_id = self.select_best_cx() @@ -77,16 +80,17 @@ class Price_Believe_Distribiute_Agent(Base_Distribution_Agent): if o.leaves_qty == 0: # order is done self.open_orders[cx_id].remove(i) # remove order from open + self.update_trades() succsess=self.calc_order_success(cx,o) modifier=0 if succsess>=self.hp_threshold: modifier=1 elif succsess<=self.lp_threshold: modifier=-1 - self.update_believe(cx_id,o.price, succsess) # update price believe + self.update_believe(cx_id,o.price, succsess,o.qty) # update price believe self.collect_balance_from_cxs() self.collect_resource_from_cxs(self.resource) - self.update_trades() + continue if not (i["leaves"] == leaves): @@ -107,7 +111,7 @@ class Price_Believe_Distribiute_Agent(Base_Distribution_Agent): cx.cancel_order(i["id"]) self.collect_balance_from_cxs() self.collect_resource_from_cxs(self.resource) - self.update_believe(cx_id,o.price, succsess) + self.update_believe(cx_id,o.price, succsess,o.qty) self.open_orders[cx_id].remove(i) def calc_order_success(self,cx, o): """ @@ -121,15 +125,19 @@ class Price_Believe_Distribiute_Agent(Base_Distribution_Agent): score=sold-nsold return score - def update_believe(self, cx_id, used_price, modifier): + def update_believe(self, cx_id, used_price, modifier,qty): """ Updates the believe based on the modifier. If positive will add lr to believe If negative will sub lr to believe """ - clipMod=max(-self.lr_at_sales,min(modifier,self.lr_at_sales)) + clipMod=max(-qty,min(modifier,qty)) + moment=clipMod/qty #clip mod so that price believe more smooth - self.price_believe[cx_id]+=(clipMod/self.lr_at_sales)*self.lr + + self.lr_moment[cx_id]=self.lr_moment[cx_id]*self.beta + (1-self.beta)*moment + update=self.lr_moment[cx_id]*self.lr + self.price_believe[cx_id]+=update self.price_believe[cx_id] = round(self.price_believe[cx_id], 2) if self.price_believe[cx_id] < 1: diff --git a/econ/business/Price_Believe_Business.py b/econ/business/Price_Believe_Business.py index 1fc9307..5269756 100644 --- a/econ/business/Price_Believe_Business.py +++ b/econ/business/Price_Believe_Business.py @@ -14,7 +14,7 @@ class Price_Believe_Business(Business): self.expense_per_prod=-1 self.income_per_unit = -1 self.distribute = Price_Believe_Distribiute_Agent( - simulation, self, production["name"], exchange, 0.2,production["amount"]*2, 20) + simulation, self, production["name"], exchange, 0.5,production["amount"]*2, 20) self.craft = AutoProductionAgent(simulation, self) self.aquire = {} @@ -45,10 +45,7 @@ class Price_Believe_Business(Business): retain=0 else: ie = (self.income_per_unit/self.expense_per_unit)-1 - if ie < 0: - ie = 0 - if ie > 1: - ie = 1 + ie=max(0,min(ie,1)) retain=((self.max_storage-ie*self.max_storage)*amount)-amount #retain=0 diff --git a/econ/cells/cell.py b/econ/cells/cell.py index 7e20905..e5ec4ad 100644 --- a/econ/cells/cell.py +++ b/econ/cells/cell.py @@ -63,6 +63,7 @@ class Cell: qty=value/episode_length comm=cm.commoditys[demand_key] max_price=comm["max_world_price"]*qty + self.exchange.register_account(self.name,self.name) self.exchange.add_to_account(self.name,"balance",max_price) self.exchange.submit_order(self.name,demand_key,qty,comm["max_world_price"],Side.BUY) def setup_supply_for_episode(self): diff --git a/econ/exchange.py b/econ/exchange.py index 97cc6f4..50a9e08 100644 --- a/econ/exchange.py +++ b/econ/exchange.py @@ -9,6 +9,10 @@ import uuid import threading software_start=int(time.time()) + + + + class Exchange(): """ Basic Commodity exchange. @@ -26,6 +30,9 @@ class Exchange(): self.order_account_map={} self.orders={} self.executed_trades=[] + self.trade_curser=0 + self.account_business={} + self.order_trades_map={} self.market_rate={} self.best_ask={} @@ -36,7 +43,11 @@ class Exchange(): #self.supply={} self.traded_commoditys={} self.lock=threading.Lock() - + + + def register_account(self,account,business): + self.account_business[account]=business + def add_to_account(self,account_id,resource,amount): """ Adds resources to account escrow @@ -320,6 +331,25 @@ class Exchange(): for item , value in self.market_rate.items(): if value!=None: localStepDB[item]["market_rate"]=int(value) + #Trade + new_trades=self.executed_trades[self.trade_curser:] + self.trade_curser=len(self.executed_trades)-1 + for t in new_trades: + if t.trade_side==1: + # will get logged twice so only log one side + # + account_id=self.order_account_map[t.order_id] + data={} + data["cxid"]=name + data["tstep"]=timepoint + data["episode"]=int(episode) + data["account"]=account_id + data["business"]=self.account_business[account_id] + data["order_id"]=t.order_id + data["instmt"]=t.instmt + data["price"]=int(t.trade_price) + data["qty"]=int(t.trade_qty) + log.EXTradeDataDetail.append(data) if autolog: for id,item in localStepDB.items(): diff --git a/econ/simulation.py b/econ/simulation.py index 12b66cc..f1d4523 100644 --- a/econ/simulation.py +++ b/econ/simulation.py @@ -71,7 +71,7 @@ class Simulation(): #self.taskpool.submit(self._execute_tick,row) fun(self.tick_count,self.episode_count) - self.taskpool.map(self._execute_tick,tasks) + #self.taskpool.map(self._execute_tick,tasks) diff --git a/log/__init__.py b/log/__init__.py index d3c728b..a04218d 100644 --- a/log/__init__.py +++ b/log/__init__.py @@ -15,6 +15,7 @@ write_client = None EXInit=False EXBooksData=[] EXTradeData=[] +EXTradeDataDetail=[] BUSINESSData=[] PerformanceData=[] def get_client(): @@ -35,8 +36,14 @@ def writeEXData(): df=pd.DataFrame(EXTradeData) df.to_sql("cx_trades",con=db, if_exists='replace', index=False,chunksize=10000) + t2=time.time() print(f"cx_trades completed: {t2-t1}/{df.size}") + df=pd.DataFrame(EXTradeDataDetail) + df.to_sql("cx_trades_detailed",con=db, if_exists='replace', + index=False,chunksize=10000) + t3=time.time() + print(f"cx_trades_detailed completed: {t3-t2}/{df.size}") def writeBusinessData(): db = create_engine(posturl) diff --git a/main.py b/main.py index 9b74720..13ae49e 100644 --- a/main.py +++ b/main.py @@ -29,8 +29,8 @@ cxs=[cx] #cx.submit_order(w,"Wood",0,1000,Side.BUY) #cx.submit_order(2,"Gem",1,10,Side.SELL) EPISODE_LEN=100 -NUM_EPISODES=100 -NUM_SEED_BUS=5 +NUM_EPISODES=50 +NUM_SEED_BUS=10