- Inherits From:
- Declared In:
This model presents an interesting scheduling challenge. We want to generate 501 periods of history that agents can refer to when they make decisions. The warmUp schedule is a repeating schedule, and we want its actions done 501 times, and when that is finished, we want the periodSchedule to begin at time 0, the starting time of actual agent involvement. When I looked at the original, I shuddered at the complexity of it. I thought to myself, there must be a simpler way to do this [grin :)], and it turns out there is. Now, in case you are comparing the new code against the old code, understand that the old ASM-2.0 way was like this. First, the warmUp schedule is created. Then a second nonrepeating schedule is created, called "startupSchedule." At time 0 in the model, that startupSchedule controls the first action, and the action it executes is a method that causes the warmUp schedule to run 501 steps of prehistory. I don't know why they had 501 steps, but they did. That's the warmUp method. The warmUp method gets that done by creating a temporary Swarm class without any context (activateIn: nil) and then activating the startupSchedule in there, so it runs "doWarmupStep" 501 steps, but none of the 501 steps count against time in the larger context of the model.
As of ASM-2.2, I have gotten rid of that complicated setup. Instead of creating the phony swarm and activating the warmup schedule inside it, I created a method in ASMModelSwarm.m that carries out one time step's worth of warmup. And then I dumped 501 createActionTo methods on the startup schedule that execute the required startup steps. I've verified the results are numerically identical to the original model. And the scheduling is much easier to understand.
After the warmUp, then an ActionGroup called "periodActions" comes to the forefront. The periodSchedule is a repeating schedule, which causes the periodActions to happen at every time step in the larger model.
In ASM-2.0, there was another initial schedule called initPeriodSchedule. After looking at it for a long time, I concluded it was doing nothing necessary, it was basically just running the periodActions at time 0 only. We might as well just schedule that action at time 0 in the startupSchedule. I have verified that the model runs exactly the same (numerically identical). Now, as noted below, I think this step is logically unnecessary, but removing it changes the numerical path of the simulation, so I'm leaving it in for comparison.
id <ActionGroup> periodActions;
id <Schedule> periodSchedule;
id <Schedule> startupSchedule;
id <List> agentList;
Specialist * specialist;
Dividend * dividendProcess;
World * world;
Output * output;
BFParams * bfParams;
ASMModelParams * asmModelParams;
modelTime An integer used to represent the current timestep periodActions An ActionGroup that collects things that are supposed to happen in a particular sequential order during each timestep periodSchedule Schedule on which we add period (repeating) actions, most importantly, the action group periodActions startupSchedule No description. agentList A Swarm collection of agents specialist Specialist who clears the market dividendProcess Dividend process that generates dividends world A World object, a price historian, really output An Output object bfParams A (BFParams) parameter object holding BFagent parameters asmModelParams A (ASMModelParms) parameter object holding parameters of Models
- - createEnd
- - setParamsModel:BF:
- - setOutputObject:
- - getAgentList
- - getNumBFagents
- - getInitialCash
- - getWorld
- - getSpecialist
- - getOutput
- - setBatchRandomSeed:
- - buildObjects
- - writeParams
- - buildActions
- - activateIn:
- - doWarmupStep
- - periodStepDividend
- - periodStepPrice
- - getModelTime
- - drop
The activities of the ASMModelSwarm are brought into time-sync with higher level Swarm activities. Basically, each time the higher level takes a step, this one will too, and the higher one won't step again until this one is finished with its turn.
Create the model actions, separating into two different action groups, the warmup period and the actual period. Note that time is not calculated by a t counter but internally within Swarm. Time is recovered by the getTime message
Build and initialize objects
No method description.
Ask the dividend object for a draw from the dividend distribution, then tell the world about it. Tell the world to do an update of to respond to the dividend. Then calculate the price the divident implies and insert it into the world
No method description.
Returns a list that contains all the agents
Returns the initialcash value, which is held in asmModelParams
- (long int)getModelTime
Returns the integer time-step of the current simulation.
Returns the number of BFagents, which is held in asmModelParams
- (Output *)getOutput
Return a pointer to an object of the Output class. Sometimes it is necessary for other classes to find out who the output record keeper is and send that class a message.
- (Specialist *)getSpecialist
Return a pointer to the Specialist object
- (World *)getWorld
Returns a handle of the world object, the place where historical price/dividend information is maintained. It is also the place where the BFagents can retrieve information in bit string form.
Have the dividendProcess calculate a new dividend. Then tell the world about the dividendProcess output. Also this increment the modelTime variable
Have the Specialist perform the trading process. Then tell the world about the price that resulted from the Specialist's action.
The value of the randomSeed that starts the simulation will remain fixed, unless you change it by using this method
- setOutputObject:(Output *)obj
No method description.
- setParamsModel:(ASMModelParams *)modelParams BF:(BFParams *)bfp
This is very vital. When the ASMModelSwarm is created, it needs to be told where to find many constants that determine how agents are created. This passes handles of objects that have the required data.
This triggers a writing of the model parameters, for record keeping.