📄 world.m
字号:
// The Santa Fe Stockmarket -- Implementation of class World
// SOME VARIABLES EXPLAINED
//
// int malength[]
// List of moving average periods.
//
#import "World.h"
#import "MovingAverage.h"
#import <random.h>
#include <math.h>
#include <misc.h>
//pj:
/*" drand(), urand() and irand(x) are convenience macros to replace stuff from ASM random with Swarm random stuff "*/
#define drand() [uniformDblRand getDoubleSample]
#define urand() [uniformDblRand getDoubleWithMin: -1 withMax: 1]
#define irand(x) [uniformIntRand getIntegerWithMin: 0 withMax: x-1]
/*" GETMA(x,j) is a macro that checks to see if we want an exponential MA or regular when we retrieve values from MA objects "*/
#define GETMA(x,j) exponentialMAs ? [x[j] getEWMA]:[x[j] getMA]
/*" bitname struct holds the substantive information about various world indicators
It is a list of bit names and descriptions
// NB: If you change the order or meaning of bits, also check or change:
// 1. Their computation in -makebitvector in this file.
// 2. The PUPDOWBITNUM value.
// 3. The NAMES documentation file -- do "market -n > NAMES".
"*/
static struct bitnamestruct
{
const char *name;
const char *description;
} bitnamelist[] = {
{"on", "dummy bit -- always on"}, // 0
{"off", "dummy bit -- always off"},
{"random", "random on or off"},
{"dup", "dividend went up this period"}, // 3
{"dup1", "dividend went up one period ago"},
{"dup2", "dividend went up two periods ago"},
{"dup3", "dividend went up three periods ago"},
{"dup4", "dividend went up four periods ago"},
{"d5up", "5-period MA of dividend went up"}, // 8
{"d20up", "20-period MA of dividend went up"},
{"d100up", "100-period MA of dividend went up"},
{"d500up", "500-period MA of dividend went up"},
{"d>d5", "dividend > 5-period MA"}, // 12
{"d>d20", "dividend > 20-period MA"},
{"d>d100", "dividend > 100-period MA"},
{"d>d500", "dividend > 500-period MA"},
{"d5>d20", "dividend: 5-period MA > 20-period MA"}, // 16
{"d5>d100", "dividend: 5-period MA > 100-period MA"},
{"d5>d500", "dividend: 5-period MA > 500-period MA"},
{"d20>d100", "dividend: 20-period MA > 100-period MA"},
{"d20>d500", "dividend: 20-period MA > 500-period MA"},
{"d100>d500", "dividend: 100-period MA > 500-period MA"},
{"d/md>1/4", "dividend/mean dividend > 1/4"}, // 22
{"d/md>1/2", "dividend/mean dividend > 1/2"},
{"d/md>3/4", "dividend/mean dividend > 3/4"},
{"d/md>7/8", "dividend/mean dividend > 7/8"},
{"d/md>1", "dividend/mean dividend > 1 "},
{"d/md>9/8", "dividend/mean dividend > 9/8"},
{"d/md>5/4", "dividend/mean dividend > 5/4"},
{"d/md>3/2", "dividend/mean dividend > 3/2"},
{"d/md>2", "dividend/mean dividend > 2"},
{"d/md>4", "dividend/mean dividend > 4"},
{"pr/d>1/4", "price*interest/dividend > 1/4"}, // 32
{"pr/d>1/2", "price*interest/dividend > 1/2"},
{"pr/d>3/4", "price*interest/dividend > 3/4"},
{"pr/d>7/8", "price*interest/dividend > 7/8"},
{"pr/d>1", "price*interest/dividend > 1"},
{"pr/d>9/8", "price*interest/dividend > 9/8"},
{"pr/d>5/4", "price*interest/dividend > 5/4"},
{"pr/d>3/2", "price*interest/dividend > 3/2"},
{"pr/d>2", "price*interest/dividend > 2"},
{"pr/d>4", "price*interest/dividend > 4"},
{"pup", "price went up this period"}, // 42
{"pup1", "price went up one period ago"},
{"pup2", "price went up two periods ago"},
{"pup3", "price went up three periods ago"},
{"pup4", "price went up four periods ago"},
{"p5up", "5-period MA of price went up"}, // 47
{"p20up", "20-period MA of price went up"},
{"p100up", "100-period MA of price went up"},
{"p500up", "500-period MA of price went up"},
{"p>p5", "price > 5-period MA"}, // 51
{"p>p20", "price > 20-period MA"},
{"p>p100", "price > 100-period MA"},
{"p>p500", "price > 500-period MA"},
{"p5>p20", "price: 5-period MA > 20-period MA"}, // 55
{"p5>p100", "price: 5-period MA > 100-period MA"},
{"p5>p500", "price: 5-period MA > 500-period MA"},
{"p20>p100", "price: 20-period MA > 100-period MA"},
{"p20>p500", "price: 20-period MA > 500-period MA"},
{"p100>p500", "price: 100-period MA > 500-period MA"}
};
#define NWORLDBITS (sizeof(bitnamelist)/sizeof(struct bitnamestruct))
#define NULLBIT -1
// The index of the "pup" bit
#define PUPDOWNBITNUM 42
// Breakpoints for price*interest/dividend and dividend/mean-dividend ratios.
static double ratios[] =
{0.25, 0.5, 0.75, 0.875, 1.0, 1.125, 1.25, 1.5, 2.0, 4.0};
#define NRATIOS (sizeof(ratios)/sizeof(double))
#define EQ 0
// ------ Private methods ------
@interface World(Private)
-makebitvector;
@end
@implementation World
/*" The World is a class that is mainly used to serve the information needs of BFagents. The WOrld takes price data and converts it into a number of trends, averages, and so forth.
One instance of this object is created to manage the "world" variables
-- the globally-visible variables that reflect the market itself,
including the moving averages and the world bits. Everything is based
on just two basic variables, price and dividend, which are set only by
the -setPrice: and -setDividend: messages.
The World also manages the list of bits, translating between bit names
and bit numbers, and providing descriptions of the bits' functions.
These are done by class methods because they are needed before the
instnce is instantiated."*/
/*" Supplies a description of the specified bit, taken from the
* bitnamelist[] table below. Also works for NULLBIT.
"*/
+ (const char *)descriptionOfBit: (int)n
{
if (n == NULLBIT)
return "(Unused bit for spacing)";
else if (n < 0 || n >= NWORLDBITS)
return "(Invalid world bit)";
return bitnamelist[n].description;
}
/*" Supplies the name of the specified bit, taken from the
// bitnamelist[] table below. Also works for NULLBIT. Basically,
// it converts a bit number to a bit name.
"*/
+ (const char *)nameOfBit: (int)n
{
if (n == NULLBIT)
return "null";
else if (n < 0 || n >= NWORLDBITS)
return "";
return bitnamelist[n].name;
}
+ (int)bitNumberOf: (const char *)name
/*" Converts a bit name to a bit number. Supplies the number of a bit
* given its name. Unknown names return NULLBIT. Relatively slow
* (linear search). Could be made faster with a hash table etc, but
* that's not worth it for the intended usage. "*/
{
int n;
for (n = 0; n < NWORLDBITS; n++)
if (strcmp(name,bitnamelist[n].name) == EQ)
break;
if (n >= NWORLDBITS) n = NULLBIT;
return n;
}
- setintrate: (double)rate
/*" Interest rate set in ASMModelSwarm."*/
{
intrate = rate;
return self;
}
- setExponentialMAs: (BOOL)aBool
/*" Turns on the use of exponential MAs in calculations. Can be
turned on in GUI or ASMModelSwarm.m. If not, simple averages of
the last N periods."*/
{
exponentialMAs = aBool;
return self;
}
- (int)getNumWorldBits
/*" Returns numworldbits; used by the BFagent."*/
{
return nworldbits;
}
- initWithBaseline: (double)baseline
/*"
Initializes moving averages, using initial values based on
a price scale of "baseline" for the dividend. The baseline is
set in ASMModelSwarm. " */
{
int i;
double initprice, initdividend;
// Check pup index
if (strcmp([World nameOfBit:PUPDOWNBITNUM], "pup") != EQ)
printf("PUPDOWNBITNUM is incorrect");
// Set price and dividend etc from baseline
dividendscale = baseline;
initprice = baseline/intrate;
initdividend = baseline;
saveddividend = dividend = initdividend;
[self setDividend:initdividend];
savedprice = price = initprice;
[self setPrice:initprice];
// Initialize profit measures
returnratio = intrate;
profitperunit = 0.0;
// Initialize miscellaneous variables
nworldbits = NWORLDBITS;
malength[0] = 5;
malength[1] = 20;
malength[2] = 100;
malength[3] = MAXHISTORY;
history_top = 0;
updown_top = 0;
divhistory = [[self getZone] alloc: MAXHISTORY*sizeof(double)];
pricehistory = [[self getZone] alloc: MAXHISTORY*sizeof(double)];
realworld = calloc(NWORLDBITS, sizeof(int));
if(!realworld)
printf("Error allocating memory for realworld.");
// Initialize arrays
for (i = 0; i < UPDOWNLOOKBACK; i++)
{
pupdown[i] = 0;
dupdown[i] = 0;
}
for (i = 0; i < MAXHISTORY; i++)
{
pricehistory[i] = initprice;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -