| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
 | local Grammar = require 'grammar'
local GA = require 'ga'
local data = {}
local csvFile = io.open('HistoricalData_1735758980544-AAPL.csv')
local skip = true
for line in csvFile:lines() do
  if skip then
    skip = false
  else
    local tbl = {}
    for lineValue in string.gmatch(line, '[^,]+') do
      table.insert(tbl, lineValue)
    end
    table.insert(data, tbl)
  end
end
local metaproduction = {}
metaproduction["<start>"] = {{'<functions>'}}
metaproduction["<functions>"] = { {}, {'<function>', '<functions>'} }
metaproduction["<function>"] = {{ 'defun(', '<arity>', ')\n' }}
metaproduction["<arity>"] = { {'0'}, {'1+', '<arity>'} }
local metagrammar = Grammar.createGrammar(metaproduction, {})
local production = {}
production["<start>"]={{'<expr>'}}
production["<expr>"]={ {'<data>'}, {'<number>'}, {'(','<expr>','<op>','<expr>',')'}, {'<func>','(','<expr>',')'} }
production["<op>"]={ {'+'}, {'-'}, {'*'}, {'/'} }
production["<func>"]={ {'math.log'}, {'math.exp'}, {'math.sin'}, {'math.cos'}, {'math.tan'}, }
production["<digit>"]={ {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'} }
production["<lowdigit>"]={ {'0'}, {'1'}, {'2'} }
production["<data>"]={ 
  {'high(','<date>',')'}, {'low(','<date>',')'}, 
  {'volume(','<date>',')'}, 
  {'open(','<date>',')'}, {'close(','<date>',')'}
}
production["<date>"]={ {'<lowdigit>','<digit>', '<digit>'} }
production["<number>"]={ {'0.','<digit>','<digit>','<digit>'} }
local grammar = Grammar.createGrammar(production, {})
--math.randomseed(0)
math.randomseed(os.time())
function randomGenome()
  local len = math.ceil(math.random() * 300)
  local genome = {}
  for i=1,len do
    table.insert(genome, math.floor(256 * math.random()))
  end
  return genome
end
local g = randomGenome()
print(#g, metagrammar:expand(randomGenome()))
os.exit(0)
function randomPop()
  local pop = {}
  for n=1,1000 do
    table.insert(pop, randomGenome())
  end
  return pop
end
function evaluate(genome)
  local s = 'return function(close, volume, open, high, low) return ' .. grammar:expand(genome) .. ' end'
  -- print(s)
  local f = assert(loadstring(s))()
  local cost = 0
  for n=1,1000 do
    local start = math.ceil((#data-300) * math.random()) + 300
    local dataView = function(offset, i) return tonumber(string.match(data[1 + start + offset][i], '[^$]+')) end
    local close = function(offset) return dataView(offset, 2) end
    local volume = function(offset) return dataView(offset, 3) end
    local open = function(offset) return dataView(offset, 4) end
    local high = function(offset) return dataView(offset, 5) end
    local low = function(offset) return dataView(offset, 6) end
    ok, y = pcall(f, close, volume, open, high, low)
    -- if ok and type(y) == 'table' then for k,v in pairs(y) do print(k, v) end end
    if (not ok) or (y ~= y) then
      cost = cost + 100
    else
      cost = cost + math.abs(y - high(-30))
    end
  end
  return -(cost)
end
local ga = GA.createGA(randomPop(), {
  evaluate=evaluate,
  crossover=function(a, b)
    local crossoverPoint = math.ceil(#a * math.random())
    local new = {}
    for i=1,#b do
      table.insert(new, (i>=crossoverPoint and b[i]) or a[i])
    end
    return new
  end,
  mutate=function(a)
    local new = {}
    for i,v in ipairs(a) do new[i] = v end
    local mutationPoint = math.ceil(#a * math.random())
    new[mutationPoint] = math.floor(256 * math.random())
    return new
  end,
})
for n=1,100 do
  print(ga:step())
  print(grammar:expand(ga.population[ga.bestMember]))
end
-- for k,v in ipairs(ga.population) do
--   print(k, '(', v[1], v[2], v[3], ')', evaluate(v))
-- end
 |