Storing and Accessing variable/values in amibroker afl code - amibroker

I am inputting few values with Param functions.
selecting timeframe
Assigning period to the selected timeframe.
Now if i want to store the timeframe and corresponding period to a array and later in the code if to retrieve it, how do i do it in amibroker AFL?
say like storing data similar to below at start of program
setting period[in3minutes] = 10;
setting period[in5minutes] = 20;
setting period[in10minutes] = 30;
and at end the getting assigned data
period1 = period[in3minutes];
period2 = period[in5minutes];
period3 = period[in10minutes];
Here is the sample code of setting the data with Param.
swing_tf = ParamList ("Custom TimeFrames0 (default is 15min)", "in1Minute|in3Minute|in5Minute|in15Minute|in25Minute|in30Minute|in45Minute|inHourly|in75Minute|in90Minute|inDaily|inWeekly|inMonthly", 3);
swing_period = Param ("Custom TimeFrames0 Periods", 20, 1, 200, 1);
swing_tf1 = ParamList ("Custom TimeFrames1 (default is 30min)", "in1Minute|in3Minute|in5Minute|in15Minute|in25Minute|in30Minute|in45Minute|inHourly|in75Minute|in90Minute|inDaily|inWeekly|inMonthly", 5);
swing_period1 = Param ("Custom TimeFrames1 Periods", 20, 1, 200, 1);
swing_tf2 = ParamList ("Custom TimeFrames2 (default is hourly)", "in1Minute|in3Minute|in5Minute|in15Minute|in25Minute|in30Minute|in45Minute|inHourly|in75Minute|in90Minute|inDaily|inWeekly|inMonthly", 7);
swing_period2 = Param ("Custom TimeFrames2 Periods", 20, 1, 200, 1);
swing_tf3 = ParamList ("Custom TimeFrames3 (default is 90min)", "in1Minute|in3Minute|in5Minute|in15Minute|in25Minute|in30Minute|in45Minute|inHourly|in75Minute|in90Minute|inDaily|inWeekly|inMonthly", 9);
swing_period3 = Param ("Custom TimeFrames3 Periods", 20, 1, 200, 1);
Thanks in advance for your time in helping me out with this query.

Try a matrix,
m = Matrix(1, 4, Null);
m[0][0] = in1Minute; // 1 Minute
m[0][1] = in1Minute * 3; // 3 Minute
m[0][2] = in5Minute; // 5 Minute
m[0][3] = in15Minute; // 15 Minute
p = [0][2] // in5Minute
It can be initialized easier if you are just looking for a set of constants.
m = MxFromString("{{10,20,30,40}}");

Related

How to get an alert once on a trend on a supertrend, in pinescript,with loop or another way?

How to get an alert once on a supertrend trend,I think with while i can solve(but my knowledge is not enough),maybe is another way to solve my problem.
I need to skip the first signal(on down/up trend) and enter the second alert, and this signal alert one time per supertrend trend.
I describe signals below in the code.
//#version=5
indicator("My-Supertrend", overlay=true, timeframe="", timeframe_gaps=true)
atrPeriod = input(13, "ATR Length")
atrPeriod2 = input(21, "ATR Length2")
factor = input.float(3.0, "Factor", step = 0.01)
factor2 = input.float(7.0, "Factor2", step = 0.01)
[supertrend, direction] = ta.supertrend(factor, atrPeriod)
[supertrend2, direction2] = ta.supertrend(factor2, atrPeriod2)
//ST 1
bodyMiddle = plot((open + close) / 2, display=display.none)
upTrend = plot(direction < 0 ? supertrend : na, "Up Trend", color = #00cf42, style=plot.style_linebr,linewidth=1)
downTrend = plot(direction < 0? na : supertrend, "Down Trend", color = #bb2c01, style=plot.style_linebr,linewidth=1)
//ST 2
bodyMiddle2 = plot((open + close) / 2, display=display.none)
upTrend2 = plot(direction2 < 0 ? supertrend2 : na, "Up Trend", color = #00cf42, style=plot.style_linebr,linewidth=3)
downTrend2 = plot(direction2 < 0? na : supertrend2, "Down Trend", color = #bb2c01, style=plot.style_linebr,linewidth=3)
//ST1 color
fill(bodyMiddle, upTrend, color.new(#95bd06, 80), fillgaps=false)
fill(bodyMiddle, downTrend, color.new(#0692bd, 80), fillgaps=false)
//ST2 color
fill(bodyMiddle2, upTrend2, color.new(#5abd13, 70), fillgaps=false)
fill(bodyMiddle2, downTrend2, color.new(#bd3006,70), fillgaps=false)
//Logic
down_upTrend=direction>0 and direction2<0 and direction[1]<0
up_upTrend=direction<0 and direction2<0 and direction[1]>0
up_downTrend=direction<0 and direction2>0 and direction[1]>0
down_downTrend=direction>0 and direction2>0 and direction[1]<0
//For short
while direction2>0
up_downTrend
continue
down_downTrend
break
//For Long
while direction2<0
down_upTrend
continue
up_upTrend
break
plotshape(up_upTrend,style=shape.triangleup,location=location.belowbar,size=size.normal,color=color.rgb(27, 182, 27))
plotshape(up_downTrend,style=shape.triangleup,location=location.belowbar,size=size.normal,color=color.rgb(20, 112, 20))
plotshape(down_upTrend,style=shape.triangledown,location=location.abovebar,size=size.normal,color=color.rgb(255, 0, 0))
plotshape(down_downTrend,style=shape.triangledown,location=location.abovebar,size=size.normal,color=color.rgb(141, 21, 21))
alertcondition(up_upTrend or down_downTrend,"Long/Short","Signal")
I try to solve with while loop(and i describe my logic in while loop),but while dont work like I think.

How to access array element sequentially in for loop in MATLAB?

I have 5 dataset:
data1=rand(1,1000)
data2=rand(1,1000)
data3=rand(1,1000)
data4=rand(1,1000)
data5=rand(1,1000)
I have to select the values sequentially and a non-repetitive way.
My whole pocess is for i=1,
Result1(index1) = data1(index1)+data1(2)
Result2(index1) = data2(index1)+data2(index2)
result3(index1) = data1(index3)+data2(index1)+data3(index1)
result4(index1) = data1(index4)+data3(index2)
And i want to continue this process for i=200,where array index should be in sequential way.
like following way:
Result1(index2) = data1(index5)+data1(6)
Result2(index2) = data2(index3)+data2(index4)
result3(index2) = data1(index7)+data2(index3)+data3(index3)
result4(index2) = data1(index8)+data3(index4)
Thank you for your time and considerations.
METHOD 1: using a FOR loop (SLOW)
data1=rand(1,1000);
data2=rand(1,1000);
data3=rand(1,1000);
data4=rand(1,1000); % ! not used
data5=rand(1,1000); % ! not used
% Preallocation of memory for better performance
result1 = zeros(1,200);
result2 = zeros(1,200);
result3 = zeros(1,200);
result4 = zeros(1,200);
% Main loop
for i=1:200
i1 = (i-1)*4+1; % takes values 1, 5, 9, 13,...
i2 = (i-1)*4+2; % takes values 2, 6, 10, 14,...
i3 = (i-1)*4+3; % takes values 3, 7, 11, 15,...
i4 = (i-1)*4+4; % takes values 4, 8, 12, 16,...
result1(i) = data1(i1)+data1(i2);
result2(i) = data2(i1)+data2(i2);
result3(i) = data1(i3)+data2(i1)+data3(i1);
result4(i) = data1(i4)+data3(i2);
end
METHOD 2: using MATRIX indexing operations (FAST)
imat = 1:200;
i1mat = 4*(imat-1)+1;
i2mat = 4*(imat-1)+2;
i3mat = 4*(imat-1)+3;
i4mat = 4*(imat-1)+4;
result1 = data1(i1mat)+data1(i2mat);
result2 = data2(i1mat)+data2(i2mat);
result3 = data1(i3mat)+data2(i1mat)+data3(i1mat);
result4 = data1(i4mat)+data3(i2mat);
You can also avoid to construct imat,i1mat,i2mat,i3mat,i4mat and just do:
result1 = data1(1:4:800)+data1(2:4:800);
result2 = data2(1:4:800)+data2(2:4:800);
result3 = data1(3:4:800)+data2(1:4:800)+data3(1:4:800);
result4 = data1(4:4:800)+data3(2:4:800);
All the methods give the same results.

Map Layer Issues in ggplot2

I'm having a few issues with finalizing my map for a report. I think I'm warm on the solutions, but haven't quite figured them out. I would really appreciate any help on solutions so that I can finally move on!
1) The scale bar will NOT populate in the MainMap code and the subsequent Figure1 plot. This is "remedied" in the MainMap code if I comment out the "BCWA_land" map layer. However, when I retain the "BCWA_land" map layer it will eliminate the scale bar and produces this error:
Warning message: Removed 3 rows containing missing values (geom_text).
And this is the code:
MainMap <- ggplot(QOI) +
geom_sf(aes(fill = quadID)) +
scale_fill_manual(values = c("#6b8c42",
"#70b2ae",
"#d65a31")) +
labs(fill = "Quadrants of Interest",
caption = "Figure 1: Map depicting the quadrants in the WSDOT project area as well as other quadrants of interest in the Puget Sound area.")+
ggtitle("WSDOT Project Area and Quadrants of Interest") +
scalebar(x.min = -123, x.max = -122.8, y.min = 47, y.max = 47.1, location = "bottomleft",
transform = TRUE, dist = 10, dist_unit = "km", st.size = 3, st.bottom = TRUE, st.dist = 0.1) +
north(data = QOI, location = "topleft", scale = 0.1, symbol = 12, x.min = -123, y.min = 48.3, x.max = -122.7, y.max = 48.4) +
theme_bw()+
theme(panel.grid= element_line(color = "gray50"),
panel.background = element_blank(),
panel.ontop = TRUE,
legend.text = element_text(size = 11, margin = margin(l = 3), hjust = 0),
legend.position = c(0.95, 0.1),
legend.justification = c(0.85, 0.1),
legend.background = element_rect(colour = "#3c4245", fill = "#f4f4f3"),
axis.title = element_blank(),
plot.title = element_text(face = "bold", colour = "#3c4245", hjust = 0.5, margin = margin(b=10, unit = "pt")),
plot.caption = element_text(face = "italic", colour = "#3c4245", margin = margin(t = 7), hjust = 0, vjust = 0.5)) +
geom_sf(data = BCWA_land) + #this is what I've tried to comment out to determine the scale bar problem
xlim (-123.1, -121.4) +
ylim (47.0, 48.45)
MainMap
InsetRect <- data.frame(xmin=-123.2, xmax=-122.1, ymin=47.02, ymax=48.45)
InsetMap <- ggplotGrob( ggplot( quads) +
geom_sf(aes(fill = "")) +
scale_fill_manual(values = c("#eefbfb"))+
geom_sf(data = BCWA_land) +
scale_x_continuous(expand = c(0,0), limits = c(-124.5, -122.0)) +
scale_y_continuous(expand = c(0,0), limits = c(47.0, 49.5)) +
geom_rect(data = InsetRect,aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax),
color="#3c4245",
size=1.25,
fill=NA,
inherit.aes = FALSE) +
theme_bw()+
theme(legend.position = "none",
panel.grid = element_blank(),
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
plot.margin = margin(0,0,0,0)))
InsetMap
Figure1 <- MainMap +
annotation_custom(grob = InsetMap, xmin = -122.2, xmax = -121.3,
ymin = 47.75, ymax = 48.5)
Figure1
As you can see I'm not getting this issue or error for my north arrow so I'm not really sure what is happening with the scale bar!
This problem is probably a little too OCD, however I REALLY don't want the gridlines to show up on the InsetMap, and was hoping that the InsetMap would overlay on top of the MainMap, without gridlines as I had those parameters set to element_blank() in the InsetMap code.
Here is an image of my plot. If you would like the data for this, please let me know. Because these are shapefiles, the data is unwieldy and not super conducive to SO's character limit for a post...
If anyone has any insight into a solution(s) I would so so appreciate that!! Thanks for your time!
The issue was the
xlim (-123.1, -121.4) +
ylim (47.0, 48.45)
call that I made. Instead, I used coord_sf(xlim = c(min, max), ylim = c(min, max)). I thought that this would be helpful to someone who might be in my position later on!
Essentially the difference between setting the limits of to the graph using just the x/y lim calls is that that truncates the data that is available in your dataset, whereas the coord_sf call simply "focuses" your graph on that extent if you will without altering the data you have available in your dataset.

value created from loop index incorrect

I'm probably overlooking something simple.
I'm looping through a 2D Array assigning values to variables in each object in the array. However when 'j' increments the value assigned to gameArray[1][1].x changes from 100 to 400, while it shouldn't be changed after the initial assignment.
--create tilemap 5x5 array
for i = 1, gridSize.x, 1 do
gameArray[i] = {}
for j = 1, gridSize.y, 1 do
gameArray[i][j] = tileArray[math.random(numTiles)]
gameArray[i][j].x = (i * 100)
gameArray[i][j].y = (j * 100)
debug.debug()
end
end
tileArray[x] is an object containing 4 integers and a love2D image loaded from a PNG.
--tUD
tileArray[1].u = 1
tileArray[1].r = 0
tileArray[1].d = 1
tileArray[1].l = 0
tileArray[1].img = love.graphics.newImage('tiles/tUD.png')
Below is a copy of the debug console while testing:
lua_debug> print(gameArray[1][1].y)
100
lua_debug> cont
lua_debug> print(gameArray[1][1].y)
100
lua_debug> cont
lua_debug> print(gameArray[1][1].y)
100
lua_debug> cont
lua_debug> print(gameArray[1][1].y)
400
lua_debug>
Any ideas what may be causing this?
Your inner loop is overwriting previously stored values in gameArray[i][j].y. This is because of this line:
gameArray[i][j] = tileArray[math.random(numTiles)]
Here, a random number, presumably from 1 to 25, is used to select a tile. But, it is likely that the same tile will be selected more that once, leading to the first value written to gameArray[i][1].y being overwritten when j is larger. I don't know exactly what functionality you desire here, but one solution is to build an array of indices, and to randomly select an index when selecting a tile, removing the index from the list so that it can not be selected again.
Here is an example of how this might be implemented. I have included some dummy initializations so that the code runs and displays results:
-- Dummy initializations
tileArray = {}
for i = 1, 25 do
tileArray[i] = {}
end
gameArray = {}
gridSize = {}
-- Initialize gridSize
gridSize.x = 5
gridSize.y = 5
-- List of available tile indices
indices = {}
for i = 1, 25 do
indices[i] = i
end
-- Create tilemap 5x5 array
for i = 1, gridSize.x do
gameArray[i] = {}
for j = 1, gridSize.y do
k = math.random(#indices)
index = indices[k]
table.remove(indices, k)
gameArray[i][j] = tileArray[index]
gameArray[i][j].x = (i * 100)
gameArray[i][j].y = (j * 100)
end
end
-- Display results
for i = 1, gridSize.x do
for j = 1, gridSize.y do
fmt = string.format("[%d][%d].x = %d, [%d][%d].y = %d\n",
i, j, gameArray[i][j].x, i, j, gameArray[i][j].y)
io.write(fmt)
end
end
Program output:
[1][1].x = 100, [1][1].y = 100
[1][2].x = 100, [1][2].y = 200
[1][3].x = 100, [1][3].y = 300
[1][4].x = 100, [1][4].y = 400
[1][5].x = 100, [1][5].y = 500
[2][1].x = 200, [2][1].y = 100
[2][2].x = 200, [2][2].y = 200
[2][3].x = 200, [2][3].y = 300
[2][4].x = 200, [2][4].y = 400
[2][5].x = 200, [2][5].y = 500
[3][1].x = 300, [3][1].y = 100
[3][2].x = 300, [3][2].y = 200
[3][3].x = 300, [3][3].y = 300
[3][4].x = 300, [3][4].y = 400
[3][5].x = 300, [3][5].y = 500
[4][1].x = 400, [4][1].y = 100
[4][2].x = 400, [4][2].y = 200
[4][3].x = 400, [4][3].y = 300
[4][4].x = 400, [4][4].y = 400
[4][5].x = 400, [4][5].y = 500
[5][1].x = 500, [5][1].y = 100
[5][2].x = 500, [5][2].y = 200
[5][3].x = 500, [5][3].y = 300
[5][4].x = 500, [5][4].y = 400
[5][5].x = 500, [5][5].y = 500
UPDATE
Given some more information about the goals of the OP code, it became apparent that you need to be able to use tiles from tileArray more than once. The problem is that by assigning an element from tileArray to gameArray[i][j], and then modifying gameArray[i][j], you are also modifying the original tile element.
The solution is to assign a copy of the tile element to gameArray[i][j]. Lua does not come with a function to copy tables, but you can look at this link to read about ways to copy tables. For a simple table requiring only a shallow copy, the page linked provides a function called shallowcopy(). Here is a modification of the above code that uses shallowcopy():
function shallowcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
-- Dummy initializations
numTiles = 5
tileArray = {}
for i = 1, numTiles do
tileArray[i] = {}
tileArray[i].tile_type = i
end
gameArray = {}
gridSize = {}
-- Initialize gridSize
gridSize.x = 5
gridSize.y = 5
-- Create tilemap 5x5 array
for i = 1, gridSize.x do
gameArray[i] = {}
for j = 1, gridSize.y do
gameArray[i][j] = shallowcopy(tileArray[math.random(numTiles)])
gameArray[i][j].x = (i * 100)
gameArray[i][j].y = (j * 100)
end
end
-- Display results
for i = 1, gridSize.x do
for j = 1, gridSize.y do
fmt = string.format("[%d][%d].x = %d, [%d][%d].y = %d : type %d\n",
i, j, gameArray[i][j].x, i, j, gameArray[i][j].y,
gameArray[i][j].tile_type)
io.write(fmt)
end
end
Program output:
[1][1].x = 100, [1][1].y = 100 : type 1
[1][2].x = 100, [1][2].y = 200 : type 1
[1][3].x = 100, [1][3].y = 300 : type 5
[1][4].x = 100, [1][4].y = 400 : type 2
[1][5].x = 100, [1][5].y = 500 : type 3
[2][1].x = 200, [2][1].y = 100 : type 5
[2][2].x = 200, [2][2].y = 200 : type 4
[2][3].x = 200, [2][3].y = 300 : type 2
[2][4].x = 200, [2][4].y = 400 : type 4
[2][5].x = 200, [2][5].y = 500 : type 3
[3][1].x = 300, [3][1].y = 100 : type 3
[3][2].x = 300, [3][2].y = 200 : type 5
[3][3].x = 300, [3][3].y = 300 : type 2
[3][4].x = 300, [3][4].y = 400 : type 4
[3][5].x = 300, [3][5].y = 500 : type 3
[4][1].x = 400, [4][1].y = 100 : type 4
[4][2].x = 400, [4][2].y = 200 : type 3
[4][3].x = 400, [4][3].y = 300 : type 5
[4][4].x = 400, [4][4].y = 400 : type 2
[4][5].x = 400, [4][5].y = 500 : type 2
[5][1].x = 500, [5][1].y = 100 : type 5
[5][2].x = 500, [5][2].y = 200 : type 5
[5][3].x = 500, [5][3].y = 300 : type 1
[5][4].x = 500, [5][4].y = 400 : type 5
[5][5].x = 500, [5][5].y = 500 : type 3
While the above answer written by David Bowling works and is beautiful code, it does not fix the original problem as the duplication of tiles is prevented as part of the fix.
The original problem was fixed by using a shallow copy function for the table. Which was borrowed from the following site:
http://lua-users.org/wiki/CopyTable
Changing the line
gameArray[i][j] = tileArray[math.random(numTiles)]
to
gameArray[i][j] = shallowcopy(tileArray[math.random(numTiles)])
Adding this is as a second answer for anyone that has a similar problem

Corona show text from database in newScrollView

Im trying to pull some data from SQLite database to the Corona newScollView.
I managed to get data from the database in a tableView, so I thought the code should almost be the same for the newScrollView.
It keeps saying the row is empty, but its not. Any help?
Here is the code:
function scene:create( event )
local sceneGroup = self.view
local function scrollListener( event )
-- Get reference to the row group
local row = event.row
local options_metni =
{
parent = row,
text = row.params.Metni,
x = 0,
y = 0,
font = native.systemFont,
fontSize = 16
}
local metniObject = display.newText(options_metni)
metniObject:setTextColor(0)
metniObject.x = display.contentCenterX
end
---------------------
-- CREATE SCROLLVIEW
---------------------
local scrollView = widget.newScrollView
{
left = 0,
top = 0,
width = display.contentWidth,
height = display.contentHeight / 2,
topPadding = 200,
bottomPadding = 50,
horiontalScrollDisabled = true,
verticalScrollDisable = false,
listener = scrollListener,
}
sceneGroup:insert(scrollView)
---------------------
-- GET DATA FROM DB
---------------------
for row in db:nrows("SELECT baslik FROM dua LIMIT 1") do
if row.data == nil then
print(" NO DATA FOUND ")
end
local rowParams =
{
duaID = row.dua_id,
Metni = row.baslik,
}
end
end
You need to insert an object into the scrollView, it doesn't work like the tableView. Try this where the display object is being created and the text is being set from row.baslik:
for row in db:nrows("SELECT baslik FROM dua LIMIT 1") do
local text = display.newText( tostring( row.baslik ), 0, 0, native.systemFont, 16 )
scrollView:insert( text )
end

Resources