Sirs,
In connection with another problem, I am trying to create an array whose contents are the previous hourly closing values of the EURUSD. I have code as follows:
void Trade()
{
double longThresh = this.longThreshold;
double longTP = this.longTakeProfit;
double longSL = this.longStopLoss;
double shortThresh = this.shortThreshold;
double shortTP = this.shortTakeProfit;
double shortSL = this.shortStopLoss;
int dummyIndex = 0;
Print( "Triggered reload of stack data for trading routine" );
this.stackArray[0] = iClose( "EURUSD", PERIOD_H1, 1 );
this.stackArray[1] = iClose( "EURUSD", PERIOD_H1, 2 );
this.stackArray[2] = iClose( "EURUSD", PERIOD_H1, 3 );
this.stackArray[3] = iClose( "EURUSD", PERIOD_H1, 4 );
this.stackArray[4] = iClose( "EURUSD", PERIOD_H1, 5 );
this.stackArray[5] = iClose( "EURUSD", PERIOD_H1, 6 );
this.stackArray[6] = iClose( "EURUSD", PERIOD_H1, 7 );
this.stackArray[7] = iClose( "EURUSD", PERIOD_H1, 8 );
this.PrintStackArray();
}
The function above is actually an object method. The Object is instantiated, and a do-while loop causes the method above to be re-executed every hour at the five minute mark.
The problem is that when the code above executes an hour later, the PrintStackArray() output indicates that the iClose() function is not keeping up with new candlesticks every hour.
To put it another way, if the code were to execute at 5:05, it would give the same output as it would at 6:05, and in turn give identical output at 7:05.
I cannot for the life of me figure out why re-executing the iClose() functions does not update the array with the new candlestick values. Despite over two weeks of tinkering with this issue, I cannot force my EA to update and recognize new candlestick values.
This may happen uder such condition,that the code was being run without a live-feed of events from market, using just a localhost time-bound triggered Object method invocation ( which was not disclosed as an MCVE above ) thus forever showing the same time-series data head, which under such conditions simply get no live-feed updates, yielding the same [1,2,3,..] values forever:
if ( !IsConnected() )
{ Print( "No connection!" );
return( 0 );
}
may validate your EA state against a live server.
Related
I have a simple backtest of below EA:
void OnTick()
{
double rsi = iRSI( Symbol(), PERIOD_M5, 14, PRICE_CLOSE, 0 );
int day = TimeDay( TimeCurrent() );
int hour = TimeHour( TimeCurrent() );
int min = TimeMinute( TimeCurrent() );
if ( day == 7
&& hour >= 9
&& hour < 11
) {
Print( Symbol(), " / ", PERIOD_M5, " rsi: ", (string) rsi );
}
}
However, the backtest log seems does not match with show in the chart as this image:
http://i.imgur.com/PRhtvQD.png
Could you please give some explanation?
Q : "Could you please give some explanation?"
Sure, your code calculates & updates a printed RSI(14)-value (per-tick)
Kindly notice, that the previous bar 08:55 has finished with RSI(14)-value well above the HLINE ~ 30% (if in doubts, one can initially Print( iRSI( Symbol(), PERIOD_M5, 14, PRICE_CLOSE, 1 ) ); where you will see the "previous"-bar value numerically.
From about that value ( above ~ 30% ) the newly opened bar [0] will start to "develop" the actual RSI(14)-value, inside the new bar. So, initially, the values will "move" and the graph plots / redraws the line ( we can visualise each such change as a dot, marker or a Hi/Lo-range ), which is THE REASON, why we finally see a blue line fallen to the position, where the Close[0] has "finished" upon exiting of the bar under review (the 09:00 one, at about the 09:04:59:9999 time).
My question is in two closely related parts:
Given the entry price and stop loss, how can I calculate my lot size so that 2.5% of my current account balance would be risked on trades?
Also in cases where the 2.5% lot size is not a tradable lot size, say 0.013 and 0.018, how can I round the lot size already calculated in 1. to the closest tradable lot size 0.01 (for 0.013) and 0.02 (for 0.018)?
I know how to calculate the number of pips between my entry price and stop loss:
double DiffInPips = MathAbs(NormalizeDouble(stopLoss-openPrice,Digits)/Point);
I believe it is needed to solve this, but not sure how to arrive at the desired lot sizes in both of the above.
Calculating the risk-exposed part of your equity is a trivial but not on-topic here, so let me here focus on the programming, solving the item 2:
double NormalizeLotsToTRADE( const double aLotSizeREQUESTED ) // DEMO CODE
{
double aMinSIZE = MarketInfo( _Symbol, MODE_MINLOT ),
aMaxSIZE = MarketInfo( _Symbol, MODE_MAXLOT ),
aFixSTEP = MarketInfo( _Symbol, MODE_LOTSTEP );
return( MathMin( aMaxSIZE, // never > MAXLOT
MathMax( aMinSIZE, // never < MINLOT
( aMinSIZE // ~ min + steps
+ aFixSTEP * MathFloor( ( aLotSizeREQUESTED
- aMinSIZE
)
/ aFixSTEP
)
)
)
)
);
}
For a case your Risk-Manager is not so strict on your risk-modeling caveats and permit you to go into "closest" rounding, may use MathRound() instead of risk-management strict using of MathFloor().
I'm attempting to modify my market orders to breakeven the position when the position get 100 pips to the good. This also accounts for the StopLevels which are around 20-30 pips for my broker. It checks the param's via a "for(){...} loop" function
The MagicNumber is the timeframe number for the chart it is on (i.e. 240=4H, 60=1H) I don't set a TakeProfit price & initially no StopLoss price.
The EA is not adding a SL to be equal to the opening price when the trade reaches 100 pip in profit (plus stoplevels). Profit points reaches well over 130 points.
My code is below for a OP_SELL order - any help would be appreciated. Regards, Todd
/*Global Declarations*/
double pnlPoints;
double price, sl, tp;
double point;
int stopLevel;
int breakeven;
double newSL;
/*Local Declaratons*/
pnlPoints = 0;
point = MarketInfo( Symbol(), MODE_POINT );
stopLevel = int( MarketInfo( Symbol(), MODE_STOPLEVEL )
+ MarketInfo( Symbol(), MODE_SPREAD )
);
sl = NormalizeDouble( OrderStopLoss(), Digits );
tp = OrderTakeProfit();
breakeven = 100;
for( int s = OrdersTotal() - 1; s >= 0; s-- )
{ if ( ( OrderSelect( s, SELECT_BY_POS, MODE_TRADES ) ) == true )
price = MarketInfo( Symbol(), MODE_ASK );
newSL = NormalizeDouble( OrderOpenPrice(), Digits );
pnlPoints = ( OrderOpenPrice() - price ) / point;
if ( OP_SELL == OrderType() )
if ( Period() == OrderMagicNumber() )
if ( stopLevel < ( newSL - price ) / point )
if ( breakeven < pnlPoints )
if ( newSL != sl )
ModSell = OrderModify( OrderTicket(),
OrderOpenPrice(),
newSL,
tp,
buycolor
);
else if ( ModBuy == false )
{ Print( "OrderModify failed with error #",
GetLastError()
);
}
}
For the moment being,refine the codeandadd self-debuging / tracing code
After OrderModify() use a self-debugging / journaling Print( StringFormat( ... ) ) to document all instructed values used in the actual OrderModify() call and also the remote-execution ( { server-side | StrategyTester } ) reported issues.
The current code does not enter into such self-diagnostics and ModSell is not inspected at all, ModBuy is inspected only at uncertain conditions / by-coincidence at some future visit of the for(){...} code-execution path to a part after newSL == sl ( and all above stated conditions are just by chance met too )
Next, check an assigned value of tp
As stated above,
/*Local Declarations*/
...
tp = OrderTakeProfit();
which introduces a reasonable doubt, that re-using of this ( inherently uncertain value, as no one knows, which OrderSelect() was the last one that set a db.Pool pointer to decide, from which record from the db.Pool this veryOrderTakeProfit() would accidentally read ( if any record is present in db.Pool already ) inside the whole for(){...} traversing the db.Pool records will not meet conditions for setting properly a TakeProfit price in the next series of OrderModify() calls.
This seems to be the root cause, or a source of unhandled exceptions to the valid, Broker-compliant, OrderModify() values.
Try this:
if (newSL != sl ) {
ModSell = OrderModify( OrderTicket(),
OrderOpenPrice(),
OrderOpenPrice(),
0,
OrderExpiration(),
clrRed
);
if(ModBuy == false )
Print( "OrderModify failed with error #", GetLastError());
}
Then check the Expert-tab for error-message if it fails to set the stop.
Also, you need to take note that StopLoss will ONLY occur if you are on the right chart-timeframe; Otherwise, it won't even get into the if-statements.
I am totally drain out as the second if statement couldn't be executed.
My original idea was when volatility is in a range of 90 - 110, the program will send one and only one order. And it will wait and see till the volatility reaches in a range of 111 - 150, and then it will send the second order.
If I don't use a bool function here, the program will send countless order when the range is reached.
Could someone please help me?
if ( TodayMaxVolatilityPercentage >= 90.0
&& ( dayTrend == 1 )
&& orderOpened == false
)
{
Print( "Entered if clause" );
// Print( "Today volatility percentage is: ", TodayMaxVolatilityPercentage + "%" );
// ticket: Returns number of the ticket assigned to the order by the trade server or -1 if it fails.
ticket = OrderSend( Symbol(),
OP_SELL,
0.3,
Bid,
3,
0 * MyPoint,
30 * MyPoint,
NULL,
MagicNumber,
0,
Blue
);
Print( "Order is opened on", OrderOpenTime()+" at price: ", OrderOpenPrice() );
Print( "trend number is ",dayTrend );
if ( ticket > 0 )
{
if ( TakeProfit > 0 ) TheTakeProfit = Bid - TakeProfit * MyPoint;
OrderSelect( ticket, SELECT_BY_TICKET ); // bool value
/* OrderModify( OrderTicket(),
OrderOpenPrice(),
0,
NormalizeDouble( TheTakeProfit, Digits ),
0,
Green
);
*/
}
orderOpened = true;
if ( TodayMaxVolatilityPercentage >= 110.0 ) orderOpened = false;
}
if ( TodayMaxVolatilityPercentage >= 110.0
&& ( dayTrend == 1 )
&& orderOpened == false
)
{
Print( "Entered second if clause" );
// ticket: Returns number of the ticket assigned to the order by the trade server or -1 if it fails.
ticket = OrderSend( Symbol(),
OP_SELL,
0.3,
Bid,
3,
0 * MyPoint,
30 * MyPoint,
NULL,
MagicNumber,
0,
Blue
);
if ( ticket > 0 )
{
if ( TakeProfit > 0 ) TheTakeProfit = Bid - TakeProfit * MyPoint;
OrderSelect( ticket, SELECT_BY_TICKET ); // bool value
/* OrderModify( OrderTicket(),
OrderOpenPrice(),
0,
NormalizeDouble( TheTakeProfit, Digits ),
0,
Green
);
*/
}
orderOpened = true;
}
A hidden show-stopper:
By design, the first successful OrderSend() returns a value you assign into an ticket = OrderSend(...).
The devil is hidden in detail.
[MQL4-Help] says:
Returns number of the ticket assigned to the order by the trade server or -1 if it fails.
So the first successful OrderSend() ticket# returned is 0 ( in StrategyTester, a real MT4/Server rather runs into high numbers drawn from it's db.pool of tickets ).
Thus the second if ( ticket > 0 ) will never let you in.
It is common to rather use if ( ticket > EMPTY ) so as to also clarify the intention and use symbolic instead of a -1 integer constant.
First time post and I sincerely apologize if this has been answered in any other post but I have not been able to find a resolution for the problem I'm facing on this or any other site. I'm a new programmer self-teaching with web tutorials and any other resource I have found. I am trying to create code which will spawn characters and allow you to call them. I've had trouble assigning an index value to the individual instances I have created with a for function. I have tried to establish the instance as both a table and a group display object. If anyone is able to point me in the direction of any resources to get a more indepth understanding of tables and group display objects for the Corona SDK implementation of Lua I'm sure that my problem is that I don't have a thorough enough understanding of these particular functionalities and how they work. Here is the code I've written so far.
-- Character Game
require "sprite"
require "ui"
local background = display.newImage("Background Placeholder.png")
halfW = display.viewableContentWidth / 2
halfH = display.viewableContentHeight / 2
local numCharacters = 20
local roundedRect = display.newRoundedRect( 365, 20, 110, 40, 8 )
roundedRect:setFillColor( 0, 255, 0, 80 )
score = 0
t = ui.newLabel{ bounds = { 370, 30, 100, 40 },
text = "Score " .. score,
textColor = { 255, 0, 20, 255 },
size = 18,
align = "center"
}
local scoreboard = function ( event )
t:setText( "Score " .. score )
end
Runtime:addEventListener( "enterFrame", scoreboard )
local group = display.newGroup()
local character = sprite.newSpriteSheetFromData( "Character Placeholder.png", require("Character Placeholder").getSpriteSheetData() )
local characterSet1 = sprite.newSpriteSet(character,1,8)
sprite.add(characterSet1,"character",1,8,1500,0)
local characterplay = function( event )
score = score + group.points
group[i]:removeSelf()
end
do
for i=1, numCharacters do
group:insert(sprite.newSprite(characterSet1))
group[i].xScale = .2
group[i].yScale = .2
group.points = 50
group[i]:setReferencePoint ( display.BottomCenterReferencePoint )
group[i]:translate( halfW + math.random( -100, 100 ), halfH + math.random( -130, -110 ) )
end
timer.performWithDelay( 500, charactermovie )
for i=1, 21 do
timer.performWithDelay( math.random( 500, 5000 ) , charactermove )
charactermove = function(event )
transition.to( group[i], { time=10000, y = 580 } )
transition.to( group[i], { time=8000, x = math.random( 0, 480 ) } )
transition.to( group[i], { time=7000, xScale = 1.5} )
transition.to( group[i], { time=7000, yScale = 1.5} )
group[i]:prepare("character")
group[i]:play()
end
group[i]:addEventListener( "tap", characterplay )
end
end
charactermovie = function( event )
group[i]:prepare("character")
group[i]:play()
end
local function spriteListener( event )
print( "Sprite event: ", event.sprite, event.sprite.sequence, event.phase )
end
for i, group in pairs(group) do print (group, i, v) end
I'm currently getting an "attempt to index field '?' at the line containing this code "group[i]:addEventListener( "tap", zombieplay )" upon launch and a "nil key supplied for property lookup" error at the "group[i]:removeSelf()" line of the "zombieplay" function. I've tried moving the offending code to a variety of locations to see if this is a scoping issue but I largely run into the same error and believe I may not properly understand indexes and keys... I've found that the app functions as intended but I have to call index keys 1 through 21 to get them all to move even though I am only calling for 20 characters and the removeSelf line throwing errors is not removing the individual characters. I'm going to try writing a module for the characters and see if that helps clear any of this up. I will post my results shortly.
Your characterplay and charactermovie functions are trying to use the variable i, this is outside the functions scope.
There is a property of event called target, which is used to get the event callee. You want to do something like this:
local characterplay = function( event )
score = score + group.points
event.target:removeSelf()
end