Order closing and opening very quickly unintendedly in MQL4 when using multiple criteria with 'OR' operator - algorithmic-trading

I am trying to close my trades based on 2 separate types of criteria,
Regardless of what the profit is, close the trade after 1020 seconds.
If my import value changes from -1 to 1 or vice versa, close it regardless of any other variables.
So far, my code works fine with 1 criteria, however when I add 2 if statements, MT4 does this thing where it opens and closes the trades very quickly, within every half a second, it doesn't look like its working properly.
If somebody could let me know what's making it do it, I would be grateful.
My code is below,
//Global Variables
//int Value = ReadCSVFile and get cell value(Either -1 or 1)
int Ticket;
int TicketBuy;
datetime SwitchBuy
datetime SwitchSell
void OnTick()
{
//Open Trades based on Value from CSV and if No other buy orders open
if(Value == 1){
if(getBuyOrderCount(Symbol(),magic) < 1){
Ticket == OrderSend(NULL,OP_BUY,0.01,Ask,2,0,0,NULL,magic,0,clrAliceBlue);
SwitchBuy = TimeCurrent();
}}
if(Value == (-1)){
if(SellOrderCount(Symbol(),magic) < 1){
TicketSell = OrderSend(NULL,OP_SELL,0.01,Bid,2,0,0,NULL,magic,0,clrAliceBlue);
SwitchSell = TimeCurrent();
}}
//Close Trades based on value in CSV file changing
if(Ticket > 0){
if(Value == (-1)||(TimeCurrent()>(SwitchBuy+60))){
CloseAllTradesBuy();
Ticket = 0;
Alert("Buy Trade Closed Because Probabilities Changed to -1!");
}
}
if(TicketSell > 0){
if(Value == 1||(TimeCurrent()>(SwitchBuy+60))){
CloseAllTradesSell();
TicketSell = 0;
Alert("Sell Trade Closed Because Probabilities Changed to 1!");
}
}
//Second Independent Criteria
if((SwitchBuy+1020) < TimeCurrent()){
if(OrderType() == OP_BUY){
CloseAllTradesBuy();
}
}
if((SwitchSell+1020) < TimeCurrent()){
if(OrderType() == OP_SELL){
CloseAllTradesSell();
}
}
}
//Functions to Close Trades
double CloseAllTradesBuy(){
for (int i =OrdersTotal(); i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS)==true)
if(OrderType()==OP_BUY)
if (OrderSymbol()==Symbol())
{
OrderClose(Ticket,OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),5,clrRed);
}
}
}
double CloseAllTradesSell(){
for (int i =OrdersTotal(); i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS)==true)
if(OrderType()==OP_SELL)
if (OrderSymbol()==Symbol())
{
OrderClose(TicketSell,OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),5,clrRed);
}
}
}

change this code of close orders :
//Functions to Close Trades
double CloseAllTradesBuy(){
for (int i =OrdersTotal()-1; i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS) && OrderType()==OP_BUY && OrderSymbol()==Symbol())
{
OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),5,clrRed);
}
}
}
double CloseAllTradesSell(){
for (int i =OrdersTotal()-1; i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS) && OrderType()==OP_SELL && OrderSymbol()==Symbol())
{
OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),5,clrRed);
}
}
}

Related

Adding a trailing Stop loss to an expert advisor using MQL5

Hi I'm new to MQL5 and I wanted to add a trailing stop loss to my expert advisor but some reason it does not add. Here is the code:
if(PositionSelect(_Symbol) && UseTrailingStop == true)
{
double TrailingStop = (atr[1] * 3) + close[1];
Trail.TrailingStop(_Symbol,TrailingStop,0,0);
}
Please note that close[1] is for the close price of the previous bar and atr[1] is for the value of the average true range. What am i doing wrong?????
There you go: hope this is helpful.
//--- trailing position
for(i=0;i<PositionsTotal();i++)
{
if(Symbol()==PositionGetSymbol(i))
{
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
{
sl=MathMax(PositionGetDouble(POSITION_PRICE_OPEN)+Spread*_Point,Bid-SL*_Point);
if(sl>PositionGetDouble(POSITION_SL) && (Bid-StopLevel*_Point-Spread*_Point)>PositionGetDouble(POSITION_PRICE_OPEN))
{
request.action = TRADE_ACTION_SLTP;
request.symbol = _Symbol;
request.sl = NormalizeDouble(sl,_Digits);
request.tp = PositionGetDouble(POSITION_TP);
OrderSend(request,result);
if(result.retcode==10009 || result.retcode==10008) // request executed
Print("Moving Stop Loss of Buy position #",request.order);
else
{
Print(ResultRetcodeDescription(result.retcode));
return;
}
return;
}
}
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
{
sl=MathMin(PositionGetDouble(POSITION_PRICE_OPEN)-Spread*_Point,Ask+SL*_Point);
if(sl<PositionGetDouble(POSITION_SL) && (PositionGetDouble(POSITION_PRICE_OPEN)-StopLevel*_Point-Spread*_Point)>Ask)
{
request.action = TRADE_ACTION_SLTP;
request.symbol = _Symbol;
request.sl = NormalizeDouble(sl,_Digits);
request.tp = PositionGetDouble(POSITION_TP);
OrderSend(request,result);
if(result.retcode==10009 || result.retcode==10008) // request executed
Print("Moving Stop Loss of Sell position #",request.order);
else
{
Print(ResultRetcodeDescription(result.retcode));
return;
}
return;
}
}
}
}

How to push the latest data entered based on conditions on Google AppScript?

Currently, the code below checks the if the data meets two criteria and then it's pushed into an array, but the need now is to get the latest data that meet those criteria.
The date's index within the dataset is [19] (20th column).
How would I go about tweaking it?
for (var i = 0; i < values.length; i++) {
if (values[i][0] == productCode && values[i][2] == productVersao) {
data.push(values[i]);
}
}
Thanks a lot in advance!
function themostrecent(values) {
values.sort(function(a,b){
var A=new Date(a[19]).valueOf();
var B=new Date(b[19]).valueOf();
return B-A;
});
for (var i = 0; i < values.length; i++) {
if (values[i][0] == productCode && values[i][2] == productVersao) {
data.push(values[i]);
break;
}
}
return data;
}

QLineEdit and QComboBox have unrelated behavior

I have a user interface with a lot of controls. However I have a problem with a QLineEdit and a QComboBox that are not responding properly.
I am basically converting from pixel measurements to millimeters/centimeters/decimeters and meters with a QComboBox and showing the result on a QLineEdit.
For the conversion table I used this page.
When I choose fromPixelToMillimeters() it does the conversion, but when I choose fromPixelToCentimeters() I think it is using the present value after the first conversion of fromPixelToMillimeters(). And if I go back choosing fromPixelToMillimeters() I get a different result too. This happens continuously, I get different measures each time.
See the code below:
void MainWindow::on_cBoxMeasures_currentIndexChanged(const QString &arg1)
{
if(arg1 == "Select Conversion(s)") {
return ui->leftLineEditDist->setText(QString("%1").arg(ui->leftLineEditDist->text().toDouble()));
} else if(arg1 == "pixel") {
return ui->leftLineEditDist->setText(QString("%1").arg(ui->leftLineEditDist->text().toDouble()));
} else if(arg1 == "mm") {
return fromPixelToMillimeters();
} else if(arg1 == "dm") {
return fromPixelToDecimeters();
} else if(arg1 == "cm") {
return fromPixelToCentimeters();
} else if(arg1 == "m") {
return fromPixelToMeters();
}
}
void MainWindow::fromPixelToMillimeters()
{
double mm = ui->leftLineEditDist->text().toDouble();
double dpi = 300;
double totalDistanceInMillimeter = (mm*25.4)/dpi;
ui->leftLineEditDist->setText(QString("%1").arg(totalDistanceInMillimeter));
ui->leftLineEditDist->show();
}
void MainWindow::fromPixelToCentimeters()
{
double mm = ui->leftLineEditDist->text().toDouble();
double dpi = 300;
double totalDistanceInCm = ((mm*25.4)/dpi)*0.1;
ui->leftLineEditDist->setText(QString("%1").arg(totalDistanceInCm));
ui->leftLineEditDist->show();
}
void MainWindow::fromPixelToDecimeters()
{
double mm = ui->leftLineEditDist->text().toDouble();
double dpi = 300;
double totalDistanceInDcm = ((mm*25.4)/dpi)*0.01;
ui->leftLineEditDist->setText(QString("%1").arg(totalDistanceInDcm));
ui->leftLineEditDist->show();
}
void MainWindow::fromPixelToMeters()
{
double mm = ui->leftLineEditDist->text().toDouble();
double dpi = 300;
double totalDistanceInM = ((mm*25.4)/dpi)*0.001;
ui->leftLineEditDist->setText(QString("%1").arg(totalDistanceInM));
ui->leftLineEditDist->show();
}
void MainWindow::on_cBoxMeasures_currentIndexChanged(int index)
{
switch (index) {
case(0):
break;
case(1):
break;
case(2):
fromPixelToMillimeters();
break;
case(3):
fromPixelToCentimeters();
break;
case(4):
fromPixelToDecimeters();
break;
case(5):
fromPixelToMeters();
break;
}
}
Please advise on what the problem might be.
I think these slots
on_cBoxMeasures_currentIndexChanged(const QString &arg1)
on_cBoxMeasures_currentIndexChanged(int index)
are connected the onIndexChange signal.
When the combo value will be changed, these two slots will be called simultaneously.
So that your code wont work well.
I recommend you to remove one of these slots.

How to correct loop counters for maze algorithm?

I have figured out how to move my character around the maze using the algorithm I have written, but the count is not figuring correctly. At the end of each row my character moves up and down several times until the count reaches the specified number to exit the loop, then the character moves along the next row down until it reaches the other side and repeats the moving up and down until the count reaches the specified number again. Can anyone help me find why my count keeps getting off? The algorithm and the maze class I am calling from is listed below.
public class P4 {
public static void main(String[] args) {
// Create maze
String fileName = args[3];
Maze maze = new Maze(fileName);
System.out.println("Maze name: " + fileName);
// Get dimensions
int mazeWidth = maze.getWidth();
int mazeHeight = maze.getHeight();
// Print maze size
System.out.println("Maze width: " + mazeWidth);
System.out.println("Maze height: " + mazeHeight);
int r = 0;
int c = 0;
// Move commands
while (true){
for (c = 0; c <= mazeWidth; c++){
if (maze.moveRight()){
maze.isDone();
c++;
}
if (maze.isDone() == true){
System.exit(1);
}
if (maze.moveRight() == false && c != mazeWidth){
maze.moveDown();
maze.moveRight();
maze.moveRight();
maze.moveUp();
c++;
}
}
for (r = 0; r % 2 == 0; r++){
maze.moveDown();
maze.isDone();
if (maze.isDone() == true){
System.exit(1);
}
}
for (c = mazeWidth; c >= 0; c--){
if (maze.moveLeft()){
c--;
maze.isDone();
System.out.println(c);
}
if (maze.isDone() == true){
System.exit(1);
}
if (maze.moveLeft() == false && c != 0){
maze.moveDown();
maze.moveLeft();
maze.moveLeft();
maze.moveUp();
c--;
}
}
for (r = 1; r % 2 != 0; r++){
maze.moveDown();
maze.isDone();
if (maze.isDone() == true){
System.exit(1);
}
}
}
}
}
public class Maze {
// Maze variables
private char mazeData[][];
private int mazeHeight, mazeWidth;
private int finalRow, finalCol;
int currRow;
private int currCol;
private int prevRow = -1;
private int prevCol = -1;
// User interface
private JFrame frame;
private JPanel panel;
private Image java, student, success, donotpass;
private ArrayList<JButton> buttons;
// Maze constructor
public Maze(String fileName) {
// Read maze
readMaze(fileName);
// Graphics setup
setupGraphics();
}
// Get height
public int getHeight() {
return mazeHeight;
}
// Get width
public int getWidth() {
return mazeWidth;
}
// Move right
public boolean moveRight() {
// Legal move?
if (currCol + 1 < mazeWidth) {
// Do not pass?
if (mazeData[currRow][currCol + 1] != 'D')
{
currCol++;
redraw(true);
return true;
}
}
return false;
}
// Move left
public boolean moveLeft() {
// Legal move?
if (currCol - 1 >= 0) {
// Do not pass?
if (mazeData[currRow][currCol - 1] != 'D')
{
currCol--;
redraw(true);
return true;
}
}
return false;
}
// Move up
public boolean moveUp() {
// Legal move?
if (currRow - 1 >= 0) {
// Do not pass?
if (mazeData[currRow - 1][currCol] != 'D')
{
currRow--;
redraw(true);
return true;
}
}
return false;
}
// Move down
public boolean moveDown() {
// Legal move?
if (currRow + 1 < mazeHeight) {
// Do not pass?
if (mazeData[currRow + 1][currCol] != 'D')
{
currRow++;
redraw(true);
return true;
}
}
return false;
}
public boolean isDone() {
// Maze solved?
if ((currRow == finalRow) && (currCol == finalCol))
return true;
else
return false;
}
private void redraw(boolean print) {
// Wait for awhile
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
if (print)
System.out.println("Moved to row " + currRow + ", column " + currCol);
// Compute index and remove icon
int index = (prevRow * mazeWidth) + prevCol;
if ((prevRow >= 0) && (prevCol >= 0)) {
buttons.get(index).setIcon(null);
}
// Compute index and add icon
index = (currRow * mazeWidth) + currCol;
if ((currRow == finalRow) && (currCol == finalCol))
buttons.get(index).setIcon(new ImageIcon(success));
else
buttons.get(index).setIcon(new ImageIcon(student));
// Store previous location
prevRow = currRow;
prevCol = currCol;
}
// Set button
private void setButton(JButton button, int row, int col) {
if (mazeData[row][col] == 'S') {
button.setIcon(new ImageIcon(student));
currRow = row;
currCol = col;
} else if (mazeData[row][col] == 'J') {
button.setIcon(new ImageIcon(java));
finalRow = row;
finalCol = col;
} else if (mazeData[row][col] == 'D') {
button.setIcon(new ImageIcon(donotpass));
}
}
// Read maze
private void readMaze(String filename) {
try {
// Open file
Scanner scan = new Scanner(new File(filename));
// Read numbers
mazeHeight = scan.nextInt();
mazeWidth = scan.nextInt();
// Allocate maze
mazeData = new char[mazeHeight][mazeWidth];
// Read maze
for (int row = 0; row < mazeHeight; row++) {
// Read line
String line = scan.next();
for (int col = 0; col < mazeWidth; col++) {
mazeData[row][col] = line.charAt(col);
}
}
// Close file
scan.close();
} catch (IOException e) {
System.out.println("Cannot read maze: " + filename);
System.exit(0);
}
}
// Setup graphics
private void setupGraphics() {
// Create grid
frame = new JFrame();
panel = new JPanel();
panel.setLayout(new GridLayout(mazeHeight, mazeWidth, 0, 0));
frame.add(Box.createRigidArea(new Dimension(0, 5)), BorderLayout.NORTH);
frame.add(panel, BorderLayout.CENTER);
// Look and feel
try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
// Configure window
frame.setSize(mazeWidth * 100, mazeHeight * 100);
frame.setTitle("Maze");
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setAlwaysOnTop(true);
// Load and scale images
ImageIcon icon0 = new ImageIcon("Java.jpg");
Image image0 = icon0.getImage();
java = image0.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
ImageIcon icon1 = new ImageIcon("Student.jpg");
Image image1 = icon1.getImage();
student = image1.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
ImageIcon icon2 = new ImageIcon("Success.jpg");
Image image2 = icon2.getImage();
success = image2.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
ImageIcon icon3 = new ImageIcon("DoNotPass.jpg");
Image image3 = icon3.getImage();
donotpass = image3.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
// Build panel of buttons
buttons = new ArrayList<JButton>();
for (int row = 0; row < mazeHeight; row++) {
for (int col = 0; col < mazeWidth; col++) {
// Initialize and add button
JButton button = new JButton();
Border border = new LineBorder(Color.darkGray, 4);
button.setOpaque(true);
button.setBackground(Color.gray);
button.setBorder(border);
setButton(button, row, col);
panel.add(button);
buttons.add(button);
}
}
// Show window
redraw(false);
frame.setVisible(true);
}
}
One error I can see in your code is that you're incrementing your c counter more often than you should. You start with it managed by your for loop, which means that it will be incremented (or decremented, for the leftward moving version) at the end of each pass through the loop. However, you also increment it an additional time in two of your if statements. That means that c might increase by two or three on a single pass through the loop, which is probably not what you intend.
Furthermore, the count doesn't necessarily have anything obvious to do with the number of moves you make. The loop code will always increase it by one, even if you're repeatedly trying to move through an impassible wall.
I don't really understand what your algorithm is supposed to be, so I don't have any detailed advice for how to fix your code.
One suggestion I have though is that you probably don't ever want to be calling methods on your Maze class without paying attention to their return values. You have a bunch of places where you call isDone but ignore the return value, which doesn't make any sense. Similarly, you should always be checking the return values from your moveX calls, to see if the move was successful or not. Otherwise you may just blunder around a bunch, without your code having any clue where you are in the maze.

X++ Coming Out Of QueryRun In Fetch Method

I can't seem to find the resolution for this. I have modified the Fetch method in a report, so that if the queryRun is changed, and the new ID is fetched, then the while loop starts over and a new page appears and 2 elements are executed. This part works fine, the next part does not, in each ID there are several Records which I am using Element.Execute(); and element.Send(); to process. What happens is, the first ID is selected, the element (body) of the reports is executed and the element is sent as expected, however the while loop does not go onto the next ID?
Here is the code;
public boolean fetch()
{
APMPriorityId oldVanId, newVanId;
LogisticsControlTable lLogisticsControlTable;
int64 cnt, counter;
;
queryRun = new QueryRun(this);
if (!queryRun.prompt() || !element.prompt())
{
return false;
}
while (queryRun.next())
{
if (queryRun.changed(tableNum(LogisticsControlTable)))
{
lLogisticsControlTable = queryRun.get(tableNum(LogisticsControlTable));
if (lLogisticsControlTable)
{
info(lLogisticsControlTable.APMPriorityId);
cnt = 0;
oldVanId = newVanId;
newVanId = lLogisticsControlTable.APMPriorityId;
if(newVanId)
{
element.newPage();
element.execute(1);
element.execute(2);
}
}
if (lLogisticsControlTable.APMPriorityId)
select count(recId) from lLogisticsControlTable where lLogisticsControlTable.APMPriorityId == newVanId;
counter = lLogisticsControlTable.RecId;
while select lLogisticsControlTable where lLogisticsControlTable.APMPriorityId == newVanId
{
cnt++;
if(lLogisticsControlTable.APMPriorityId == newVanId && cnt <= counter)
{
element.execute(3);
element.send(lLogisticsControlTable);
}
}
}
}
return true;
}
You are using lLogisticsControlTable as a target of both a queryRun.get() and a while select. However these two uses interfere; there are two SQL cursors to control.
Use two different record variables.

Resources