Historical Market Screener: Processing Array Data - arrays

I have a question with respect to arrays & tables on PineScript, please. To give an overview of what I am intending to do, I want to create a screener that will go through a set of symbols and output the annual performance at a historical date.
The idea behind this concept is that I would be able to identify top performing symbols from a historical perspective. I have researched online, and I was not able to find such a tool.
The reason why I would need a tool like this, is so that I can back-test my strategy on historical top-performers, considering that I would be rebalancing my portfolio at a fixed interval e.g. once per quarter.
So my questions with regards to the code below are basically 2 –
How can I filter the arrays to output only values above 10% yearly performance?
How do I sort the table so that the top performers come to the top of the list?
I have shortened the code for this post. However, this screener can go through a max of 40 symbols as you all know. My plan is to run this on basically all the major and minor FX pairs and for stocks, I will pick a balanced portfolio with stocks from each of the 11 S&P sectors. As liquidity rotates through each of sectors, this should keep me running my strategy on stocks with positive alpha potential.
//#version=5
indicator('Annual Performance Historical Screener', overlay=true)
////////////
// INPUTS //
//Year Input
input_year = input(2022, "Year")
/////////////
// SYMBOLS //
u01 = input.bool(true, title = "", group = 'Symbols', inline = 's01')
u02 = input.bool(true, title = "", group = 'Symbols', inline = 's02')
u03 = input.bool(true, title = "", group = 'Symbols', inline = 's03')
u04 = input.bool(true, title = "", group = 'Symbols', inline = 's04')
u05 = input.bool(true, title = "", group = 'Symbols', inline = 's05')
s01 = input.symbol('XRPUSDT', group = 'Symbols', inline = 's01')
s02 = input.symbol('BTCUSDT', group = 'Symbols', inline = 's02')
s03 = input.symbol('DOGEUSDT', group = 'Symbols', inline = 's03')
s04 = input.symbol('BNBUSDT', group = 'Symbols', inline = 's04')
s05 = input.symbol('ETHUSDT', group = 'Symbols', inline = 's05')
//////////////////
// CALCULATIONS //
// Get only symbol
only_symbol(s) =>
array.get(str.split(s, ":"), 1)
//price at the input
price_input_year = timestamp(input_year,10,12)
period = time >= price_input_year and time[1] < price_input_year
periodPrice = ta.valuewhen(period, close, 0)
//price at 1 year preceeding input
price_prev_year = timestamp(input_year-1,10,12)
period_prev = time >= price_prev_year and time[1] < price_prev_year
periodPrice_prev = ta.valuewhen(period_prev, close, 0)
screener_func() =>
//Yearly performance from input date
annual_perf=(periodPrice-periodPrice_prev)*100/periodPrice
[math.round_to_mintick(close), annual_perf]
// Security call
[cl01, ap01] = request.security(s01, timeframe.period, screener_func())
[cl02, ap02] = request.security(s02, timeframe.period, screener_func())
[cl03, ap03] = request.security(s03, timeframe.period, screener_func())
[cl04, ap04] = request.security(s04, timeframe.period, screener_func())
[cl05, ap05] = request.security(s05, timeframe.period, screener_func())
////////////
// ARRAYS //
s_arr = array.new_string(0)
u_arr = array.new_bool(0)
cl_arr = array.new_float(0)
ap_arr = array.new_float(0)
// Add Symbols
array.push(s_arr, only_symbol(s01))
array.push(s_arr, only_symbol(s02))
array.push(s_arr, only_symbol(s03))
array.push(s_arr, only_symbol(s04))
array.push(s_arr, only_symbol(s05))
///////////
// FLAGS //
array.push(u_arr, u01)
array.push(u_arr, u02)
array.push(u_arr, u03)
array.push(u_arr, u04)
array.push(u_arr, u05)
///////////
// CLOSE //
array.push(cl_arr, cl01)
array.push(cl_arr, cl02)
array.push(cl_arr, cl03)
array.push(cl_arr, cl04)
array.push(cl_arr, cl05)
/////////
// Annual performance //
array.push(ap_arr, ap01)
array.push(ap_arr, ap02)
array.push(ap_arr, ap03)
array.push(ap_arr, ap04)
array.push(ap_arr, ap05)
///////////
// PLOTS //
var tbl = table.new(position.top_right, 6, 41, frame_color=#151715, frame_width=1, border_width=2, border_color=color.new(color.white, 100))
if barstate.islast
table.cell(tbl, 0, 0, 'Symbol', text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell(tbl, 1, 0, 'Price', text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell(tbl, 2, 0, 'Annual Performance', text_halign = text.align_center, bgcolor = color.gray, text_color = color.white, text_size = size.small)
for i = 0 to 4
if array.get(u_arr, i)
ap_col = array.get(ap_arr, i) >= 10 ? color.green : #aaaaaa
table.cell(tbl, 0, i + 1, array.get(s_arr, i), text_halign = text.align_left, bgcolor = color.gray, text_color = color.white, text_size = size.small)
table.cell(tbl, 1, i + 1, str.tostring(array.get(cl_arr, i)), text_halign = text.align_center, bgcolor = #aaaaaa, text_color = color.white, text_size = size.small)
table.cell(tbl, 2, i + 1, str.tostring(array.get(ap_arr, i), "#.##"), text_halign = text.align_center, bgcolor = ap_col, text_color = color.white, text_size = size.small)

Related

Fixing Plotting of Initial Balance Indicator in AmiBroker AFL

I am using the following AFL code for "Initial Balance with Range Extension" in AmiBroker -
_SECTION_BEGIN("Initial Balance with Range Extensions");
P11 = Param("IB Start Time",091500, 0 , 235959, 1 ) ;
P12 = Param("IB END Time",101500, 0 , 235959, 1 ) ;
START = (TimeNum()>= P11);
END = (TimeNum()<= P12);
ZONE = START AND END;
ST = (TimeNum()>= P12);
NewTime = ZONE!= Ref(ZONE, -1);
highestoftheday = HighestSince(NewTime,H,1);
Lowestoftheday = LowestSince(NewTime,L,1);
IBHigh = ValueWhen(ZONE,highestoftheday,1);
IBLow = ValueWhen(ZONE,lowestoftheday,1);
ORBClose = ValueWhen(zone,C,1);
IBrange = IBHigh - IBLow; // First Hour Range
IBM = IBLow+IBrange/2;
IB1xh = IBHigh+IBrange ; // Target 1 for range extension upside
IB2xh = IBHigh+2*IBrange ;
IB3xh = IBHigh+3*IBrange ;
IB1xl = IBLow-IBrange ;
IB2xl = IBLow-2*IBrange ; // target 1 for range extension downside
IB3xl = IBLow-3*IBrange ;
PlotGrid(LastValue(IBHigh, True), colorPlum, pattern=10, width = 2, label = True);
PlotGrid(LastValue(IBLow, True), colorPlum, pattern=10, width = 2, label = True);
PlotGrid(LastValue(IBM, True), colorBrown, pattern=10, width = 2, label = True);
PlotGrid(LastValue(IB1xh, True), colorGreen, pattern=10, width = 2, label = True);
PlotGrid(LastValue(IB2xh, True), colorGreen, pattern=10, width = 2, label = True);
PlotGrid(LastValue(IB3xh, True), colorGreen, pattern=10, width = 2, label = True);
PlotGrid(LastValue(IB1xl, True), colorRed, pattern=10, width = 2, label = True);
PlotGrid(LastValue(IB2xl, True), colorRed, pattern=10, width = 2, label = True);
PlotGrid(LastValue(IB3xl, True), colorRed, pattern=10, width = 2, label = True);
_SECTION_END();
This code is plotting continuous horizontal lines. But I need disjointed horizontal lines for individual sessions. How can I get that? Please help me to fix this issue. Thanks for your time and effort. Regards.

Import many files .txt in SAS

I built a code to import multiple data simultaneously into SAS, but I want to improve it does anyone have any suggestions?
filename indata pipe 'dir E:\Desafio_SAS\Dados /B';
data file_list;
length arquivos$20.;
infile indata truncover ;
input arquivos $20.;
call symput('num_files',_n_);
arquivos=compress(arquivos,',.txt');
run;
CRIANDO UMA MACRO POR PROC SQL PARA GUARDAR O NOME DOS ARQUIVOS
proc sql;
select arquivos into :lista separated by ' ' from file_list;
quit;
%let &lista;
%macro importar(arquivo=);
filename data "E:\Desafio_SAS\Dados\&arquivo..txt";
data &arquivo;
infile data dlm=" " missover dsd firstobs=2;
input v0 (v1 - v8) ($);
format v0 F16.;
run;
%mend importar;
%macro fileout;
%do i=1 %to &num_files;
%importar(arquivo=df&i);
data df&i;
set var_names df&i;
run;
%end;
%mend fileout;
%fileout;
%macro excluiv0;
%do i=1 %to &num_files;
data _null_;
data df&i(drop = v0);
set df&i;
run;
%end;
run;
%mend excluiv0;
%excluiv0;
It's just part of the code.
You can use a wildcard in the infile file-specification. As long as all the files meeting the wildcard are the same layout, you can use a single input to read all the files.
Example
* create three text files having same fields;
data _null_;
file '%temp%\1.txt';
put '1 2 3 abc';
put '3 4 5 def';
file '%temp%\2.txt';
put '6 7 8 ghi';
put '9 10 11 jkl';
file '%temp%\3.txt';
put '12 13 14 xyz';
put '15 16 17 tuv';
run;
* read all three using wildcard in infile. Save name of file whence
* data cometh frometh;
data want;
length _filename_ $250;
infile '%temp%\?.txt' filename=_filename_;
length source $250;
length a b c 8 s $20;
source = _filename_;
input a b c s;
run;
Wildcards are
?, 0 or 1 of any character
*, any number of any character
t1 <- ttheme_default(core=list(
fg_params=list(fontface=c("bold.italic")),
bg_params = list(fill=c("green", "grey90","blue","red"))))
grid.arrange(g1,
tableGrob(iris[1:5, 1:4], theme = t1,, rows=NULL),
g1, g1, nrow = 2)
---
title: "Column Orientation"
output: flexdashboard::flex_dashboard
---
```{r setup, include=FALSE}
library(ggplot2);library(knitr);library(kableExtra)
library(flexdashboard);library(gridExtra);library(grid)
```
<style>
.colored {
background-color: #002080;}
</style>
Column{data-width=200}
-------------------------------------
### Chart 1{.colored}
```{r}
gauge(10, min = 0, max = 100, sectors = gaugeSectors(colors = "#002080"))
gauge(50, min = 0, max = 100, sectors = gaugeSectors(colors = "#002080"))
gauge(20, min = 0, max = 100, sectors = gaugeSectors(colors = "#002080"))
gauge(15, min = 0, max = 100, sectors = gaugeSectors(colors = "#002080"))
gauge(5 , min = 0, max = 100, sectors = gaugeSectors(colors = "#002080"))
```
Column
-------------------------------------
### Chart 2
```{r, include=FALSE}
tt1 <- ttheme_default()
tt2 <- ttheme_minimal()
tt3 <- ttheme_minimal(
core=list(bg_params = list(fill = blues9[1:4], col=NA),
fg_params=list(fontface=3)),
colhead=list(fg_params=list(col="navyblue", fontface=4L)),
rowhead=list(fg_params=list(col="orange", fontface=3L)))
tab <- grid.arrange(tableGrob(iris[c(1:4,1:2), c(1:3,1:2)], theme=tt3), nrow=1)
graf <- ggplot(data=mtcars, aes(x=drat, y=disp, group=vs)) +
geom_line() + ylab("") +
geom_point()
gg.gauge <- function(pos,breaks=c(0,10,25,100)) {
get.poly <- function(a,b,r1=0.5,r2=1.0) {
th.start <- pi*(1-a/100)
th.end <- pi*(1-b/100)
th <- seq(th.start,th.end,length=1000)
x <- c(r1*cos(th),rev(r2*cos(th)))
y <- c(r1*sin(th),rev(r2*sin(th)))
return(data.frame(x,y))
}
ggplot()+
geom_polygon(data=get.poly(breaks[1],breaks[2]),aes(x,y),fill="forestgreen", colour = "white", size = 1.2, alpha = 0.7) +
geom_polygon(data=get.poly(breaks[2],breaks[3]),aes(x,y),fill="gold", colour = "white", size = 1.2, alpha = 0.7) +
geom_polygon(data=get.poly(breaks[3],breaks[4]),aes(x,y),fill="red", colour = "white", size = 1.2, alpha = 0.7) +
geom_polygon(data=get.poly(pos-1,pos+1,0.2),aes(x,y), colour = "white")+
annotate("text",x=0,y=0,label=pos,vjust=0,size=8,fontface="bold")+
coord_fixed()+
theme_bw()+
theme(axis.text=element_blank(),
axis.title=element_blank(),
axis.ticks=element_blank(),
panel.grid=element_blank(),
panel.border=element_blank())
}
gg1 <- gg.gauge(2,breaks=c(0,10,25,100))
gg2 <- gg.gauge(5,breaks=c(0,10,25,100))
gg3 <- gg.gauge(7,breaks=c(0,10,25,100))
```
```{r, fig.width=9.5, fig.height=7}
for (i in 1:5){
title1=textGrob("Test title TESTE", gp=gpar(fontface="bold", fontsize = 15))
lay <- rbind(c(3,3,4,4,5,5),
c(1,1,1,1,1,1),
c(1,1,1,1,1,1),
c(2,2,2,2,2,2),
c(2,2,2,2,2,2))
grid.arrange(graf, tab, gg1, gg2, gg3, top=title1,
layout_matrix= lay)
grid.rect(width = 1, height = 1, gp = gpar(lwd = 2, col = "black", fill = NA))
cat("\n")
}
```
---
title: "BRADESCO"
output:
flexdashboard::flex_dashboard:
orientation: rows
---
```{r setup, include=FALSE}
library(ggplot2);library(knitr);library(kableExtra)
library(flexdashboard);
library(gridExtra);library(grid)
```
Geral {data-icon="fa-signal"}
=====================================
### Chat 1
```{r}
p1 <- qplot(mpg, wt, data = mtcars, colour = cyl)
p2 <- qplot(mpg, data = mtcars)
p3 <- qplot(mpg, data = mtcars, geom = "dotplot")
lay <- rbind(c(1,1,1,2,2,2),
c(3,3,3,3,3,3))
grid.arrange(p2, p3, p1, nrow = 2, layout_matrix= lay)
```
### Table 1
```{r}
kable(mtcars[1:10, c(1:6,1:4)], caption = "Group Rows") %>%
kable_styling("striped", full_width = F) %>%
group_rows("Group 1", 4, 7) %>%
group_rows("Group 2", 8, 10)
```
Por segmento {data-icon="fa-signal"}
=====================================
<style>
.colored {
background-color: #002080;}
</style>
Row{data-height=200}
-------------------------------------
### Chart 1{.colored}
```{r, fig.width=55}
dat = data.frame(count=rep(c(10, 60, 30),10), category=rep(c("A", "B", "C"),10), fator=c(1,2,3,4,5))
# Add addition columns, needed for drawing with geom_rect.
dat$fraction = dat$count / sum(dat$count)
dat = dat[order(dat$fraction), ]
dat$ymax = cumsum(dat$fraction)
dat$ymin = c(0, head(dat$ymax, n=-1))
p <- ggplot(dat, aes(x=2, y=fraction, fill=category))+
geom_bar(stat="identity", colour = "white", size = 2) +
xlim(0, 2.5) +
scale_fill_manual(values=c("#002080", "#002080", "white")) +
coord_polar(theta = "y")+
labs(x=NULL, y=NULL)+ guides(fill=FALSE) +
ylab("fsfagafs") + facet_wrap(~ fator,nrow = 1) +
annotate("text", x = 0, y = 0, label = "WW", size = 20, colour = "white") +
theme(
plot.margin = margin(-1.1, 3.6, -1.1, 3.6, "cm"),
panel.spacing = unit(30, "lines"),
axis.ticks=element_blank(),
axis.text=element_blank(),
axis.title=element_blank(),
panel.grid=element_blank(),
plot.background = element_rect(fill = "#002080", colour="#002080"),
panel.background = element_rect(fill = "#002080", colour="#002080"),
strip.background = element_blank(),
strip.text.x = element_blank())
p
```
Row
-------------------------------------
### Chart 2 {data-wight=900}
```{r, include=FALSE}
tt1 <- ttheme_default()
tt2 <- ttheme_minimal()
tt3 <- ttheme_minimal(
core=list(bg_params = list(fill = blues9[1:4], col=NA),
fg_params=list(fontface=3)),
colhead=list(fg_params=list(col="navyblue", fontface=4L)),
rowhead=list(fg_params=list(col="orange", fontface=3L)))
tab <- grid.arrange(tableGrob(iris[c(1:4,1:2), c(1:3,1:2)], theme=tt3), nrow=1)
graf <- ggplot(data=mtcars, aes(x=drat, y=disp, group=vs)) +
geom_line() + ylab("") +
geom_point()
gg.gauge <- function(pos,breaks=c(0,10,25,100)) {
get.poly <- function(a,b,r1=0.5,r2=1.0) {
th.start <- pi*(1-a/100)
th.end <- pi*(1-b/100)
th <- seq(th.start,th.end,length=1000)
x <- c(r1*cos(th),rev(r2*cos(th)))
y <- c(r1*sin(th),rev(r2*sin(th)))
return(data.frame(x,y))
}
ggplot()+
geom_polygon(data=get.poly(breaks[1],breaks[2]),aes(x,y),fill="forestgreen", colour = "white", size = 1.2, alpha = 0.7) +
geom_polygon(data=get.poly(breaks[2],breaks[3]),aes(x,y),fill="gold", colour = "white", size = 1.2, alpha = 0.7) +
geom_polygon(data=get.poly(breaks[3],breaks[4]),aes(x,y),fill="red", colour = "white", size = 1.2, alpha = 0.7) +
geom_polygon(data=get.poly(pos-1,pos+1,0.2),aes(x,y), colour = "white")+
annotate("text",x=0,y=0,label=pos,vjust=0,size=8,fontface="bold")+
coord_fixed()+
theme_bw()+
theme(axis.text=element_blank(),
axis.title=element_blank(),
axis.ticks=element_blank(),
panel.grid=element_blank(),
panel.border=element_blank())
}
gg1 <- gg.gauge(2,breaks=c(0,10,25,100))
gg2 <- gg.gauge(5,breaks=c(0,10,25,100))
gg3 <- gg.gauge(7,breaks=c(0,10,25,100))
```
```{r, fig.width=7.2, fig.height=7}
for (i in 1:5){
title1=textGrob("Test title TESTE", gp=gpar(fontface="bold", fontsize = 15))
lay <- rbind(c(3,3,4,4,5,5),
c(1,1,1,1,1,1),
c(1,1,1,1,1,1),
c(2,2,2,2,2,2),
c(2,2,2,2,2,2))
grid.arrange(graf, tab, gg1, gg2, gg3, top=title1,
layout_matrix= lay)
grid.rect(width = 1, height = 1, gp = gpar(lwd = 2, col = "black", fill = NA))
cat("\n")
}
```
### Chart 2
```{r}
mydata = data.frame(x1 = c(1,2,3),
x2 = c(9,8,7),
label = c("description a",
"description b",
"description c"))
ht = 5
wd1 = 5
wd2 = 12
gap = 0.1
nc = ncol(mydata)
nr = nrow(mydata)
x = rep(c(seq(0,(nc-2)*(wd1+gap), wd1+gap), (nc-2)*(wd1+gap) + gap + 0.5*(wd2+wd1)), nr)
y = rep(seq(0,(nr-1)*(ht+gap), ht+gap), nc) %>% sort()
h = rep(ht, nr * nc)
w = rep(c(rep(wd1, nc-1), wd2), nr)
info = as.vector(t(as.matrix(mydata[nr:1,])))
df = data.frame(x = x, y = y, h = h, w = w, info = info)
ggplot(df, aes(x, y, height = h, width = w, label = info)) +
geom_tile() +
geom_text(color = "white", fontface = "bold") +
coord_fixed() +
scale_fill_brewer(type = "qual",palette = "Dark2") +
theme_void() +
guides(fill = F)
```
teste

AnyChart - Live Streaming Stock Chart

I call a database that gives me the initial time interval data to create a OHLC stock chart in AnyChart. Live price updates are then streamed.
What is the strategy about showing live price changes on the latest ticker?
I've been trying to figure out how to use a set function from the view or data class but no luck with table data.
Should I keep track of this newest interval and keep updating this row in AnyChart? When the interval is finished I drop the last one from the series and generate a new one?
If I caught your idea correctly, you're looking for an approach like the following one:
anychart.onDocumentReady(function () {
/*
An interval ticker and random number generators simulate incoming data.
For the demonstration purposes the time is “accelerated”.
*/
//create new point every 1 minute
var period = 60000;
//new price ticks come every 15 seconds
var tickPeriod = 15000;
var stage = anychart.graphics.create("container");
// create and tune the chart
var chart = anychart.stock();
var plot = chart.plot();
grouping = chart.grouping();
//create OHLC series
var ohlcSeries = plot.ohlc().name('OHLC');
// create dataset
var dataset = anychart.data.table();
dataset.addData(getData());
//map data
var mapping = dataset.mapAs({
x: 0,
open: 1,
high: 2,
low: 3,
close: 4
});
//set mapping to both series
ohlcSeries.data(mapping);
//render chart
chart.container(stage).draw();
/* --- simulation code --- */
//create empty array for point data update
var newDataRow = [];
newDataRow[0] = new Array(5);
//current price variable
var price = null;
//select the last point from existing datatable
var selectable = mapping.createSelectable();
selectable.selectAll();
var iterator = selectable.getIterator();
while(iterator.advance()) {
//put data from the last exsiting point
newDataRow[0][0] = iterator.get('x');
newDataRow[0][1] = iterator.get('open');
newDataRow[0][2] = iterator.get('high');
newDataRow[0][3] = iterator.get('low');
newDataRow[0][5] = iterator.get('close');
}
//timestamp variable for incoming ticks
var newTimestamp = newDataRow[0][0];
//simulate price ticker
window.setInterval(stream, 500);
//updating chart handler
function stream() {
//get new price
price = randomPrice();
//get timestamp of incoming price tick
newTimestamp += tickPeriod;
//current point update or create new point
if (newTimestamp - newDataRow[0][0] <= period) {
//set price as close for existing point
newDataRow[0][4] = price;
//update min and max
if (newDataRow[0][2] < price) {
newDataRow[0][2] = price;
} else if (newDataRow[0][3] > price) {
newDataRow[0][3] = price;
}
} else {
//erase update data array
newDataRow[0] = new Array(5);
//set data for the new point
newDataRow[0][0] = newTimestamp;
newDataRow[0][1] = price;
newDataRow[0][2] = price;
newDataRow[0][3] = price;
newDataRow[0][4] = price;
}
dataset.addData(newDataRow);
}
});
function randomPrice() {
return (Math.random() * (24 - 22) + 22).toFixed(2);
}
function getData() {
return [[1508889600000, 18.23, 19.36, 18.18, 19.31, 116002], [1508889660000, 19.5, 19.89, 19, 19.29, 113146], [1508889720000, 19.13, 19.15, 18.43, 18.75, 88690], [1508889780000, 18.54, 18.76, 18.27, 18.76, 80909], [1508889840000, 18.76, 19.14, 18.63, 18.76, 94782], [1508889900000, 18.97, 19.62, 18.96, 19.19, 133294], [1508889960000, 19.45, 19.7, 19.22, 19.67, 136209], [1508890020000, 19.69, 19.85, 19.37, 19.59, 136739], [1508890080000, 19.44, 19.55, 19, 19.35, 45322], [1508890140000, 19.21, 19.25, 18.51, 18.83, 37537], [1508890200000, 19.16, 19.78, 18.99, 19.76, 37994], [1508890260000, 19.69, 19.69, 19, 19.2, 114186], [1508890320000, 18.89, 18.95, 18.57, 18.61, 61185], [1508890380000, 18.59, 19.08, 18.57, 18.97, 40558], [1508890440000, 18.76, 19.19, 18.7, 18.78, 54007], [1508890500000, 18.92, 18.94, 18.47, 18.92, 65713], [1508890560000, 19.82, 21.2, 19.5, 20.91, 114016], [1508890620000, 20.55, 20.82, 20.28, 20.4, 100002], [1508890680000, 20.25, 20.27, 19.79, 19.93, 112040], [1508890740000, 20.11, 20.89, 20.06, 20.25, 106204], [1508890800000, 20.6, 21.1, 20.01, 20.26, 43234], [1508890860000, 20.19, 20.35, 19.86, 20.24, 45577], [1508890920000, 20.37, 20.4, 19.98, 20.19, 138514], [1508890980000, 20.14, 20.24, 19.64, 19.79, 15961], [1508891040000, 20.06, 20.07, 19.61, 19.79, 4816], [1508891100000, 19.96, 19.99, 19.14, 19.32, 42609], [1508891160000, 19.46, 19.64, 19.14, 19.42, 100893], [1508891220000, 19.2, 19.73, 19.01, 19.32, 106489], [1508891280000, 19.51, 20.06, 19.47, 19.89, 86507], [1508891340000, 19.92, 20, 19.67, 19.75, 122805], [1508891400000, 19.83, 20.23, 19.8, 20.06, 38734], [1508891460000, 20.13, 20.5, 19.98, 20.22, 128804], [1508891520000, 20.36, 20.6, 20.24, 20.6, 30999], [1508891580000, 20.51, 20.74, 20.25, 20.31, 45246], [1508891640000, 20.41, 20.69, 20.22, 20.38, 101014], [1508891700000, 20.14, 20.23, 19.51, 19.82, 119823], [1508891760000, 19.93, 20.17, 19.47, 19.75, 73663], [1508891820000, 19.54, 20.45, 19.45, 20.34, 56848], [1508891880000, 20.25, 20.6, 20.07, 20.13, 133059], [1508891940000, 20.32, 20.63, 20.05, 20.45, 41431], [1508892000000, 20.56, 20.94, 20.3, 20.89, 30151], [1508892060000, 21, 21.5, 20.86, 21.4, 82553], [1508892120000, 21.36, 21.98, 21.2, 21.4, 81917], [1508892180000, 21.31, 21.76, 21.29, 21.73, 52368], [1508892240000, 21.77, 21.9, 21.58, 21.83, 20181], [1508892300000, 21.96, 22.31, 21.81, 22.14, 112622], [1508892360000, 21.98, 22.32, 21.63, 22.05, 99857], [1508892420000, 22.06, 22.32, 21.88, 22.08, 105763], [1508892480000, 22.17, 22.62, 22.12, 22.55, 118968], [1508892540000, 22.59, 23.26, 22.57, 22.83, 12246], [1508892600000, 22.9, 23.38, 22.74, 23.33, 134378], [1508892660000, 23.23, 23.54, 23.02, 23.42, 117356], [1508892720000, 23.47, 24.11, 23.44, 23.45, 71104], [1508892780000, 23.5, 23.82, 23.17, 23.68, 44932], [1508892840000, 23.62, 23.69, 23.3, 23.5, 87991], [1508892900000, 24.04, 24.34, 23.75, 24.07, 91442], [1508892960000, 23.95, 23.95, 23.25, 23.28, 34895], [1508893020000, 23.38, 23.66, 23.21, 23.34, 88422], [1508893080000, 23.45, 23.75, 23.36, 23.47, 65606], [1508893140000, 23.43, 23.92, 23.2, 23.79, 127863], [1508893200000, 23.57, 23.69, 23.32, 23.35, 81565], [1508893260000, 23.6, 24.03, 23.55, 23.86, 56219], [1508893320000, 23.97, 24.24, 23.63, 23.77, 89107], [1508893380000, 24.05, 24.3, 23.96, 24.04, 94978], [1508893440000, 23.76, 24.04, 23.21, 23.37, 83000]];
}
html, body, #container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://cdn.anychart.com/releases/v8/js/anychart-base.min.js"></script>
<script src="https://cdn.anychart.com/releases/v8/js/anychart-stock.min.js"></script>
<script src="https://cdn.anychart.com/releases/v8/js/anychart-ui.min.js"></script>
<link href="https://cdn.anychart.com/releases/v8/fonts/css/anychart-font.css" rel="stylesheet"/>
<link href="https://cdn.anychart.com/releases/v8/css/anychart-ui.min.css" rel="stylesheet"/>
<div id="container"></div>

Optimize matrices operations

I'm optimizing via Genetic Algorithm a machine simulator (of a MultiheadWeigher machine) in order to solve the well known "Setup problem". I based all the code on matricies but with the multiproduct case I think there is still some inefficiency...
Code
function [f] = MHW(position_matrix, HA, HB, HC)
global W_best_tot
global Function
global n_b_global
nComb = size(position_matrix,1);
dim = size(position_matrix,2);
WL = 241;
%SIMULATIONS VARIABLES
alpha = 0.123;
nSim = 3000;
CellUncertainty = 0.5 * 10^(-6);
%// Define Product Hopper allocation
WT_A = 130; WL_A = 129;
WT_B = 30; WL_B = 29;
%HC = 2;
WT_C = 90; WL_C = 89;
%// COMBINATION MATRIX
CombinantionMatrix_A = combn([0 1], HA);
CombinantionMatrix_B = combn([0 1], HB);
CombinantionMatrix_C = combn([0 1], HC);
if HA == 1
CombinantionMatrix_A = CombinantionMatrix_A.';
end
if HB == 1
CombinantionMatrix_B = CombinantionMatrix_B.';
end
if HC == 1
CombinantionMatrix_C = CombinantionMatrix_C.';
end
CombinantionMatrix_A_Transp = CombinantionMatrix_A.';
CombinantionMatrix_B_Transp = CombinantionMatrix_B.';
CombinantionMatrix_C_Transp = CombinantionMatrix_C.';
% OBJECTIVE FUNCTION COST COEFFICIENTS
Cu_A = 0.03; c_p = 0.6; c_f = 734; c_l = 3.2;
Cu_B = 0.09;
Cu_C = 0.04;
[HopperWeight UncertainWeight] = Weight(nComb, dim, alpha, ...
position_matrix, CellUncertainty);
HopperWeight_A = HopperWeight(:,1:HA);
HopperWeight_B = HopperWeight(:,HA+1:HA+HB);
HopperWeight_C = HopperWeight(:,HA+HB+1:HA+HB+HC);
UncertainWeight_A = UncertainWeight(:,1:HA);
UncertainWeight_B = UncertainWeight(:,HA+1:HA+HB);
UncertainWeight_C = UncertainWeight(:,HA+HB+1:HA+HB+HC);
W_best_tot = zeros(nComb, nSim);
W_best_ABC = zeros(nComb, 3, nSim);
for ii=1:nSim
W_A = HopperWeight_A * CombinantionMatrix_A_Transp;
W_B = HopperWeight_B * CombinantionMatrix_B_Transp;
W_C = HopperWeight_C * CombinantionMatrix_C_Transp;
W_Unc_A = UncertainWeight_A * CombinantionMatrix_A_Transp;
W_Unc_B = UncertainWeight_B * CombinantionMatrix_B_Transp;
W_Unc_C = UncertainWeight_C * CombinantionMatrix_C_Transp;
[~,comb_A] = min(abs(W_Unc_A - WT_A),[],2);
[~,comb_B] = min(abs(W_Unc_B - WT_B),[],2);
[~,comb_C] = min(abs(W_Unc_C - WT_C),[],2);
W_best_A = W_A(sub2ind_mod(size(W_A),1:size(W_A,1),comb_A.')).';
W_best_B = W_B(sub2ind_mod(size(W_B),1:size(W_B,1),comb_B.')).';
W_best_C = W_C(sub2ind_mod(size(W_C),1:size(W_C,1),comb_C.')).';
W_best_ABC(:,:,ii) = [W_best_A W_best_B W_best_C];
W_best_tot(:,ii) = sum(W_best_ABC(:,:,ii),2);
[HopperWeight_2_A UncertainWeight_2_A] = Weight(nComb, HA, alpha, ...
position_matrix(:,1:HA), CellUncertainty);
[HopperWeight_2_B UncertainWeight_2_B] = Weight(nComb, HB, alpha, ...
position_matrix(:,HA+1:HA+HB), CellUncertainty);
[HopperWeight_2_C UncertainWeight_2_C] = Weight(nComb, HC, alpha, ...
position_matrix(:,HA+HB+1:HA+HB+HC), CellUncertainty);
idx = CombinantionMatrix_A(comb_A,:)~=0;
HopperWeight_A(idx) = HopperWeight_2_A(idx);
UncertainWeight_A(idx) = UncertainWeight_2_A(idx);
idx = CombinantionMatrix_B(comb_B,:)~=0;
HopperWeight_B(idx) = HopperWeight_2_B(idx);
UncertainWeight_B(idx) = UncertainWeight_2_B(idx);
idx = CombinantionMatrix_C(comb_C,:)~=0;
HopperWeight_C(idx) = HopperWeight_2_C(idx);
UncertainWeight_C(idx) = UncertainWeight_2_C(idx);
clear HopperWeight_2_A HopperWeight_2_B HopperWeight_2_C ...
UncertainWeight_2_A UncertainWeight_2_B UncertainWeight_2_C;
end
n_b = logical(W_best_tot >= WL);
n_bA = logical(reshape(W_best_ABC(:,1,:), nComb, nSim) >= WL_A);
n_bB = logical(reshape(W_best_ABC(:,2,:), nComb, nSim) >= WL_B);
n_bC = logical(reshape(W_best_ABC(:,3,:), nComb, nSim) >= WL_C);
n_b_global = sum(n_b .* n_bA .* n_bB .* n_bC, 2);
GAvg_A = sum(reshape(W_best_ABC(:,1,:), nComb, nSim).*(reshape(...
W_best_ABC(:,1,:), nComb, nSim) > WT_A),2)./sum(reshape(...
W_best_ABC(:,1,:), nComb, nSim) > WT_A,2);
GAvg_B = sum(reshape(W_best_ABC(:,2,:), nComb, nSim).*(reshape(...
W_best_ABC(:,2,:), nComb, nSim) > WT_B),2)./sum(reshape(...
W_best_ABC(:,2,:), nComb, nSim) > WT_B,2);
GAvg_C = sum(reshape(W_best_ABC(:,3,:), nComb, nSim).*(reshape(...
W_best_ABC(:,3,:), nComb, nSim) > WT_C),2)./sum(reshape(...
W_best_ABC(:,3,:), nComb, nSim) > WT_C,2);
f = Cu_A .* GAvg_A + Cu_B .* GAvg_B + Cu_C .* GAvg_C + (nSim./...
n_b_global) .* c_p + (c_f./n_b_global) + ((nSim - n_b_global)./...
n_b_global) .* c_l;
Function = f;
Profiler
This is the Main Profiler and these are: the MHW function and the Weight function. The main problems are in the Weight since it's called 3000times for each GA generation...Above the Weight function code:
Weight Function Code
function [ HopperWeight UncertainWeight ] = Weight( nComb, H, alpha, AllComb, CellUncertainty )
HopperWeight = randn(nComb,H) * alpha;
HopperWeight = (1+HopperWeight) .* AllComb;
idx = HopperWeight<0;
random = randn(sum(idx(:)), 1);
HopperWeight(idx) = random .* ((1+alpha) .* AllComb(idx));
%ADD ERROR
RandomizeUncertainty = randn(nComb,H) * CellUncertainty;
UncertainWeight = abs((1+RandomizeUncertainty) .* HopperWeight);
end
Is there something that I am missing in order to optimize better the Weight function and in general the time consuming part in the MHW function? (If you need the GA launcher in order to try the MHW function use THIS code)
TIA

Wow addon failing to work with array

I'm trying to create a simple addon for world of warcraft which records my kills.
I've already got'n quite far except there is a problem with the writing of a lua array.
The code I have so far
local CharacterDefaults = {
kills = {},
totalkills = 0
}
local killDefaults = {
DBtimeofday = 0,
DBplayer = 0,
DBenemyname = 0,
DBenemyid = 0,
DBzone = 0,
DBkilltype = 0
}
The next piece is inside a event which checks for overkill
if not KillCount then
KillCount = CharacterDefaults
end
if not KillCount.totalkills then
KillCount.totalkills = 0
end
KillCount.enemy[KillCount.totalkills] = destName
KillCount.kills[KillCount.totalkills] = killDefaults
KillCount.kills[KillCount.totalkills].DBtimeofday = stamp
KillCount.kills[KillCount.totalkills].DBzone = zone
KillCount.kills[KillCount.totalkills].DBkilltype = killtype
KillCount.kills[KillCount.totalkills].DBenemyid = unitId
KillCount.kills[KillCount.totalkills].DBenemyname = destName
KillCount.kills[KillCount.totalkills].DBplayer = playerName
KillCount.totalkills = KillCount.totalkills + 1
Ofcourse there's more code but this is the only important code (as far as I know).
If I look at this I would expect that for every new kill a new array part is made and the values are entered. However, for each kill I make in world of warcraft, every single item already in it will get the results of the last kill.
The lua variables saved file:
KillCount = {
["kills"] = {
{
["DBplayer"] = "MyName",
["DBzone"] = "Blackrock Depths",
["DBkilltype"] = 0,
["DBenemyname"] = "Grim Patron",
["DBenemyid"] = 9545,
["DBtimeofday"] = "11-09-22 10:45:23",
}, -- [1]
{
["DBplayer"] = "MyName",
["DBzone"] = "Blackrock Depths",
["DBkilltype"] = 0,
["DBenemyname"] = "Grim Patron",
["DBenemyid"] = 9545,
["DBtimeofday"] = "11-09-22 10:45:23",
}, -- [2]
[0] = {
["DBplayer"] = "MyName",
["DBzone"] = "Blackrock Depths",
["DBkilltype"] = 0,
["DBenemyname"] = "Grim Patron",
["DBenemyid"] = 9545,
["DBtimeofday"] = "11-09-22 10:45:23",
},
},
["totalkills"] = 3,
}
as you can see the [0] is the only one to be properly writen. Am I doing something wrong?
The problem is here:
KillCount.kills[KillCount.totalkills] = killDefaults
Everytime you kill, you're pointing KillCount.kills[KillCount.totalkills] to killDefaults then modifying killDefaults. The problem is, you are using the same killDefaults every time. So when you udpate the values of killDefaults later, it affects every reference to killDefaults that you have already created.
Try something like:
function GetDefaultKills()
return {
DBtimeofday = 0,
DBplayer = 0,
DBenemyname = 0,
DBenemyid = 0,
DBzone = 0,
DBkilltype = 0
};
end
KillCount.kills[KillCount.totalkills] = GetDefaultKills()

Resources