how to code 30 second candles in MT5 similar to the EA "candle by seconds" which i cant see the code for - bar-chart

enter image description here
Heres an image of an MT5 window showing 15s candles which is a free indicator in the MT5 market. How the heck did this person do this? it isnt renko and its not tradeable but i would like to try and create something like this... so that an indicator can be added and then trades can be placed on the 1min chart
wondering where to start? would it just be finding a way to group the tick data according to different set timeframes?
i can code EAs that use indicators and strategies but i just cant get my head around the seconds chart.
https://www.mql5.com/en/market/product/51159 thats the link for the actual indicator anyway
we have contacted the maker on the site, but not sure if hes active there anymore.
i actually did find a tickdata indicator that shows candles as 16ticks... is there a way to change this so that it shows seconds?
//+------------------------------------------------------------------+
//| TickColorCandles |
//| |
//+------------------------------------------------------------------+
#property copyright "Denis Zyatkevich"
#property description "The indicator plots the 'Tick Candles'"
#property version "1.00"
// Indicator is plotted in a separate window
#property indicator_separate_window
// One graphic plot is used, color candles
#property indicator_plots 1
// We need 4 buffers for OHLC prices and one - for the index of color
#property indicator_buffers 5
// Specifying the drawing type - color candles
#property indicator_type1 DRAW_COLOR_CANDLES
// Specifying the colors for the candles
#property indicator_color1 Gray,Red,Green
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
// Declaration of the enumeration
enum price_types
{
Bid,
Ask
};
// The ticks_in_candle input variable specifies the number of ticks,
// corresponding to one candle
input int ticks_in_candle=16; //Tick Count in Candles
// The applied_price input variable of price_types type indicates
// the type of the data, that is used in the indicator: Bid or Ask prices.
input price_types applied_price=0; // Price
// The path_prefix input variable specifies the path and prefix to the file name
input string path_prefix=""; // FileName Prefix
// The ticks_stored variable contains the number of stored quotes
int ticks_stored;
// The TicksBuffer [] array is used to store the incoming prices
// The OpenBuffer [], HighBuffer [], LowBuffer [] and CloseBuffer [] arrays
// are used to store the OHLC prices of the candles
// The ColorIndexBuffer [] array is used to store the index of color candles
double TicksBuffer[],OpenBuffer[],HighBuffer[],LowBuffer[],CloseBuffer[],ColorIndexBuffer[];
//+------------------------------------------------------------------+
//| Indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
// The OpenBuffer[] array is an indicator buffer
SetIndexBuffer(0,OpenBuffer,INDICATOR_DATA);
// The HighBuffer[] array is an indicator buffer
SetIndexBuffer(1,HighBuffer,INDICATOR_DATA);
// The LowBuffer[] array is an indicator buffer
SetIndexBuffer(2,LowBuffer,INDICATOR_DATA);
// The CloseBuffer[] array is an indicator buffer
SetIndexBuffer(3,CloseBuffer,INDICATOR_DATA);
// The ColorIndexBuffer[] array is the buffer of the color index
SetIndexBuffer(4,ColorIndexBuffer,INDICATOR_COLOR_INDEX);
// The TicksBuffer[] array is used for intermediate calculations
SetIndexBuffer(5,TicksBuffer,INDICATOR_CALCULATIONS);
// The indexation of OpenBuffer[] array as timeseries
ArraySetAsSeries(OpenBuffer,true);
// The indexation of HighBuffer[] array as timeseries
ArraySetAsSeries(HighBuffer,true);
// The indexation of LowBuffer[] array as timeseries
ArraySetAsSeries(LowBuffer,true);
// The indexation of CloseBuffer[] array as timeseries
ArraySetAsSeries(CloseBuffer,true);
// The indexation of the ColorIndexBuffer [] array as timeseries
ArraySetAsSeries(ColorIndexBuffer,true);
// The null values of Open prices (0th graphic plot) should not be plotted
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
// The null values of High prices (1st graphic plot) should not be plotted
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);
// The null values of Low prices (2nd graphic plot) should not be plotted
PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0);
// The null values of Close prices (3rd graphic plot) should not be plotted
PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
// the file_handle variable is a file handle
// the BidPosition and AskPosition - are positions of Bid and Ask prices in the string;
// the line_string_len is a length of a string, read from the file,
// CandleNumber - number of candle, for which the prices OHLC are determined,
// i - loop counter;
int file_handle,BidPosition,AskPosition,line_string_len,CandleNumber,i;
// The last_price_bid variable is the recent received Bid price
double last_price_bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
// The last_price_ask variable is the recent received Ask price
double last_price_ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
// the filename is a name of a file, the file_buffer is a string,
// used as a buffer for reading and writing of string data
string filename,file_buffer;
// Setting the size of TicksBuffer[] array
ArrayResize(TicksBuffer,ArraySize(CloseBuffer));
// File name formation from the path_prefix variable, name
// of financial instrument and ".Txt" symbols
StringConcatenate(filename,path_prefix,Symbol(),".txt");
// Opening a file for reading and writing, codepage ANSI, shared reading mode
file_handle=FileOpen(filename,FILE_READ|FILE_WRITE|FILE_ANSI|FILE_SHARE_READ);
if(prev_calculated==0)
{
// Reading the first line from the file and determine the length of a string
line_string_len=StringLen(FileReadString(file_handle))+2;
// if file is large (contains more quotes than rates_total/2)
if(FileSize(file_handle)>(ulong)line_string_len*rates_total/2)
{
// Setting file pointer to read the latest rates_total/2 quotes
FileSeek(file_handle,-line_string_len*rates_total/2,SEEK_END);
// Moving file pointer to the beginning of the next line
FileReadString(file_handle);
}
// if file size is small
else
{
// Moving file pointer at the beginning of a file
FileSeek(file_handle,0,SEEK_SET);
}
// Reset the counter of stored quotes
ticks_stored=0;
// Reading until the end of the file
while(FileIsEnding(file_handle)==false)
{
// Reading a string from thefile
file_buffer=FileReadString(file_handle);
// Processing of string if its length is larger than 6 characters
if(StringLen(file_buffer)>6)
{
// Finding the start position of Bid price in the line
BidPosition=StringFind(file_buffer," ",StringFind(file_buffer," ")+1)+1;
//Finding the start position of Ask price in the line
AskPosition=StringFind(file_buffer," ",BidPosition)+1;
// If the Bid prices are used, adding the Bid price to TicksBuffer[] array
if(applied_price==0) TicksBuffer[ticks_stored]=StringToDouble(StringSubstr(file_buffer,BidPosition,AskPosition-BidPosition-1));
// If the Ask prices are used, adding the Ask price to TicksBuffer[] array
if(applied_price==1) TicksBuffer[ticks_stored]=StringToDouble(StringSubstr(file_buffer,AskPosition));
// Increasing the counter of stored quotes
ticks_stored++;
}
}
}
// If the data have been read before
else
{
// Moving file pointer at the end of the file
FileSeek(file_handle,0,SEEK_END);
// Forming a string, that should be written to the file
StringConcatenate(file_buffer,TimeCurrent()," ",DoubleToString(last_price_bid,_Digits)," ",DoubleToString(last_price_ask,_Digits));
// Writing a string to the file
FileWrite(file_handle,file_buffer);
// If the Bid prices are used, adding the last Bid price to TicksBuffer[] array
if(applied_price==0) TicksBuffer[ticks_stored]=last_price_bid;
// If the Ask prices are used, adding the last Ask price to TicksBuffer[] array
if(applied_price==1) TicksBuffer[ticks_stored]=last_price_ask;
// Increasing the quotes counter
ticks_stored++;
}
// Closing the file
FileClose(file_handle);
// If number of quotes is more or equal than number of bars in the chart
if(ticks_stored>=rates_total)
{
// Removing the first tick_stored/2 quotes and shifting remaining quotes
for(i=ticks_stored/2;i<ticks_stored;i++)
{
// Shifting the data to the beginning in the TicksBuffer[] array on tick_stored/2
TicksBuffer[i-ticks_stored/2]=TicksBuffer[i];
}
// Changing the quotes counter
ticks_stored-=ticks_stored/2;
}
// We assign the CandleNumber with a number of invalid candle
CandleNumber=-1;
// Search for all the price data available for candle formation
for(i=0;i<ticks_stored;i++)
{
// If this candle is forming already
if(CandleNumber==(int)(MathFloor((ticks_stored-1)/ticks_in_candle)-MathFloor(i/ticks_in_candle)))
{
// The current quote is still closing price of the current candle
CloseBuffer[CandleNumber]=TicksBuffer[i];
// If the current price is greater than the highest price of the current candle, it will be a new highest price of the candle
if(TicksBuffer[i]>HighBuffer[CandleNumber]) HighBuffer[CandleNumber]=TicksBuffer[i];
// If the current price is lower than the lowest price of the current candle, it will be a new lowest price of the candle
if(TicksBuffer[i]<LowBuffer[CandleNumber]) LowBuffer[CandleNumber]=TicksBuffer[i];
// If the candle is bullish, it will have a color with index 2 (green)
if(CloseBuffer[CandleNumber]>OpenBuffer[CandleNumber]) ColorIndexBuffer[CandleNumber]=2;
// If the candle is bearish, it will have a color with index 1 (red)
if(CloseBuffer[CandleNumber]<OpenBuffer[CandleNumber]) ColorIndexBuffer[CandleNumber]=1;
// If the opening and closing prices are equal, then the candle will have a color with index 0 (grey)
if(CloseBuffer[CandleNumber]==OpenBuffer[CandleNumber]) ColorIndexBuffer[CandleNumber]=0;
}
// If this candle hasn't benn calculated yet
else
{
// Let's determine the index of a candle
CandleNumber=(int)(MathFloor((ticks_stored-1)/ticks_in_candle)-MathFloor(i/ticks_in_candle));
// The current quote will be the opening price of a candle
OpenBuffer[CandleNumber]=TicksBuffer[i];
// The current quote will be the highest price of a candle
HighBuffer[CandleNumber]=TicksBuffer[i];
// The current quote will be the lowest price of a candle
LowBuffer[CandleNumber]=TicksBuffer[i];
// The current quote will be the closing price of a candle
CloseBuffer[CandleNumber]=TicksBuffer[i];
// The candle will have a color with index 0 (gray)
ColorIndexBuffer[CandleNumber]=0;
}
}
// Return from OnCalculate(), return a value, different from zero
return(rates_total);
}
//+------------------------------------------------------------------+

Related

Google Apps Script: filter one 2D array based off the closest timestamp of another 2D array

I have two 2D-arrays; both of which contain a timestamp and a float-value. Array1 contains hundreds of timestamp-value pairs, while Array2 will generally only contain ~10 timestamp-value pairs.
I am trying to compare Array1 with Array2, and only want to keep Array1's timestamp-value pairings for the timestamps that are closest to the timestamps in Array2.
Array1 = {[59.696, 2020-12-30T00:00:00.000Z],
[61.381, 2020-12-30T00:15:00.000Z],
[59.25, 2020-12-30T00:30:00.000Z],
[57.313, 2020-12-30T00:45:00.000Z],...}
Array2 = {[78.210, 2020-12-30T00:06:00.000Z],
[116.32, 2020-12-30T00:39:00.000Z],...}
So in these Array examples above, I would want Array1 to be filtered down to:
Array1 = {[59.696, 2020-12-30T00:00:00.000Z],
[57.313, 2020-12-30T00:45:00.000Z],...}
because those timestamps are the closest match for timestamps in Array2.
I have tried implementing the suggested code from Find matches for two columns on two sheets google script but can't get it to work, and I can't otherwise find a neat solution for the timestamp matching.
Any help is much appreciated. Let me know if I need to edit or add to my question with more information.
The goal
Given two arrays:
Array1 = [
[59.696, "2020-12-30T00:00:00.000Z"],
[61.381, "2020-12-30T00:15:00.000Z"],
[59.25, "2020-12-30T00:30:00.000Z"],
[57.313, "2020-12-30T00:45:00.000Z"]
]
Array2 = [
[78.210, "2020-12-30T00:06:00.000Z"],
[116.32, "2020-12-30T00:39:00.000Z"]
]
The goal is for each item in Array2 to be matched with the closest date in Array1. So the resultant array of the above example would be 2 items. If Array2 had 100 items and Array1 had 1000, the resultant array would be of 100 items.
I am assuming that each item in Array1 can only be used once.
I am also assuming that the first item in the array, the float value, is to be ignored in the calculation, but kept together with the date and be included in the output.
The script
function filterClosestTimes(array1, array2) {
// Initializing "maps" to keep track of the differences
// closest, will contain the final pairs used
// differences, is used to decide which pair gets used
// positions used, is so that the same pair in array 1
// doesn't get used twice.
closest = []
differences = []
positionsUsed = []
// For each member of array2
array2.forEach((pair, i) => {
// Initializing a date object
targetDate = new Date(pair[1])
// Initializing the position of the current index in the
// tracking arrays.
closest.push(null)
differences.push(Infinity)
positionsUsed.push(null)
// Going through each member of array 1
array1.forEach((subpair, j) => {
// First checking if the position has already been used
if (positionsUsed.includes(j)) return
//initializing date
dateToTest= new Date(subpair[1])
// checking difference between the currently testing date
// of array 2
difference = Math.abs(targetDate - dateToTest)
// Checking if it is the date with the smallest difference
// if so, setting the position in the tracking arrays.
// These values will likely be overwritten many times until
// the date with the least difference is found.
if (differences[i] > difference) {
differences[i] = difference
closest[i] = subpair
positionsUsed[i] = j
}
})
})
return closest
}
function test(){
Logger.log(filterClosestTimes(Array1, Array2))
}
Running test returns:
[["59.696, 2020-12-30T00:00:00.000Z"], ["57.313, 2020-12-30T00:45:00.000Z"]]
Note
This algorithm, seeing as it involves checking every element of one array with almost every one in another array, can get slow. Though if you are only dealing with hundreds of values and comparing with ~10 in your Array2 then it will be fine. Just be aware that this approach has O(n^2) time complexity. Which will mean that as the number of comparisons go up, the time needed to complete the operation increases exponentially. If you try to compare tens of thousands with tens of thousands, then there will be a noticeable wait!
References
JS Date object
Time Complexity

read CSV file in Cplex

my question is related to my previous question. I should make some change in my code. I have a number of nodes between 1 to 100 in the CSV file. I create another CSV file and generate 20 random numbers between the 100 nodes and called them demand points. Each of this demand point has specific demands which are the randomly generate numbers between 1 to 10. I want to read this demand points(the indexes) and their weights. this is the first part of my question? how can I read this?
After that, I need to have a distance between each of these demand points and all nodes. I don't how can I just read the indexes of demand points and calculate the distance between them and all the nodes.
Based on the code that I provided, I need the indexes of demand points for a lot of places. My main problem is that I don't know how should I get these indexes in Cplex through the CSV file.
The demand points with their demands picture is:
first column is demandpointindex and second column in their demands
this file has 200 rows
I tried this code for reading the demand points:
tuple demands
{
int demandpoint;
int weight;
}
{demands} demand={};
execute
{
var f=new IloOplInputFile("weight.csv");
while (!f.eof)
{
var data = f.readline().split(",");
if (ar.length==2)
demand.add(Opl.intValue(ar[0]),Opl.intValue(ar[1]));
}
f.close();
}
execute
{
writeln(demand);
}
but it's not true.
int n=100;
int p=5;
tuple demands
{
int demandpointindex;
int weight;
}
{demands} demand={};
execute
{
var f=new IloOplInputFile("weight.csv");
while (!f.eof)
{
var data = f.readline().split(",");
if (ar.length==2)
demand.add(Opl.intValue(ar[0]),Opl.intValue(ar[1]));
}
f.close();
}
execute
{
writeln(demand);
}
float d[demandpointindexes][facilities];
execute {
var f = new IloOplInputFile("test1.csv");
while (!f.eof) {
var data = f.readline().split(",");
if (data.length == 3)
d[Opl.intValue(data[0])][Opl.intValue(data[1])] = Opl.floatValue(data[2]);
}
writeln(d);
}
dvar boolean x[demandpointindexe][facilities];
...
I hope I got your explanation right. Assume you have a file weight.csv like this:
1,2,
3,7,
4,9,
Here the first item in each row is the index of a demand point, the second item is its weight. Then you can parse this as before using this scripting block:
tuple demandpoint {
int index;
int weight;
}
{demandpoint} demand={};
execute {
var f = new IloOplInputFile("weight.csv");
while (!f.eof) {
var data = f.readline().split(",");
if (data.length == 3)
demand.add(Opl.intValue(data[0]), Opl.intValue(data[1]));
}
writeln(demand);
}
Next you can create a set that contains the indeces of all the demand points:
{int} demandpoints = { d.index | d in demand };
Assume file test1.csv looks like this
1,1,0,
1,2,5,
1,3,6,
1,4,7,
3,1,1,
3,2,1.5,
3,3,0,
3,4,3.5,
4,1,1,
4,2,1.5,
4,3,1.7,
4,4,0,
Here the first item is a demand point index, the second item is a facility index and the third item is the distance between first and second item. Note that there are no lines that start with 2 since there is no demand point with index 2 in weight.csv. Also note that I assume only 4 facilities here (to keep the file short). You can read the distance between demand points and facitilies as follows:
range facilities = 1..4;
float d[demandpoints][facilities];
execute {
var f = new IloOplInputFile("test1.csv");
while (!f.eof) {
var data = f.readline().split(",");
if (data.length == 4)
d[Opl.intValue(data[0])][Opl.intValue(data[1])] = Opl.floatValue(data[2]);
}
writeln(d);
}
The full script (including a dummy objective and constraints so that it can be run) looks:
tuple demandpoint {
int index;
int weight;
}
{demandpoint} demand={};
execute {
var f = new IloOplInputFile("weight.csv");
while (!f.eof) {
var data = f.readline().split(",");
if (data.length == 3)
demand.add(Opl.intValue(data[0]), Opl.intValue(data[1]));
}
writeln(demand);
}
// Create a set that contains all the indeces of demand points
// as read from weight.csv
{int} demandpoints = { d.index | d in demand };
range facilities = 1..4;
float d[demandpoints][facilities];
execute {
var f = new IloOplInputFile("test1.csv");
while (!f.eof) {
var data = f.readline().split(",");
if (data.length == 4)
d[Opl.intValue(data[0])][Opl.intValue(data[1])] = Opl.floatValue(data[2]);
}
writeln(d);
}
minimize 0;
subject to {}
It prints
{<1 2> <3 7> <4 9>}
[[0 5 6 7]
[1 1.5 0 3.5]
[1 1.5 1.7 0]]
Be careful about how many commas you have in your csv! The code posted above assumes that each line ends with a comma. That is, each line has as many commas as it has fields. If the last field is not terminated by a comma then you have to adapt the parser.
If you have in test1.csv the distance between all the nodes then it makes sense to first read the data into an array float distance[facilities][facilities]; and then define the array d based on that as
float d[i in demandpoints][j in facilities] = distance[i][j];
Update for the more detailed specification you gave in the comments:
In order to handle the test1.csv you explained in the comments you could define a new tuple:
tuple Distance {
int demandpoint;
int facility;
float distance;
}
{Distance} distances = {};
and read/parse this exactly as you did parse the weight.csv file (with one additional field, of course).
Then you can create the distance matrix like so:
float d[i in I][j in J] = sum (dist in distances : dist.demandpoint == i && dist.facility == j) dist.distance;
Here I and J are the sets or ranges of demand points and facilities, respectively. See above for how you can get a set of all demand points defined in the tuple set. The created matrix will have an entry for each demandpoint/distance pair. The trick in the definition d is that there are two cases:
If a pair (i,j) is defined in test1.csv then the sum will match exactly one element in distances: the one that defines the distance between two points.
If a pair (i,j) is not defined in test1.csv then the sum will not match anything and the corresponding entry in the distance matrix will thus be 0.

3D binary image to 3D mesh using itk

I'm trying to generate a 3d mesh using 3d RLE binary mask.
In itk, I find a class named itkBinaryMask3DMeshSource
it's based on MarchingCubes algorithm
some example, use this class, ExtractIsoSurface et ExtractIsoSurface
in my case, I have a rle 3D binary mask but represented in 1d vector format.
I'm writing a function for this task.
My function takes as parameters :
Inputs : crle 1d vector ( computed rle), dimension Int3
Output : coord + coord indices ( or generate a single file contain both of those array; and next I can use them to visualize the mesh )
as a first step, I decoded this computed rle.
next, I use imageIterator to create an image compatible to BinaryMask3DMeshSource.
I'm blocked, in the last step.
This is my code :
void GenerateMeshFromCrle(const std::vector<int>& crle, const Int3 & dim,
std::vector<float>* coords, std::vector<int>*coord_indices, int* nodes,
int* cells, const char* outputmeshfile) {
std::vector<int> mask(crle.back());
CrleDecode(crle, mask.data());
// here we define our itk Image type with a 3 dimension
using ImageType = itk::Image< unsigned char, 3 >;
ImageType::Pointer image = ImageType::New();
// an Image is defined by start index and size for each axes
// By default, we set the first start index from x=0,y=0,z=0
ImageType::IndexType start;
start[0] = 0; // first index on X
start[1] = 0; // first index on Y
start[2] = 0; // first index on Z
// until here, no problem
// We set the image size on x,y,z from the dim input parameters
// itk takes Z Y X
ImageType::SizeType size;
size[0] = dim.z; // size along X
size[1] = dim.y; // size along Y
size[2] = dim.x; // size along Z
ImageType::RegionType region;
region.SetSize(size);
region.SetIndex(start);
image->SetRegions(region);
image->Allocate();
// Set the pixels to value from rle
// This is a fast way
itk::ImageRegionIterator<ImageType> imageIterator(image, region);
int n = 0;
while (!imageIterator.IsAtEnd() && n < mask.size()) {
// Set the current pixel to the value from rle
imageIterator.Set(mask[n]);
++imageIterator;
++n;
}
// In this step, we launch itkBinaryMask3DMeshSource
using BinaryThresholdFilterType = itk::BinaryThresholdImageFilter< ImageType, ImageType >;
BinaryThresholdFilterType::Pointer threshold =
BinaryThresholdFilterType::New();
threshold->SetInput(image->GetOutput()); // here it's an error, since no GetOutput member for image
threshold->SetLowerThreshold(0);
threshold->SetUpperThreshold(1);
threshold->SetOutsideValue(0);
using MeshType = itk::Mesh< double, 3 >;
using FilterType = itk::BinaryMask3DMeshSource< ImageType, MeshType >;
FilterType::Pointer filter = FilterType::New();
filter->SetInput(threshold->GetOutput());
filter->SetObjectValue(1);
using WriterType = itk::MeshFileWriter< MeshType >;
WriterType::Pointer writer = WriterType::New();
writer->SetFileName(outputmeshfile);
writer->SetInput(filter->GetOutput());
}
any idea
I appreciate your time.
Since image is not a filter you can plug it in directly: threshold->SetInput(image);. At the end of this function, you also need writer->Update();. The rest looks good.
Side-note: it looks like you might benefit from usage of import filter instead of manually iterating the buffer and copying values one at a time.

Getting number of bytes of a bitmap

Goal is to show progress of jpeg encoding from bitmap. I have couple of bitmaps that need to be encoded. So I get the total number of bytes as was suggested here:
for (var i:int = 0; i < bitmaps.length; i++)
{
bmp = bitmaps[i];
total_bytes += bmp.getPixels(bmp.rect).length;
}
Then I'm trying to show progress when doing asychronous encoding. I get a ProgressEvent which gives me bytesLoaded. So I calculate the progress like so:
total_loaded_bytes += event.bytesLoaded;
var percentage:int = ((total_loaded_bytes / total_bytes) * 100);
However, total_bytes does not add up to total_loaded_bytes. Total bytes loaded is way highter.
A wrong approach to use bytesLoaded property. This is not to be blandly added up, as this contains the total of already loaded bytes bu the Loader object that issued the event. And a wrong approach on getting total bytes too, you need to use event.bytesTotal from within the progress event listener, since you are loading bytes, not pixels. Even if you are uploading. Also, the exact progress may be totally unavailable for asynchronous encoding, you are only displaying the uploading/downloading progress.
Update: to receive an accumulated progress, do something like this:
var loaders:Array=[]; // array of loaders. Fill manually
var progress:Array=[]; // fill with zeroes alongside loaders, should be same size
function updateProgress(e:ProgressEvent):void {
var loader:Loader=e.target as Loader;
if (!loader) return; // or skip type coercion, we just need the reference
var i:int=loaders.indexOf(loader); // now get an index from array
if (i<0) return; // not found, drop it
progress[i]=e.bytesLoaded; // and update progress array with new value
// now sum up progress array and divide by aggregated bytesTotal
// this one is up to you
}

How do I get the hexadecimal value from a Color object in Actionscript 3.0?

So I am making a music visualizer and I am trying to set the linestyle for my graphics to be a pre defined color! But I get an error when trying
var lineColor:Color = new Color(120,120,12);
graphics.lineStyle(lineThickness, lineColor);
1067: Implicit coercion of a value of type fl.motion:Color to an unrelated type uint.
So then I tried
var lineColor:Color = new Color(120,120,12);
graphics.lineStyle(lineThickness, lineColor.color);
But lineColor.color always returns 0! What do I do? I can't believe there is no built in API to take a color object and make it a compatible hexadecimal uint for graphics!
Any help would be much apprectiated!
Just use a method to return the hex value.
function get_uint_from_colour(red:int, green:int, blue:int) {
return red << 16 | green << 8 | blue;
}
So in your example:
graphics.lineStyle(lineThickness, get_uint_from_colour(120, 120, 12));
In response to your comment about needing to use a set of pre-defined Color objects, you will still need to (at some point) convert them to the type uint as this is the accepted data-type for the lineStyle method.
My suggestion would be to adjust the get_uint_from_colour method to accept a Color object. Like so:
function get_uint_from_colour(colour:Color) {
return int(colour.redMultiplier) << 16 | int(colour.greenMultiplier) << 8 | int(colour.blueMultiplier);
}
So in your code:
graphics.lineStyle(lineThickness, get_uint_from_colour(lineColor));
Please note that I have changed the name of my original method as I felt it better describes the function
Also, keep in mind that a Color object can hold much more information about itself than a standard Hex colour can - this superfluous information will be lost in the process of converting it.