Related
I have a problem when I'm trying to find a way to check if a trade was made on the current bar or not to stop the EA for making multiple entries on the same bar.
When I don't do a multi Currency EA I usually just use
static datetime lastTradeBar;
and
if(lastTradeBar!=Time[0])
{
if(PFTP_BuySignal > 0 && PFTP_BuySignal_Prev == 0 && PFTP_Rate > PFTP_Rate_Value)
{
myTP = PFTP_TP1;
mySL = PFTP_BuySL;
return (1);
}
if(PFTP_SellSignal > 0 && PFTP_SellSignal_Prev == 0 && PFTP_Rate > PFTP_Rate_Value)
{
myTP = PFTP_TP1;
mySL = PFTP_SellSL;
return (-1);
}
else
return (0);
lastTradeBar=Time[0];
};
return (0);
}
but this doesn't work when using it as I do now.
I'm thinking I need to make a myArray[sym,period,lastTradeBar] or myArray [sym][period][lastTradeBar]
but I can't wrap my head around how or where to put it.
this is the flow
int OnInit() ->
void OnTimer() ->
void LoopThruSym(stringlistOfSym) ->
void LoopThruPeriod(string sym, string listOfPeriods, int listOfSym) ->
void Trade(string sym, int period) ->
int Signal(string sym, int period)
This is how the flow is now.
int OnInit()
{
EventSetTimer(5);
return(INIT_SUCCEEDED);
}
....
void OnTimer()
{
LoopThruSym(symbols);
}
....
void LoopThruSym(string listOfSym)
{
if(Mode == All)
{
int i;
int numSymbolmarketWatch=SymbolsTotal(false);
numSymbols=numSymbolmarketWatch;
ArrayResize(symbolListFinal,numSymbolmarketWatch);
for(i=0; i<numSymbolmarketWatch; i++)
{
symbolListFinal[i]=SymbolName(i,false);
}
}
else
if(Mode == Selected)
{
string sep=",";
ushort u_sep;
int i;
u_sep=StringGetCharacter(sep,0);
StringSplit(listOfSym,u_sep,symbolList);
numSymbols=ArraySize(symbolList);
ArrayResize(symbolListFinal,numSymbols);
for(i=0; i<numSymbols; i++)
{
symbolListFinal[i]=symbolPrefix+symbolList[i]+symbolSuffix;
LoopThruPeriod(symbolListFinal[i],periods, numSymbols);
}
}
else
if(Mode == Current)
{
LoopThruPeriod(Symbol(),periods,numSymbols);
}
return;
}
....
void LoopThruPeriod(string sym, string listOfPeriods, int listOfSym)
{
if(ModePeriod == All_Period)
{
string periodsALL = "1,5,15,30,60,240,1440,10080,43200";
string sep=",";
ushort u_sep;
int i;
int lastTradeBarArrayCount;
u_sep=StringGetCharacter(sep,0);
StringSplit(periodsALL,u_sep,periodList);
numPeriods=ArraySize(periodList);
ArrayResize(periodListFinal,numPeriods);
lastTradeBarArrayCount = listOfSym+numPeriods;
ArrayResize(lastTradeBarArray,lastTradeBarArrayCount);
for(i=0; i<numPeriods; i++)
{
periodListFinal[i]=symbolPrefix+periodList[i]+symbolSuffix;
Trade(sym,StrToInteger(periodListFinal[i]));
Comment("lastTradeBarArrayCount = "+lastTradeBarArrayCount);
}
}
else
if(ModePeriod == Selected_Period)
{
string sep=",";
ushort u_sep;
int i;
int lastTradeBarArrayCount;
u_sep=StringGetCharacter(sep,0);
StringSplit(listOfPeriods,u_sep,periodList);
numPeriods=ArraySize(periodList);
ArrayResize(periodListFinal,numPeriods);
lastTradeBarArrayCount = listOfSym*numPeriods;
ArrayResize(lastTradeBarArray,lastTradeBarArrayCount);
for(i=0; i<numPeriods; i++)
{
periodListFinal[i]=symbolPrefix+periodList[i]+symbolSuffix;
Trade(sym,StrToInteger(periodListFinal[i]));
Comment("lastTradeBarArrayCount = "+lastTradeBarArrayCount);
}
}
if(ModePeriod == Current_Period)
{
Trade(sym,Period());
}
}
...
void Trade(string sym, int period)
{
//Print("Symbole = " + sym + " : " + period);
if(OrderMethod == BuyandSell)
{
if(Signal(sym,period) == 1 && CheckMoneyForTrade(sym,Lots,OP_BUY) && CheckVolumeValue(sym,Lots))
LimitBuy(sym,period);
else
if(Signal(sym,period) == -1 && CheckMoneyForTrade(sym,Lots,OP_SELL) && CheckVolumeValue(sym,Lots))
LimitSell(sym,period);
}
else
if(OrderMethod == BuyOnly)
{
if(Signal(sym,period) == 1 && CheckMoneyForTrade(sym,Lots,OP_BUY) && CheckVolumeValue(sym,Lots))
LimitBuy(sym,period);
}
else
if(OrderMethod == SellOnly)
{
if(Signal(sym,period) == -1 && CheckMoneyForTrade(sym,Lots,OP_SELL) && CheckVolumeValue(sym,Lots))
LimitSell(sym,period);
}
//Trail(sym);
return;
}
...
int Signal(string sym, int period)
{
if(lastTradeBar!=Time[0])
{
if(PFTP_BuySignal > 0 && PFTP_BuySignal_Prev == 0 && PFTP_Rate > PFTP_Rate_Value)
{
myTP = PFTP_TP1;
mySL = PFTP_BuySL;
return (1);
}
if(PFTP_SellSignal > 0 && PFTP_SellSignal_Prev == 0 && PFTP_Rate > PFTP_Rate_Value)
{
myTP = PFTP_TP1;
mySL = PFTP_SellSL;
return (-1);
}
else
return (0);
lastTradeBar=Time[0];
};
return (0);
}
Code a function on the "void OnTick()" like this:
void OnTick()
{
//---
CheckForSignal();
}
And then code the function "CheckForSignal()"
//+------------------------------------------------------------------+
//| Function "CheckForSignal()" |
//+------------------------------------------------------------------+
void CheckForSignal(){
//check here a bar until a Signal given Signal given then initialize it to Time[]
static datetime candletime=0;
if(candletime!=Time[0]){
double upArrow=iCustom(your Custom indicator or whatever parameters);
if(upArrow != EMPTY_VALUE){
EnterTrade(OP_BUY);
}
double downArrow=iCustom(your Custom indicator or whatever parameters);
if(downArrow != EMPTY_VALUE){
EnterTrade(OP_SELL);
}
// if we have a Signal we will initialize candle time to Time[0] to avoid multiple Orders
candletime=Time[0];
}
}
//+------------------------------------------------------------------+
Then Send Signal to Open or Close or whatever you need in my example we will open Trades
//+------------------------------------------------------------------+
//| Function "EnterTrade()" |
//+------------------------------------------------------------------+
void EnterTrade(int type){
int err=0;
double price=0;
double sl=0;
double tp=0;
if(type == OP_BUY){
price=Ask;
}else{
price=Bid;
}
//steppoin8-step15: replace function "OrderSend" parameter
// ->variablename "name" (magic)
//steppoint8-step16: end ";"
int ticket=OrderSend(Symbol(),type,LotSize,price,slippage,0,0,"EA Trade",magic,0,clrMagenta);
if(ticket>0){
if(OrderSelect(ticket,SELECT_BY_TICKET)){
if(OrderType()==OP_BUY){
sl=OrderOpenPrice()-(stopLoss*pips);
tp=OrderOpenPrice()+(takeProfit*pips);
}else if(OrderType()==OP_SELL){
sl= OrderOpenPrice()+(stopLoss*pips);
tp= OrderOpenPrice()-(takeProfit*pips);
}
if(!OrderModify(ticket,price,sl,tp,0,clrMagenta)){
err=GetLastError();
Print("Encountered an error during modification!"+(string)err+" "+ErrorDescription(err));
}
}else{
Print("Failed to Select Order",ticket);
err=GetLastError();
Print("Encountered an error while selecting order"+(string)ticket+" error number"+(string)err+" "+ErrorDescription(err));
}
}
else{
err=GetLastError();
Print("Encountered an error during order placement"+(string)err+" "+ErrorDescription(err));
}
}
//+------------------------------------------------------------------+
This is not an answer more of like progress.
So what i'm doing not instead of checking for candletime=Time[0] I check then the last trade close time is for that sym/magic nr and comment. and then runing it thru if(iBarShift(sym,period,OrderCloseTime()) > 1)
this kinda works but I'm getting problems down the road if I'm trying to use symbols with different miniLots. But that will come on another post.
bool getLastOrderClose(string sym, int period)
{
if(OrdersHistoryTotal() == 0)
return true;
string comment = "Multi Currency "+sym+":"+IntegerToString(period);
int count = 0;
int tradesPerSymbole =0;
for(int i=OrdersHistoryTotal()-1; i >= 0; i--)
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
{
if(OrderSymbol() == sym)
{
if(OrderMagicNumber() == Magic)
{
tradesPerSymbole++;
if(StringFind(comment,OrderComment())<0)
{
if(iBarShift(sym,period,OrderCloseTime()) > 1)
{
return true;
}
}
}
}
}
else
{
Print(sym +" : "+"OrderSend() - getLastOrderClose - error - ", ErrorDescription(GetLastError()));
}
if(tradesPerSymbole == 0)
return true;
return false;
};
//OrderSend('EURUSD',blablabla Parameter)
//OrderSend('GBPUSD',blablabla Parameter)
//OrderSend('USDJPY',blablabla Parameter)
//OrderSend('EURCHF',blablabla Parameter)
int ticket=OrderSend('EURUSD',type,LotSize,price,slippage,0,0,"EA Trade",magic,0,clrMagenta);
for(int I=ticket;ticket<Orderstotal();i++){
if(OrderSelect(ticket,SELECT_BY_TICKET)){
if(OrderType()==OP_BUY){
sl=OrderOpenPrice()-(stopLoss*pips);
tp=OrderOpenPrice()+(takeProfit*pips);
}else if(OrderType()==OP_SELL){
sl= OrderOpenPrice()+(stopLoss*pips);
tp= OrderOpenPrice()-(takeProfit*pips);
}
if(!OrderModify(ticket,price,sl,tp,0,clrMagenta)){
err=GetLastError();
Print("Encountered an error during modification!"+(string)err+" "+ErrorDescription(err));
}
}else{
Print("Failed to Select Order",ticket);
err=GetLastError();
Print("Encountered an error while selecting order"+(string)ticket+" error number"+(string)err+" "+ErrorDescription(err));
}
}
else{
err=GetLastError();
Print("Encountered an error during order placement"+(string)err+" "+ErrorDescription(err));
}
}
//+------------------------------------------------------------------+
I think its not the pro solution but I would declare a Ordersend function for all the pairs where u want to open the order (I need not to say that the order send function should be declared in a conditional so only the the real ordersend be placed)
but the part where I want your attention is you can do it the hardware by declaring the Ordersend(not with Symbol() instead of that with "YourPairname");
hope this help you a little bit to reach your goal gl
My code below places sell pending orders when certain candle patterns are met on the H_1 chart. But duplicate pending orders are created when I change the chart timeframe and return to H_1. Also old orders that should have hit stop loss or take profit seem to still be open.
I need to have multiple pending orders, but the duplicates and orders that should have closed are not wanted. How can I solve this?
string prefix = "HG";
const int N_bars = 1;
int numBars = 1;
int numBarsArray[];
int tempVal = 0;
int NumOfDisplayBars = 300;
int count = 0;
extern double lotSize = 0.01;
int magicnumber = 1337;
void showRectangles()
{
for (int i=NumOfDisplayBars;i>=1;i--)
{
if(isBearishEngulfing(i))
{
drawBearRectangle(i + 1,iHigh(_Symbol,0,i + 1),iOpen(_Symbol,0,i + 1));
}
}
}
bool isBearishEngulfing(int current)
{
if( (iClose(_Symbol,0,current ) < iOpen( _Symbol,0,current ))
&& (iClose(_Symbol,0,current + 1) > iOpen( _Symbol,0,current + 1))
&& (iOpen( _Symbol,0,current ) > iClose(_Symbol,0,current + 1))
&& (iClose(_Symbol,0,current ) < iOpen( _Symbol,0,current + 1))
)
return true;
return false;
}
bool drawBearRectangle(int candleInt,const double top,const double bottom)
{
const datetime starts = iTime(_Symbol,0,candleInt);
const datetime ends = starts+PeriodSeconds()*N_bars;
const string name = prefix+"_"+(candleInt>0?"DEMAND":"SUPPLY")+"_"+TimeToString(starts);
if(!ObjectCreate(0,name,OBJ_RECTANGLE,0,0,0,0,0))
{
printf("%i %s: failed to create %s. error=%d",__LINE__,__FILE__,name,_LastError);
return false;
}
ObjectSetInteger(0,name,OBJPROP_TIME1, starts);
ObjectSetInteger(0,name,OBJPROP_TIME2, ends);
ObjectSetDouble( 0,name,OBJPROP_PRICE1,bottom);
ObjectSetDouble( 0,name,OBJPROP_PRICE2,top);
ObjectSetInteger(0,name,OBJPROP_COLOR, clrChocolate);
ObjectSetInteger(0,name,OBJPROP_STYLE, STYLE_DASHDOT);
ObjectSetInteger(0,name,OBJPROP_WIDTH, 1);
ObjectSetInteger(0,name,OBJPROP_FILL, false);
if(_Period == 60){
double entryPrice=bottom-3*_Point;
double stopLoss=top;
double slDist=fabs(entryPrice-stopLoss);
double dTakeProfit=entryPrice-2*slDist;
int ticketSell = OrderSend(Symbol(),OP_SELLLIMIT,lotSize, entryPrice,0,stopLoss,dTakeProfit,"SellOrder",magicnumber,0,Red);
}
return true;
}
void OnDeinit(const int reason){ObjectsDeleteAll(0,prefix);}
void OnTick()
{
if(!isNewBar())
return; // not necessary but waste of time to check every second
showRectangles();
}
bool isNewBar()
{
static datetime lastbar;
datetime curbar = (datetime)SeriesInfoInteger(_Symbol,_Period,SERIES_LASTBAR_DATE);
if(lastbar != curbar)
{
lastbar = curbar;
return true;
}
return false;
}
Q : How can I solve the duplicates of pending order issues?... when I change the chart timeframe and return to H_1.
Well, this is rather a feature of the MQL4/5 code-execution ecosystem.
Solution:
Configure a preventive checkmark, setup in MT4-Terminal in Tools > Options > Expert Advisor-tab so as to become:
[x] Disable automated trading when the chart symbol or period has been changed
Thanks Daniel for your response, the code is in start(){...} as below.
I am a bit confused why it is not working.
Hope the details I have provided are enough :
int SYMBOL_NUMBER_LIMIT = 3;
int start()
{
string COUNTED_SYMBOLS[]; ArrayResize( COUNTED_SYMBOLS, SYMBOL_NUMBER_LIMIT, 0 );
for ( int s = 0; s < SYMBOL_NUMBER_LIMIT; s++ ) COUNTED_SYMBOLS[s] = "";
int SYMBOLS_IN_TRADE_SO_FAR = 0;
bool NEW_TRADE_PERMISSION = True;
int ALL_POSITIONS = OrdersTotal(); // PositionsTotal();
if ( ALL_POSITIONS > 0 )
{
for ( int index = 0; index < ALL_POSITIONS; index++ )
{
string THIS_SYMBOL = OrderSymbol(); // PositionGetSymbol( index );
bool Symbol_already_counted = False;
for ( int i = 0; i < SYMBOL_NUMBER_LIMIT; i++ )
{
if ( COUNTED_SYMBOLS[i] == THIS_SYMBOL )
{
Symbol_already_counted = True;
break;
}
if ( Symbol_already_counted ) continue;
else
{
SYMBOLS_IN_TRADE_SO_FAR++;
// if ( SYMBOLS_IN_TRADE_SO_FAR >= SYMBOL_NUMBER_LIMIT )
if ( SYMBOLS_IN_TRADE_SO_FAR == SYMBOL_NUMBER_LIMIT )
{
NEW_TRADE_PERMISSION = False;
break;
}
for ( int j = 0; j < SYMBOL_NUMBER_LIMIT; j++ )
if ( COUNTED_SYMBOLS[j] == "" )
{
COUNTED_SYMBOLS[j] = THIS_SYMBOL;
break;
}
}
}
}
}
input int SYMBOL_NUMBER_LIMIT;
int start(){
// some logic
int direction; string symbol;//these parameters to initialize to send a new trade
// some function to get a new direction and symbol
if(direction!=0 && symbol!=NULL){
bool allowSendNewTrade=isNewTradeAllowed(symbol);
if(allowSendNewTrade)OrderSend(symbol,lot,direction>0?OP_BUY:OP_SELL,0,0,0);
}
return(0);
}
bool isNewTradeAllowed(string symbolInQuestion){
string symbols[];
int SYMBOLS_IN_TRADE_SO_FAR=0;
ArrayResize(symbols,OrdersTotal());
for(int i=OrdersTotal()-1;i>=0;i--){
if(!OrderSelect(i,SELECT_BY_POS))continue;
string currentSymbol=OrderSymbol();
boolean symbolAlreadyInList=false;
for(int j=SYMBOLS_IN_TRADE_SO_FAR-1;j>=0;j--){
if(symbols[j]==currentSymbol){
symbolAlreadyInList=true;
break;
}
}
if(!symbolAlreadyInList)
symbols[SYMBOLS_IN_TRADE_SO_FAR++]=currentSymbol;
}
if(SYMBOLS_IN_TRADE_SO_FAR>SYMBOL_NUMBER_LIMIT)
return false;
if(SYMBOLS_IN_TRADE_SO_FAR==SYMBOL_NUMBER_LIMIT){
for(int j=SYMBOLS_IN_TRADE_SO_FAR-1;j>=0;j--){
if(symbols[SYMBOLS_IN_TRADE_SO_FAR]==symbolInQuestion)
return true;
}
return false;
}
return true; //SYMBOLS_IN_TRADE_SO_FAR<SYMBOL_NUMBER_LIMIT
}
Your code was missing the {...}-code-block syntax closing-bracket.
int SYMBOL_NUMBER_LIMIT = 3;
int start()
{
string COUNTED_SYMBOLS[]; ArrayResize( COUNTED_SYMBOLS, SYMBOL_NUMBER_LIMIT, 0 );
for ( int s = 0; s < SYMBOL_NUMBER_LIMIT; s++ ) COUNTED_SYMBOLS[s] = "";
int SYMBOLS_IN_TRADE_SO_FAR = 0;
bool NEW_TRADE_PERMISSION = True;
int ALL_POSITIONS = OrdersTotal(); // PositionsTotal();
if ( ALL_POSITIONS > 0 )
{
for ( int index = 0; index < ALL_POSITIONS; index++ )
{
string THIS_SYMBOL = OrderSymbol(); // PositionGetSymbol( index );
bool Symbol_already_counted = False;
for ( int i = 0; i < SYMBOL_NUMBER_LIMIT; i++ )
{
if ( COUNTED_SYMBOLS[i] == THIS_SYMBOL )
{
Symbol_already_counted = True;
break;
}
if ( Symbol_already_counted ) continue;
else
{
SYMBOLS_IN_TRADE_SO_FAR++;
// if ( SYMBOLS_IN_TRADE_SO_FAR >= SYMBOL_NUMBER_LIMIT )
if ( SYMBOLS_IN_TRADE_SO_FAR == SYMBOL_NUMBER_LIMIT )
{
NEW_TRADE_PERMISSION = False;
break;
}
for ( int j = 0; j < SYMBOL_NUMBER_LIMIT; j++ )
if ( COUNTED_SYMBOLS[j] == "" )
{
COUNTED_SYMBOLS[j] = THIS_SYMBOL;
break;
}
}
}
}
}
} // <-------------------------------------THIS ONE WAS MISSING, COMPILER WAS NOT HAPPY
I was working on a infix to postfix program(using stacks) but after all those efforts, something went wrong somewhere.I am getting the output as infix without conversion, please check if my intopost method is correct or not.
//stack class also containing the intopostfix method
import java.util.*;
public class Stack
{ int i,j;
char postfix[];
char stack[];
int top;
String post;
public Stack(int n)
{
stack=new char[n];
top=-1;
}
public void push(char item)
{
if(top>=stack.length)
System.out.println("Stack overflow");
else
{
stack[++top]=item;
}
}
public char pop()
{
if(top==-1)
{ System.out.println("Stack underflow");
return 0;
}
else
return stack[top--];
}
boolean isAlpha(char ch)
{
if((ch>='a'&&ch<='z')||(ch>=0&&ch<='9'))
return true;
else
return false;
}
boolean isOperator(char ch)
{
if(ch=='+'||ch=='-'||ch=='*'||ch=='/')
return true;
else return false;
}
void intopost(String str)
{
postfix=new char[str.length()];
char ch;
j=0;
for(i=0;i<str.length();i++)
{
ch=str.charAt(i);
if(ch=='(')
push(ch);
else if(isAlpha(ch))
{
postfix[j++]=ch;
}
else if(isOperator(ch))
{
push (ch);
}
else if(ch==')')
{
while((pop())!='(')
{
postfix[j++]=pop();
}
}
}
}
void disp()
{
for(i=0;i<postfix.length;i++)
{
System.out.print(postfix[i]);
}
}
}
at first change the following line
if((ch>='a'&&ch<='z')||(ch>=0&&ch<='9'))
into
if((ch>='a'&&ch<='z')||(ch>='0' &&ch<='9'))
And then
else if(ch==')')
{
while((pop())!='(')
{
postfix[j++]=pop();
}
}
here you are calling the pop function twice. this causes your stack to underflow.
that should be called once.
and finally try the following
void intopost(String str)
{
postfix=new char[str.length()];
char ch;
j=0;
for(i=0;i<str.length();i++)
{
ch=str.charAt(i);
if(ch=='(')
push(ch);
else if(isAlpha(ch))
{
postfix[j++]=ch;
}
else if(isOperator(ch))
{
push (ch);
}
else if(ch==')')
{
char c = pop();
while(c!='(')
{
postfix[j++]=c;
c= pop();
}
}
}
}
Following program would do the job for you
import java.io.*;
class stack
{
char stack1[]=new char[20];
int top;
void push(char ch)
{
top++;
stack1[top]=ch;
}
char pop()
{
char ch;
ch=stack1[top];
top--;
return ch;
}
int pre(char ch)
{
switch(ch)
{
case '-':return 1;
case '+':return 1;
case '*':return 2;
case '/':return 2;
}
return 0;
}
boolean operator(char ch)
{
if(ch=='/'||ch=='*'||ch=='+'||ch=='-')
return true;
else
return false;
}
boolean isAlpha(char ch)
{
if(ch>='a'&&ch<='z'||ch>='0'&&ch=='9')
return true;
else
return false;
}
void postfix(String str)
{
char output[]=new char[str.length()];
char ch;
int p=0,i;
for(i=0;i<str.length();i++)
{
ch=str.charAt(i);
if(ch=='(')
{
push(ch);
}
else if(isAlpha(ch))
{
output[p++]=ch;
}
else if(operator(ch))
{
if(stack1[top]==0||(pre(ch)>pre(stack1[top]))||stack1[top]=='(')
{
push(ch);
}
}
else if(pre(ch)<=pre(stack1[top]))
{
output[p++]=pop();
push(ch);
}
else if(ch=='(')
{
while((ch=pop())!='(')
{
output[p++]=ch;
}
}
}
while(top!=0)
{
output[p++]=pop();
}
for(int j=0;j<str.length();j++)
{
System.out.print(output[j]);
}
}
}
class intopost
{
public static void main(String[] args)throws Exception
{
String s;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
stack b=new stack();
System.out.println("Enter input string");
s=br.readLine();
System.out.println("Input String:"+s);
System.out.println("Output String:");
b.postfix(s);
}
}
Output:
Enter input string
a+b*c
Input String:a+b*c
Output String:
abc*+
Enter input string
a+(b*c)/d
Input String:a+(b*c)/d
Output String:
abc*d/)(+
public class InfixToPostfix
{
private Stack stack;
private String infix;
private String output = "";
public InfixToPostfix(String input)
{
infix = input;
stack = new Stack(infix.length());
}
public String convertInfixToPostfix()
{
for(int index=0; index < infix.length(); index++)
{
char itemRead = infix.charAt(index);
switch(itemRead)
{
case '+':
case '-':
processOperator(itemRead, 1);
break;
case '*':
case '/':
processOperator(itemRead, 2);
break;
case '(':
stack.push(itemRead);
break;
case ')':
popStackTillOpenParenthesis();
break;
default:
output = output + itemRead;
break;
}
}
while( !stack.isEmpty() )
{
output = output + stack.pop();
}
return output;
}
public void processOperator(char infixOperator, int precedence)
{
while( !stack.isEmpty() )
{
char popedOpr = stack.pop();
if( popedOpr == '(' )
{
stack.push(popedOpr);
break;
}
else
{
int popedOprPrecedence;
if(popedOpr == '+' || popedOpr == '-')
popedOprPrecedence = 1;
else
popedOprPrecedence = 2;
if(popedOprPrecedence < precedence)
{
stack.push(popedOpr);
break;
}
else
output = output + popedOpr;
}
}
stack.push(infixOperator);
}
public void popStackTillOpenParenthesis()
{
while(!stack.isEmpty())
{
char popedOpr = stack.pop();
if( popedOpr == '(' )
break;
else
output = output + popedOpr;
}
}
}
Explanation of postfix notation, with algorithm and example is present at: http://www.thinkscholar.com/java/java-topics/infix-to-postfix/
http://www.thinkscholar.com/java/java-topics/infix-to-postfix/
Try this code
/**
* Checks if the input is operator or not
* #param c input to be checked
* #return true if operator
*/
private boolean isOperator(char c){
if(c == '+' || c == '-' || c == '*' || c =='/' || c == '^')
return true;
return false;
}
/**
* Checks if c2 has same or higher precedence than c1
* #param c1 first operator
* #param c2 second operator
* #return true if c2 has same or higher precedence
*/
private boolean checkPrecedence(char c1, char c2){
if((c2 == '+' || c2 == '-') && (c1 == '+' || c1 == '-'))
return true;
else if((c2 == '*' || c2 == '/') && (c1 == '+' || c1 == '-' || c1 == '*' || c1 == '/'))
return true;
else if((c2 == '^') && (c1 == '+' || c1 == '-' || c1 == '*' || c1 == '/'))
return true;
else
return false;
}
/**
* Converts infix expression to postfix
* #param infix infix expression to be converted
* #return postfix expression
*/
public String convert(String infix){
String postfix = ""; //equivalent postfix is empty initially
Stack<Character> s = new Stack<>(); //stack to hold symbols
s.push('#'); //symbol to denote end of stack
for(int i = 0; i < infix.length(); i++){
char inputSymbol = infix.charAt(i); //symbol to be processed
if(isOperator(inputSymbol)){ //if a operator
//repeatedly pops if stack top has same or higher precedence
while(checkPrecedence(inputSymbol, s.peek()))
postfix += s.pop();
s.push(inputSymbol);
}
else if(inputSymbol == '(')
s.push(inputSymbol); //push if left parenthesis
else if(inputSymbol == ')'){
//repeatedly pops if right parenthesis until left parenthesis is found
while(s.peek() != '(')
postfix += s.pop();
s.pop();
}
else
postfix += inputSymbol;
}
//pops all elements of stack left
while(s.peek() != '#'){
postfix += s.pop();
}
return postfix;
}
This is taken from my blog here. Visit to get the complete code and see the each step of conversion in detail . Also note that here both parenthesis and exponent are also considered and can convert any expression.
try this code, more efficient as here i am not making use of lots of methods in this, just the main method.
package inn;
import com.sun.org.apache.bcel.internal.generic.GOTO;
import java.util.Scanner;
/**
*
* #author MADMEN
*/
public class Half_Life {
public Half_Life()
{
// a+b*c
// a*b+c
// d/e*c+2
// d/e*(c+2)
// (a+b)*(c-d)
// (a+b-c)*d/f
// (a+b)*c-(d-e)^(f+g)
// (4+8)*(6-5)/((3-2)*(2+2))
//(300+23)*(43-21)/(84+7) -> 300 23+43 21-*84 7+/
}
public static void main(String[] args)
{
System.out.print("\n Enter Expression : ");
Scanner c=new Scanner(System.in);
String exp=c.next();
int sym_top=0,po_top=-1,p=0,p2=0;
int size=exp.length();
char a[]=exp.toCharArray();
char symbols[]=new char[size];
char pfix[]=new char[size];
symbols[sym_top]='$';
for(int i=0;i<size;i++)
{
char c1=a[i];
if(c1==')')
{
while(sym_top!=0)
{
if(symbols[sym_top]=='(')
break;
pfix[++po_top]=symbols[sym_top--];
}
sym_top--;
}
else if(c1=='(')
{
symbols[++sym_top]=c1;
}
else if(c1=='+' || c1=='-' || c1=='*' || c1=='/' || c1=='^')
{
switch(c1)
{
case '+':
case '-': p=2;
break;
case '*':
case '/': p=4;
break;
case '^': p=5;
break;
default: p=0;
}
if(sym_top<1)
{
symbols[++sym_top]=c1;
}
else
{
do
{
char c2=symbols[sym_top];
if(c2=='^')
{
p2=5;
}
else if(c2=='*' || c2=='/')
{
p2=4;
}
else if(c2=='+' || c2=='-')
{
p2=2;
}
else
{
p2=1;
}
if(p2>=p)
{
pfix[++po_top]=symbols[sym_top--];
}
if(p>p2 || symbols[sym_top]=='$')
{
symbols[++sym_top]=c1;
break;
}
}while(sym_top!=-1);
}
}
else
{
pfix[++po_top]=c1;
}
}
for(;sym_top>0;sym_top--)
{
pfix[++po_top]=symbols[sym_top];
}
System.out.print("\n Infix to Postfix expression : ");
for(int j=0;j<=po_top;j++)
{
System.out.print(pfix[j]);
}
System.out.println("\n");
}
}
check the extreme last brace.
you can ask for more Data Structures programs at : sankie2902#gmail.com
Here is my navigationMovement():
protected boolean navigationMovement(int dx, int dy, int status, int time) {
int focusIndex = getFieldWithFocusIndex();
while (dy > 0) {
if (focusIndex >= getFieldCount()) {
return false;
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) {
f.setFocus();
dy--;
}
}
}
while (dy < 0) {
if (focusIndex < 0) {
return false;
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) {
f.setFocus();
dy++;
}
}
}
while (dx > 0) {
focusIndex++;
if (focusIndex >= getFieldCount()) {
return false;
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) {
f.setFocus();
dx--;
}
}
}
while (dx < 0) {
focusIndex--;
if (focusIndex < 0) {
return false;
} else {
Field f = getField(focusIndex);
if (f.isFocusable()) {
f.setFocus();
dx++;
}
}
}
return true;
}
This only allows the track wheel to scroll left and right, but I want up, down, left and right.
my layout is this.
It is a 3 rows x 4 columns.
This code is checking getField(0->10), that's why it cannot from 0 to 4.
I want it to be movable in all directions. How to implement that?
Updated
protected void sublayout(int width, int height) {
int y = 0;
Field[] fields = new Field[columnWidths.length];
int currentColumn = 0;
int rowHeight = 0;
for (int i = 0; i < getFieldCount(); i++) {
fields[currentColumn] = getField(i);
fields[currentColumn]
.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
final int focusIndex = getFieldWithFocusIndex();
if (focusIndex == position) {
Main.getUiApplication().popScreen(
mainscreen);
} else {
Main.getUiApplication().popScreen(
mainscreen);
Main.getUiApplication().pushScreen(
new Custom_LoadingScreen(1));
Main.getUiApplication().invokeLater(
new Runnable() {
public void run() {
if (focusIndex == 0)
Main.getUiApplication()
.pushScreen(
new Main_AllLatestNews());
else
Main.getUiApplication()
.pushScreen(
new Main_ParticularCategoryAllNews(
catnewsid[focusIndex],
focusIndex,
cattitle[focusIndex]));
}
}, 1 * 1000, false);
}
}
});
layoutChild(fields[currentColumn], columnWidths[currentColumn],
height - y);
if (fields[currentColumn].getHeight() > rowHeight) {
rowHeight = fields[currentColumn].getHeight() + 10;
}
currentColumn++;
if ((currentColumn == columnWidths.length)
|| (i == (getFieldCount() - 1))) {
int x = 0;
if (this.allRowHeight >= 0) {
rowHeight = this.allRowHeight;
}
for (int c = 0; c < currentColumn; c++) {
long fieldStyle = fields[c].getStyle();
int fieldXOffset = 0;
long fieldHalign = fieldStyle & Field.FIELD_HALIGN_MASK;
if (fieldHalign == Field.FIELD_RIGHT) {
fieldXOffset = columnWidths[c]
- fields[c].getWidth();
} else if (fieldHalign == Field.FIELD_HCENTER) {
fieldXOffset = (columnWidths[c] - fields[c]
.getWidth()) / 2;
}
int fieldYOffset = 0;
long fieldValign = fieldStyle & Field.FIELD_VALIGN_MASK;
if (fieldValign == Field.FIELD_BOTTOM) {
fieldYOffset = rowHeight - fields[c].getHeight();
} else if (fieldValign == Field.FIELD_VCENTER) {
fieldYOffset = (rowHeight - fields[c].getHeight()) / 2;
}
setPositionChild(fields[c], x + fieldXOffset, y
+ fieldYOffset);
x += columnWidths[c];
}
currentColumn = 0;
y += rowHeight;
}
if (y >= height) {
break;
}
}
int totalWidth = 0;
for (int i = 0; i < columnWidths.length; i++) {
totalWidth += columnWidths[i];
}
if (position > -1) {
Field f = getField(position);
f.setFocus();
}
setExtent(totalWidth, Math.min(y, height));
}
}
The issue with your code that you treat dx and dy in the same way. You need to calculate next previous index differently depends on if it's horizontal scroll or vertical.
Btw, what manager do you use? FlowFieldManager? Because I think it's should work as expected in default navigationMovement implementation.
navigationMovement default will provide focus on all focusable components.
It only matters what layout you have used & how did you arrange these managers. You have row, column wise structure, so if you used horizonal manager for a row, it's elements will get focus & after completing all elements, focus will be down to the second horizontal manager.
I just find the solution which is each move +/- column size
while (dy > 0) {
if (focusIndex + columnwidth.length >= getFieldCount()) {
return false;
} else {
Field f = getField(focusIndex + columnwidth.length);
if (f.isFocusable()) {
f.setFocus();
dy--;
}
}
}
while (dy < 0) {
if (focusIndex - columnwidth.length < 0) {
return false;
} else {
Field f = getField(focusIndex - columnwidth.length);
if (f.isFocusable()) {
f.setFocus();
dy++;
}
}
}