a lot of fixes
This commit is contained in:
@@ -23,4 +23,16 @@ class BaseAgent(ABC):
|
||||
Resets agent to new episode.
|
||||
"""
|
||||
assert "No reset method has been provided"
|
||||
pass
|
||||
pass
|
||||
|
||||
def unregister(self):
|
||||
"""
|
||||
Disables agent by removing it from the simulation
|
||||
"""
|
||||
self.simulation.unregister_agent(id)
|
||||
def register(self):
|
||||
"""
|
||||
Enables agent by adding it to the simulation:
|
||||
"""
|
||||
self.simulation.register_agent(self.id,self.tick,self.reset)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ class Base_Aquire_Agent(BaseAgent,ABC):
|
||||
Agent for aquire of resources.
|
||||
business: Business to aquire resources for.
|
||||
resource: Resource to aquire.
|
||||
exchanges: list of exchanges to aquire resources from
|
||||
exchanges: list of exchanges to acquire resources from
|
||||
"""
|
||||
self.business=business
|
||||
self.resource=resource
|
||||
|
||||
@@ -90,8 +90,11 @@ class Base_Distribution_Agent(BaseAgent,ABC):
|
||||
cx=self.exchanges[cx_id]
|
||||
orders=self.orders[cx_id]
|
||||
if len(orders)>0:
|
||||
for o in orders:
|
||||
trades.append(cx.order_trades_map[o.order_id])
|
||||
for k,o in orders.items():
|
||||
if k in cx.order_trades_map:
|
||||
trades.append(cx.order_trades_map[k])
|
||||
self.trades=trades
|
||||
return trades
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ class Price_Believe_Aquire_Agent(Base_Aquire_Agent):
|
||||
super().__init__(simulation, business, resource, exchanges)
|
||||
self.lr=lr
|
||||
self.max_price_adj_rate=max_price_adj_rate
|
||||
self.price_believe={i: 0 for i in range(len(self.exchanges))}
|
||||
self.price_believe={i: 1 for i in range(len(self.exchanges))}
|
||||
self.open_orders={i: [] for i in range(len(self.exchanges))}
|
||||
self.open_qty=0
|
||||
|
||||
@@ -18,7 +18,7 @@ class Price_Believe_Aquire_Agent(Base_Aquire_Agent):
|
||||
|
||||
order_error=self.open_qty+self.target_error()
|
||||
if order_error<0:
|
||||
# aquire based on current price belive
|
||||
# aquire based on current price believe
|
||||
cx_id=self.select_best_cx()
|
||||
order=self.order_resource(self.price_believe[cx_id],order_error*-1,cx_id)
|
||||
if not order==None:
|
||||
@@ -32,10 +32,14 @@ class Price_Believe_Aquire_Agent(Base_Aquire_Agent):
|
||||
|
||||
def select_best_cx(self):
|
||||
best_id=-1
|
||||
best=0
|
||||
best=999999999
|
||||
for cx_id in range(len(self.exchanges)):
|
||||
cx=self.exchanges[cx_id]
|
||||
potential=cx.get_total_supply(self.resource)*self.price_believe[cx_id]
|
||||
available=(cx.get_total_supply(self.resource)>0)
|
||||
if available:
|
||||
potential=1*self.price_believe[cx_id]
|
||||
else:
|
||||
continue
|
||||
if potential<best:
|
||||
best=potential
|
||||
best_id=cx_id
|
||||
|
||||
@@ -8,7 +8,7 @@ class Price_Believe_Distribiute_Agent(Base_Distribution_Agent):
|
||||
super().__init__(simulation, business, resource, exchanges)
|
||||
self.lr=lr
|
||||
self.max_price_adj_rate=max_price_adj_rate
|
||||
self.price_believe={i: 0 for i in range(len(self.exchanges))}
|
||||
self.price_believe={i: 1 for i in range(len(self.exchanges))}
|
||||
self.open_orders={i: [] for i in range(len(self.exchanges))}
|
||||
self.open_qty=0
|
||||
|
||||
@@ -24,10 +24,14 @@ class Price_Believe_Distribiute_Agent(Base_Distribution_Agent):
|
||||
|
||||
def select_best_cx(self):
|
||||
best_id=-1
|
||||
best=0
|
||||
best=-1
|
||||
for cx_id in range(len(self.exchanges)):
|
||||
cx=self.exchanges[cx_id]
|
||||
potential=cx.get_total_supply(self.resource)*self.price_believe[cx_id]
|
||||
available=(cx.get_total_demand(self.resource)>0)
|
||||
if available:
|
||||
potential=1*self.price_believe[cx_id]
|
||||
else:
|
||||
continue
|
||||
if potential>best:
|
||||
best=potential
|
||||
best_id=cx_id
|
||||
|
||||
@@ -2,6 +2,7 @@ from .base_business import Business
|
||||
from ..agents.price_believe_aquire import Price_Believe_Aquire_Agent
|
||||
from ..agents.price_believe_distribute import Price_Believe_Distribiute_Agent
|
||||
from ..agents.autoproduction import AutoProductionAgent
|
||||
|
||||
class Price_Believe_Business(Business):
|
||||
def __init__(self, id, production, balance,exchange,simulation) -> None:
|
||||
super().__init__(id, production, balance)
|
||||
@@ -21,7 +22,7 @@ class Price_Believe_Business(Business):
|
||||
def tick_business_decisions(self,step):
|
||||
for comp in self.production["prod"]:
|
||||
for k,v in comp.items():
|
||||
modifier=self.craft.worker+1
|
||||
modifier=1
|
||||
self.aquire[k].set_target(v*modifier)
|
||||
max_amount=self.production["amount"]*5
|
||||
self.craft.set_target(max_amount)
|
||||
@@ -29,3 +30,8 @@ class Price_Believe_Business(Business):
|
||||
def resource_in_possesion(self):
|
||||
return self.distribute.open_qty+self.inventory[self.production["name"]]
|
||||
|
||||
def close_business(self):
|
||||
for a in self.aquire:
|
||||
a.unregister()
|
||||
self.distribute.unregister()
|
||||
self.production.unregister()
|
||||
@@ -1,4 +1,5 @@
|
||||
from abc import ABC
|
||||
import log
|
||||
class Business(ABC):
|
||||
def __init__(self,id,production,balance) -> None:
|
||||
"""production (dict): {
|
||||
@@ -43,3 +44,15 @@ class Business(ABC):
|
||||
"""
|
||||
assert "no business episode tick method has been created"
|
||||
|
||||
def close_business(self):
|
||||
assert "close_business has not been provided"
|
||||
|
||||
def log(self,episode,episode_length,step):
|
||||
data={}
|
||||
data["id"]=self.id
|
||||
data["episode"]=episode
|
||||
data["step"]=step
|
||||
data["tstep"]=step+episode*episode_length
|
||||
data["production"]=self.production["name"]
|
||||
data["balance"]=self.balance
|
||||
log.BUSINESSData.append(data)
|
||||
+1
-1
@@ -69,7 +69,7 @@ class Cell:
|
||||
self.exchange.reset()
|
||||
for supply_key,value in self.world.items():
|
||||
self.exchange.add_to_account(self.name,supply_key,value)
|
||||
self.exchange.submit_order(self.name,supply_key,value,0,Side.SELL)
|
||||
self.exchange.submit_order(self.name,supply_key,value,1,Side.SELL)
|
||||
|
||||
|
||||
|
||||
|
||||
+71
-5
@@ -1,5 +1,13 @@
|
||||
_bal="balance"
|
||||
from lightmatchingengine.lightmatchingengine import LightMatchingEngine,Side,Trade,Order,OrderBook
|
||||
import log
|
||||
from influxdb_client.client.write_api import SYNCHRONOUS
|
||||
from influxdb_client import InfluxDBClient, Point
|
||||
import time
|
||||
import pandas as pd
|
||||
import uuid
|
||||
|
||||
software_start=int(time.time())
|
||||
class Exchange():
|
||||
"""
|
||||
Basic Commodity exchange.
|
||||
@@ -110,6 +118,7 @@ class Exchange():
|
||||
Returns an order if the order is active. Returns None if submit has failed.
|
||||
"""
|
||||
# calculate price for complete order fullfilment
|
||||
amount=int(amount)
|
||||
full_price=price*amount
|
||||
|
||||
|
||||
@@ -219,15 +228,15 @@ class Exchange():
|
||||
for k,v in order_book.bids.items():
|
||||
self.demand[resource][k]=0
|
||||
for o in v:
|
||||
self.demand[resource][k]+=o.qty
|
||||
self.total_demand[resource]+=o.qty
|
||||
self.demand[resource][k]+=o.leaves_qty
|
||||
self.total_demand[resource]+=o.leaves_qty
|
||||
self.supply[resource]={}
|
||||
self.total_supply[resource]=0
|
||||
for k,v in order_book.asks.items():
|
||||
self.supply[resource][k]=0
|
||||
for o in v:
|
||||
self.supply[resource][k]+=o.qty
|
||||
self.total_supply[resource]+=o.qty
|
||||
self.supply[resource][k]+=o.leaves_qty
|
||||
self.total_supply[resource]+=o.leaves_qty
|
||||
|
||||
|
||||
self.best_ask[resource]=best_ask
|
||||
@@ -249,4 +258,61 @@ class Exchange():
|
||||
def get_total_supply(self,resource):
|
||||
if resource in self.total_supply:
|
||||
return self.total_supply[resource]
|
||||
return 0
|
||||
return 0
|
||||
|
||||
def log_step(self,name,episode,episode_length,step):
|
||||
timepoint=episode*episode_length+step
|
||||
localStepDB={}
|
||||
data={}
|
||||
data["cxid"]=name
|
||||
data["episode"]=episode
|
||||
data["step"]=step
|
||||
data["tstep"]=timepoint
|
||||
data["instrm"]="None"
|
||||
data["best_ask"]=-1
|
||||
data["best_bid"]=-1
|
||||
data["total_demand"]=-1
|
||||
data["total_supply"]=-1
|
||||
data["market_rate"]=-1
|
||||
|
||||
for id,order in self.orders.items():
|
||||
t=data.copy()
|
||||
t["instrm"]=order.instmt
|
||||
localStepDB[order.instmt]=t
|
||||
|
||||
## add best ask/best bid
|
||||
for item , value in self.best_ask.items():
|
||||
if value!=None:
|
||||
localStepDB[item]["best_ask"]=value
|
||||
for item , value in self.best_bid.items():
|
||||
if value!=None:
|
||||
localStepDB[item]["best_bid"]=value
|
||||
#demand supply
|
||||
for item , value in self.total_demand.items():
|
||||
if value!=None:
|
||||
localStepDB[item]["total_demand"]=value
|
||||
for item , value in self.total_supply.items():
|
||||
if value!=None:
|
||||
localStepDB[item]["total_supply"]=value
|
||||
#last market rate
|
||||
for item , value in self.market_rate.items():
|
||||
if value!=None:
|
||||
localStepDB[item]["market_rate"]=value
|
||||
|
||||
for id,item in localStepDB.items():
|
||||
log.EXBooksData.append(item)
|
||||
return data
|
||||
|
||||
def log_episode(self,name,episode):
|
||||
for t in self.executed_trades:
|
||||
data={}
|
||||
data["id"]=uuid.uuid4()
|
||||
data["cxid"]=name
|
||||
data["episode"]=episode
|
||||
data["order_id"]=t.order_id
|
||||
data["instmt"]=t.instmt
|
||||
data["price"]=t.trade_price
|
||||
data["qty"]=t.trade_qty
|
||||
data["side"]=t.trade_side
|
||||
log.EXTradeData.append(data)
|
||||
|
||||
|
||||
+62
-7
@@ -3,6 +3,9 @@ from .commoditys import commoditys as cm
|
||||
from .exchange import Exchange
|
||||
from .business import Price_Believe_Business
|
||||
import uuid
|
||||
import time
|
||||
|
||||
|
||||
class Simulation():
|
||||
"""
|
||||
Class for controlling the different calculation steps of the Simulation.
|
||||
@@ -11,8 +14,9 @@ class Simulation():
|
||||
self.tick_funcs={}
|
||||
self.reset_funcs={}
|
||||
self.tick_count=0
|
||||
self.episode_count=0
|
||||
self.episode_count=-1
|
||||
self.cells={}
|
||||
self.populated_cells={}
|
||||
self.businesses=[]
|
||||
self.production_util={}
|
||||
for k in cm.productions.items():
|
||||
@@ -37,6 +41,14 @@ class Simulation():
|
||||
|
||||
self.tick_funcs[id]=tickfunc
|
||||
self.reset_funcs[id]=resetfunc
|
||||
|
||||
def unregister_agent(self,id):
|
||||
"""
|
||||
Unregisters agent
|
||||
"""
|
||||
self.tick_funcs.pop(id,None)
|
||||
self.reset_funcs.pop(id,None)
|
||||
|
||||
|
||||
def tick_agents_random_order(self):
|
||||
"""
|
||||
@@ -53,22 +65,32 @@ class Simulation():
|
||||
"""
|
||||
Executes a tick of the simulation
|
||||
"""
|
||||
self.tick_agents_random_order()
|
||||
start=time.time()
|
||||
|
||||
for cell_id,c in self.cells.items():
|
||||
c.setup_demand_for_step(episode_length)
|
||||
setup=time.time()
|
||||
self.tick_agents_random_order()
|
||||
agentstep=time.time()
|
||||
for b in self.businesses:
|
||||
b.tick(self.tick_count)
|
||||
|
||||
if b.balance<=0:
|
||||
self.close_business(b.id)
|
||||
busstep=time.time()
|
||||
self.tick_count+=1
|
||||
self.log_cxs_tick(episode_length)
|
||||
self.log_business_tick(episode_length)
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
Resets all agents to new Episode
|
||||
"""
|
||||
self.log_cxs_episode()
|
||||
for k,v in self.reset_funcs.items():
|
||||
v(self.episode_count)
|
||||
for cell_id,cell in self.cells.items():
|
||||
cell.setup_supply_for_episode()
|
||||
|
||||
self.tick_count=0
|
||||
self.episode_count+=1
|
||||
|
||||
@@ -82,14 +104,15 @@ class Simulation():
|
||||
under.append(k)
|
||||
return under
|
||||
|
||||
def create_bussiness(self):
|
||||
|
||||
def create_bussiness(self,min_available_per_prod):
|
||||
"""
|
||||
Create a new business based on given econemy state.
|
||||
Return Business
|
||||
"""
|
||||
selected_prod=None
|
||||
# Create a business for every production rule out there
|
||||
under_prods=self.get_underutelized_prods(1)
|
||||
under_prods=self.get_underutelized_prods(min_available_per_prod)
|
||||
if len(under_prods)>0:
|
||||
# we need to create more businesses
|
||||
selected_prod=random.choice(under_prods)
|
||||
@@ -103,11 +126,23 @@ class Simulation():
|
||||
cell_id=random.choice(cells)
|
||||
cell=self.cells[cell_id]
|
||||
cxs=[cell.exchange,self.cx]
|
||||
self.populated_cells[cell_id]=True
|
||||
business=Price_Believe_Business.Price_Believe_Business(uuid.uuid4(),prod,1000,cxs,self)
|
||||
self.businesses.append(business)
|
||||
self.production_util[selected_prod]+=1
|
||||
return business
|
||||
|
||||
def remove_business(self,id):
|
||||
bus=None
|
||||
for i,busl in self.businesses:
|
||||
if busl.id==id:
|
||||
bus=i
|
||||
break
|
||||
|
||||
bus.close_business()
|
||||
self.businesses.remove(bus)
|
||||
|
||||
|
||||
def get_max_profit_prod(self):
|
||||
"""
|
||||
Returns the prod with the highest profit in last episode
|
||||
@@ -120,7 +155,7 @@ class Simulation():
|
||||
if diff>profit:
|
||||
profit=diff
|
||||
prod=b.production
|
||||
return prod
|
||||
return prod["id"]
|
||||
|
||||
|
||||
|
||||
@@ -146,4 +181,24 @@ class Simulation():
|
||||
cell_score[cell.name]+=cx.get_total_demand(prod["name"])
|
||||
cell_score[cell.name]-=cx.get_total_supply(prod["name"])
|
||||
max_keys = [key for key, value in cell_score.items() if value == max(cell_score.values())]
|
||||
return max_keys
|
||||
return max_keys
|
||||
|
||||
def log_cxs_tick(self,epi_length):
|
||||
for id,_ in self.populated_cells.items():
|
||||
cell=self.cells[id]
|
||||
lcx=cell.exchange
|
||||
name="lcx_{}".format(id)
|
||||
lcx.log_step(name,self.episode_count,epi_length,self.tick_count)
|
||||
self.cx.log_step("cx",self.episode_count,epi_length,self.tick_count)
|
||||
|
||||
def log_cxs_episode(self):
|
||||
for id,_ in self.populated_cells.items():
|
||||
cell=self.cells[id]
|
||||
lcx=cell.exchange
|
||||
name="lcx_{}".format(id)
|
||||
lcx.log_episode(name,self.episode_count)
|
||||
self.cx.log_episode("cx",self.episode_count)
|
||||
|
||||
def log_business_tick(self,episode_length):
|
||||
for bus in self.businesses:
|
||||
bus.log(self.episode_count,episode_length,self.tick_count)
|
||||
Reference in New Issue
Block a user