MT4 Expert Advisor EA issue with updating price for offline chart - mql4

The following script uses a timer and works well in normal charts to comment current candle closing price every 1 second on chart. However, on offline chart, it only loads the closing price once and does not update it every second. Here is the code:
void OnTimer()
{
int m=TimeSeconds(TimeLocal());
double CloseValue = Close[0]; //Current Candle Close Value
string CloseValueString = DoubleToString(CloseValue,5); //Current price
Comment(
"Current value :",CloseValueString,"\n",
"Candle time :",m
);
}

Solved by adding the Refreshrates() function which updates data for the offline chart at the end of my function:
void OnTimer()
{
int m=TimeSeconds(TimeLocal());
double CloseValue = Close[0]; //Current Candle Close Value
string CloseValueString = DoubleToString(CloseValue,5); //Current price
Comment(
"Current value :",CloseValueString,"\n",
"Candle time :",m
);
RefreshRates();
}

Related

Using GSheets Script to increment value of duplicate by 1

I want to check a row for duplicates and if match increment these by 1.
The data I want to manipulate this way is LAT LONG Coordinates.
They originate from an aggregated data acquisition, where users can only insert country and city. Via an Add-On these will get GEO coded.
Problem is, that I need to slightly change the values of duplicate entries, in order to display them on a map. Easiest way (I think) is to increment a LAT or LONG coordinate by 1 if there is already an entry with the same value.
Data sample & results of script
Any idea how to do this via Script?
My code, originally intended to delete duplicate rows:
function overwriteDuplicates() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName("Formularantworten 2");
var vA=sh.getDataRange().getValues();
var hA=vA[0];
var hObj={};
hA.forEach(function(e,i){hObj[e]=i;});//header title to index
var uA=[];
var d=0;
for(var i=0;i<vA.length;i++) {
if(uA.indexOf(vA[i][hObj['Latitude']])==-1) {
uA.push(vA[i][hObj['Latitude']]);
}else{
function increment() {
SpreadsheetApp.getActiveSheet().getRange('K').setValue(SpreadsheetApp.getActiveSheet().getRange('K').getValue() + 1);
}
}}}
You want to modify the latitude whenever duplicate coordinates (latitude and longitude is found).
In this case, you can do the following:
Get all the values in the sheet, and retrieve the indexes where Latitude and Longitude are, based on the headers.
Loop through all rows (excluding headers), and for each row, check whether a previous row contains these coordinates.
If that's the case (isDuplicate), increment the last number in the latitude (after the last .), or decrement it if it's close to 999 (I assume there's always 3 digits).
Store the new latitude in an array after modification.
Use setValues to write the modified latitudes to the sheet.
Below is a possible code snippet to do this (see inline comments for details).
Code snippet:
function overwriteDuplicates() {
const ss = SpreadsheetApp.getActive();
const sheet = ss.getSheetByName("Formularantworten 2");
const values = sheet.getDataRange().getValues();
const headers = values.shift(); // Retrieve first row (headers)
const latColumn = headers.indexOf("Latitude"); // Latitude column index
const longColumn = headers.indexOf("Longitude"); // Longitude column index
let outputLocations = [];
for (let i = 0; i < values.length; i++) { // Loop through rows
const newLocation = { // Store object with current location
"latitude": values[i][latColumn],
"longitude": values[i][longColumn]
}
let isDuplicate;
do { // Check if location is duplicate, and increment if necessary
isDuplicate = outputLocations.some(location => {
const sameLatitude = location["latitude"] === newLocation["latitude"];
const sameLongitude = location["longitude"] === newLocation["longitude"];
return sameLatitude && sameLongitude;
});
if (isDuplicate) newLocation["latitude"] = modifyCoord(newLocation["latitude"]);
} while (isDuplicate);
outputLocations.push(newLocation); // Store new location in array
}
let outputLatitudes = outputLocations.map(location => [location["latitude"]]); // Retrieve latitudes from array
sheet.getRange(2, latColumn+1, sheet.getLastRow()-1).setValues(outputLatitudes); // Write updated latitudes to sheet
}
function modifyCoord(coordinates) {
let coordArray = coordinates.split(".");
let lastCoord = coordArray.pop();
if (lastCoord > 990) lastCoord--;
else lastCoord++;
coordArray.push(lastCoord);
return coordArray.join(".");
}
Output:

Flutter Timezone (as ZoneId)

I am relative new to Flutter. While I was experimenting, I came across with an issue. My REST Api takes a timezone parameter (Zone ID format such as Europe/London).
I saw both https://pub.dartlang.org/packages/flutter_native_timezone and https://pub.dartlang.org/packages/timezone, but neither of those serve my needs.
My goal is, when the user connect to the internet (without giving any location access to the app, if it is possible), get the timezone in ZoneId format and feed my back end in order to make the necessary date and time adjustments. Something similar to this
>>> var timezone = jstz.determine();
>>> timezone.name();
"Europe/London"
Presented in https://bitbucket.org/pellepim/jstimezonedetect
Any insights will be really helpful.
Thanks in advance
I've been also looking for this and here's what I found: https://pub.dev/packages/flutter_native_timezone
It a bit hacky under the hood, but it seems to work properly on both iOS and Android. Hope this will help someone in need.
Usage:
final String currentTimeZone = await FlutterNativeTimezone.getLocalTimezone();
print(currentTimeZone); // Europe/Moscow
Came up with a simple solution:
//server time(UTC)
String date_to_parse = "2019-06-23 12:59:43.444896+00:00";
DateTime server_datetime = DateTime.parse(date_to_parse);
//get current system local time
DateTime local_datetime = DateTime.now();
//get time diff
var timezoneOffset = local_datetime.timeZoneOffset;
var time_diff = new Duration(hours: timezoneOffset.inHours, minutes: timezoneOffset.inMinutes % 60);
//adjust the time diff
var new_local_time = server_datetime.add(time_diff);
After doing some digging, I found a (temporary) workaround to my issue.
Using
var now = new DateTime.now();
var timezoneOffset = now.timeZoneOffset;
I got the timezoneOffset in UTC format in flutter. Then send it to my back end as string (i.e. "-04") and drift my ZoneId properly.
Integer tzOffsetHour = Integer.valueOf(covertToTimezone);
ZoneOffset offset = ZoneOffset.ofHoursMinutes(tzOffsetHour, 0);
ZoneId zoneTZ = ZoneId.ofOffset("UTC", offset);
LocalDateTime localDateTimeClient = new Date().toInstant().atZone(zoneTZ).toLocalDateTime();
As a result I take the local time and date as stated in user's device, without using any location services, which was my goal from the beginning.
Until now, I have not faced any issues... we will see...
You can simply add .toLocal() to your DateTime object.
myDate = otherDate.toLocal();
myDate = DateTime.parse(json['server_date']).toLocal();
If you are just after the Time Zone offset. All you need is one line of code
int tzOffset = DateTime.now().timeZoneOffset.inHours;
The best way is to use timezone. as below
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
String getNameLocalTimeZone() {
tz.initializeTimeZones();
var locations = tz.timeZoneDatabase.locations;
int milliseconds=DateTime.now().timeZoneOffset.inMilliseconds;
String name = "";
locations.forEach((key, value) {
for (var element in value.zones) {
if (element.offset == milliseconds) {
name = value.name;
break;
}
}
});
return name;
}
DateTime.now().timeZoneOffset // +5:30:00.000000 is expected format

How to get price of Chart HLine objects and calculate Fibonacci levels

Three part question:
How to find 2 user created horizontal lines on a chart by name and return the price of each.
Then determine which HLine was crossed by the price most recently to determine trend direction.
Calculate Fibonacci levels based on prices and direction
double value = ObjectGetDouble(0,nameOfHLine,OBJPROP_PRICE1);
this is your value if you have name of the object, if you dont have it - need to loop over all objects:
string name;
for(int i=ObjectsTotal()-1;i>=0;i--){
name = ObjectName(i);
if(ObjectType(name)!=OBJ_HLINE) continue;
}
Working example of Fibonacci object that can be edited by the user and printing of fibonacci levels.
#include <ChartObjects/ChartObjectsFibo.mqh>
CChartObjectFibo *Fibo;
int OnInit()
{
Fibo = new CChartObjectFibo();
#Create object and set some defaults
if(!Fibo.Create(0,"Fibonacci",0,Time[5],Open[5],Time[0],Open[0]))
{
return(INIT_FAILED);
}
# Allow user to drag object
Fibo.Selectable(true);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
delete Fibo;
}
void OnTick()
{
string level_description;
double level_value;
string printString="Fibonacci Levels - ";
# Get the two anchor prices
double p1 = Fibo.GetDouble(OBJPROP_PRICE,0);
double p2 = Fibo.GetDouble(OBJPROP_PRICE,1);
# Calculate range
double range=MathAbs(p1-p2);
for(int i=0;i<Fibo.LevelsCount();i++)
{
level_description=Fibo.LevelDescription(i);
# Calculate price of level
level_value=(p2>p1)?p2-range*Fibo.LevelValue(i):p2+range*Fibo.LevelValue(i);
printString=StringFormat("%s %s:%.5f",printString,level_description,level_value);
}
Print(printString);
}
Difficult to understand exactly what you are after, not sure if you are trying to find the graphical objects or just calculate levels based on the prices. Assuming you have the price of the two horizontal lines, the following structure and function can be used to calculate Fibonacci levels. (price 1 is earlier in time than price 2).
Calculation based on formula found here
struct FibLevel {
double retrace38;
double retrace50;
double retrace61;
double extension61;
double extension100;
double extension138;
double extension161;
};
void FibLevel(double price1, double price2,FibLevel &fiblevel)
{
double range = MathAbs(price1-price2);
fiblevel.retrace38 =(price1<price2)?price2-range*0.382:price1+range*0.382;
fiblevel.retrace50 =(price1<price2)?price2-range*0.500:price1+range*0.500;
fiblevel.retrace61 =(price1<price2)?price2-range*0.618:price1+range*0.618;
fiblevel.extension61 =(price1<price2)?price2+range*0.618:price1-range*0.618;
fiblevel.extension100=(price1<price2)?price2+range :price1-range;
fiblevel.extension138=(price1<price2)?price2+range*1.382:price1-range*1.382;
fiblevel.extension161=(price1<price2)?price2+range*1.618:price1-range*1.618;
}

Unable to Select the month of a jquery datepicker using the Selenium

I am trying to select a custom date in the datepicker present in the jqueryui.com site, it is able to process the year , but the code that i written for the month is not working.Please find the code that i have used:-
private static void PickDate(WebDriver driver, String day, String mon, String year) throws Exception {
while (year != driver.findElement(By.cssSelector("span.ui-datepicker-year")).getText())
{
if (Integer.parseInt(year) < Integer.parseInt(driver.findElement(By.cssSelector("span.ui-datepicker-year")).getText()))
{
driver.findElement(By.cssSelector("a.ui-datepicker-prev")).click();
System.out.println(driver.findElement(By.cssSelector("span.ui-datepicker-month")).getText());
}
else if (Integer.parseInt(year) > Integer.parseInt(driver.findElement(By.cssSelector("span.ui-datepicker-year")).getText()))
{
driver.findElement(By.cssSelector("a.ui-datepicker-next")).click();
}
}
while (mon != (driver.findElement(By.cssSelector("span.ui-datepicker-month")).getText()))
{
if (driver.findElement(By.cssSelector("span.ui-datepicker-month")).getText() != "January")
{
driver.findElement(By.cssSelector("a.ui-datepicker-prev")).click();
}
if (mon != driver.findElement(By.cssSelector("span.ui-datepicker-month")).getText())
{
driver.findElement(By.cssSelector("a.ui-datepicker-next")).click();
}
}
If the purpose is to select a date in the datepicker, I would rather use execute script than click back and forth. :)
Something like:
((JavascriptExecutor) driver).ExecuteScript("$('#datepicker').datepicker('setDate', new Date(year, month, day))")
If you want to click on the previous/next button, then:
Because your code looks quite complicated, so I would like to provide another approach, which I believe that will be much simpler.
Notice that when you click on the previous/next button, it will move forward/backward by 1 month. So it's better if you firstly calculate how many months in difference between the date you want to select (month and year) and the current shown date on the DatePicker.
If you write in java, you can use something like:
YearMonth selectDate = YearMonth.of(year, month); // year, month are integer
int dp_Year = Integer.parseInt(driver.findElement(By.cssSelector("span.ui-datepicker-year")).getText());
int dp_Month = // convert it yourself
YearMonth dp_Date = YearMonth.of(dp_Year, dp_Month);
int month_diff = dp_Date.until(selectDate, ChronoUnit.MONTHS);
Based on month_diff and its sign (+ or -), you will know which button you need to click on and how many times.
I don't have java to try out, but I hope that the code above will work.

Not able to read the time from native calendar event

I have created a appoitment for particular date and time in Blackberry calendar,i am trying to read date and time using the following code,but its showing the error.
private void getEvents() {
try {
EventList eventList = (EventList)PIM.getInstance().openPIMList(PIM.EVENT_LIST, PIM.READ_ONLY);
Enumeration events = eventList.items();
while (events.hasMoreElements()) {
Event event = (Event)events.nextElement();
if(eventList.isSupportedField(Event.ALARM) && event.countValues(Event.ALARM) > 0) {
long alarm = event.getDate(Event.ALARM, 0);
System.out.println(alarm);
}
}
}
i am not sure what is wrong in if loop
The field Event.ALARM contains:
Field specifying a relative time for an Alarm for this Event. Data for
this field is expressed with an INT data type. The alarm is expressed
in seconds and derived by subtracting the alarm value from every
date/time occurrence of this Event. For example, if this field has a
value of 600, then the alarm first occurs 600 seconds before the
date/time value specified by Event.START. For re-occurrences of the
event, the alarm is calculated by subtracting the stored value from
the date/time of the specific event occurrence.
So you need to get the value from the field Event.START for the Date/Time of the Event start. You can then subtract the value of Event.ALARM (as seconds) from the start Date/Time to get the time for any requested reminder.
long start = event.getDate(Event.START);
int alarm = event.getDate(Event.ALARM);
if (alarm > 0) {
long reminderTime = start - (long)alarm * 1000L;
...
}
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy HH:mm");
String dateString = sdf.formatLocal(start);

Resources