//+------------------------------------------------------------------------------------------------------------------------------------------------------+
//| MarginTrader |
//| MarginTrader.mq4 (EA) |
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
#property version "1.704"
#property copyright "Copyright © 2019, MaryJane"
#property link "https://www.youtube.com/watch?v=KPOma7TiNlc"
#property icon "\\Images\\icon.ico"
#property description "A simple tool for margin level based trading."
#property strict
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
// --- RESOURCES: Images
#resource "\\Images\\mt.bmp"
#resource "\\Images\\dragon.bmp"
#resource "\\Images\\thinline.bmp"
#resource "\\Images\\h_mlimit.bmp"
#resource "\\Images\\h_mlevel.bmp"
#resource "\\Images\\h_manage.bmp"
#resource "\\Images\\h_trades.bmp"
#resource "\\Images\\h_account.bmp"
#resource "\\Images\\h_spread.bmp"
#resource "\\Images\\close_dis.bmp"
#resource "\\Images\\close_on.bmp"
#resource "\\Images\\close_off.bmp"
#resource "\\Images\\tpsl_dis.bmp"
#resource "\\Images\\sl_on.bmp"
#resource "\\Images\\sl_off.bmp"
#resource "\\Images\\tp_on.bmp"
#resource "\\Images\\tp_off.bmp"
#resource "\\Images\\speaker_on.bmp"
#resource "\\Images\\speaker_off.bmp"
#resource "\\Images\\buy_on.bmp"
#resource "\\Images\\buy_off.bmp"
#resource "\\Images\\buy_dis.bmp"
#resource "\\Images\\sell_on.bmp"
#resource "\\Images\\sell_off.bmp"
#resource "\\Images\\sell_dis.bmp"
#resource "\\Images\\buying.bmp"
#resource "\\Images\\selling.bmp"
#resource "\\Images\\chkbox_on.bmp"
#resource "\\Images\\chkbox_off.bmp"
#resource "\\Images\\arrup_on.bmp"
#resource "\\Images\\arrup_off.bmp"
#resource "\\Images\\arrup_dis.bmp"
#resource "\\Images\\arrdn_on.bmp"
#resource "\\Images\\arrdn_off.bmp"
#resource "\\Images\\arrdn_dis.bmp"
#resource "\\Images\\pend_on.bmp"
#resource "\\Images\\pend_off.bmp"
// --- RESOURCES: Sounds
#resource "\\Sounds\\button.wav"
#resource "\\Sounds\\click.wav"
#resource "\\Sounds\\closing.wav"
#resource "\\Sounds\\coin.wav"
#resource "\\Sounds\\counting.wav"
#resource "\\Sounds\\stops_set.wav"
#resource "\\Sounds\\targets_set.wav"
//------------------------------------------------------------------------------------------------------------------------------------------+
enum yesno
{
NO = 0,
YES = 1
};
// Mic v1.702 define for pending order routine
#define HOOK_NONE 0
#define HOOK_BUY 1
#define HOOK_SELL 2
// --- LIBRARIES
#include <MT_functions.mqh>
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
// --- USER VARIABLES
#define INPUT input
INPUT yesno CloseAllOnBalanceChange = NO; // Close all trades on balance change?
INPUT yesno OnlyManageOwnTrades = NO; // Manage only own trades?
INPUT yesno DisableOneClick = YES; // Disable MT4 One Click Trading panel?
INPUT yesno ForceOnTick = NO; // Force OnTick() mode instead of OnTimer()
INPUT yesno PendingConfirm = YES; // Confirm Pending Order?
INPUT int PendingReturnSpeed = 16; // Pending Mark Return Speed
INPUT double PendingSL = 0.0; // Pending Stop Loss (Pips)
INPUT double PendingTP = 0.0; // Pending Take Profit (Pips)
INPUT int MagicNumber = 32768; // Magic number
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
// --- COMMON VARIABLES
int Second, OldSecond, Total, MarginLimit, Lp,
MaxMarginLimit = 9900,
TradeMode = TRADE_NONE,
LineMode = LINE_INVALID,
Error = ERR_NO_MESSAGE_YET,
PriceLineWidth = 2,
PriceLineStyle = STYLE_SOLID,
panelBkg_add,
hook = HOOK_NONE; // Mic v1.702 for Pending routine
char fs;
double MLPadding = 2.0,
Pt, tickvalue, Spread, Fmp, Stop, Target, AvailLots, AddLots, Sl, Tp, PnL, Sym, MinPip,
StopAddingPips, SpreadAverage, SpreadHistory[100],
DPIScaling;
string _A, _F, _gSbalance, _gSoundsOn, _gAutoAdd, _gMarginLimit, _gIsTrading, _gErrorCode, _gErrorTime;
long CID, SpreadHistoryCount;
bool FirstRun, OldSoundsOn, OldAutoAdd, MousePressed, MouseClick, MouseRelease;
color BackgroundColor = C'25,24,24';
color NeutralColor = C'240,240,240';
color PositiveColor = clrLime;
color NegativeColor = clrOrangeRed;
color LabelColor = clrDarkGray;
color PendingColorSell = clrRed; // Mic v1.703
color PendingColorBuy = C'0,150,220'; // Mic v1.703
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
// --- CODE
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
int OnInit () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Runs on EA initialization. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// If EA called from Template, template set all object, delete all object
if(ObjectFind(0, _PDRAGON) >= 0)
ObjectsDeleteAll(CID, _ID);
DefineGlobals();
// Pips divider
if (Digits == 1 || Digits == 3 || Digits == 5 || (Digits == 2 && StringFind(_Symbol, "XAU") != -1)) {
Pt = _Point * 10.0;
MinPip = 0.1;
}
else {
Pt = _Point;
MinPip = 1.0;
}
// Lot precision
Lp = 1;
if (MarketInfo(_Symbol, MODE_LOTSTEP) == 0.01) Lp = 2;
if (MarketInfo(_Symbol, MODE_LOTSTEP) == 1.00) Lp = 0;
// Chart ID
CID = ChartID();
// Account currency
_A = AccountCurrencySymbol();
// Numerical representation of current symbol
Sym = EncodeSymbol();
// Terminal DPI scaling
int desktopScreenDPI = TerminalInfoInteger( TERMINAL_SCREEN_DPI );
DPIScaling = desktopScreenDPI > 96.0 ? desktopScreenDPI / 96.0 : 1.0;
// We're running for the first time
FirstRun = true;
EventSetMillisecondTimer(200);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnDeinit (const int Reason) {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Runs on EA deinitialization. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
ObjectsDeleteAll(CID, _ID);
EventKillTimer();
Comment("");
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnTick () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Runs on every incoming tick. Mandatory for strategy tester. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
if(IsTesting() || ForceOnTick) Run();
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnTimer () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Runs on timer event, standard is 200ms. Better for realtime use. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
if(!IsTesting() && !ForceOnTick) Run();
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnChartEvent (const int id,
const long& lparam,
const double& dparam,
const string& sparam) {
static bool MouseOld = false;
static int x=0;
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Mandatory for UI, monitors mouse buttons. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
if(id == CHARTEVENT_MOUSE_MOVE) {
if(uint(sparam) == 1) MousePressed = true;
else MousePressed = false;
// Mic v1.70 Added Pending order
int curX = (int)ObjectGetInteger(0,_LAB61,OBJPROP_XDISTANCE);
int curY = (int)ObjectGetInteger(0,_LAB61,OBJPROP_YDISTANCE);
int bx,by,bl,bw;
if(DPIScaling != 1.0) {
bx = (int)(80*DPIScaling); by = (int)(111*DPIScaling); bl = (int)(146*DPIScaling); bw = (int)(20*DPIScaling); // Started cordinate for PendingLabel (center of object)
} else {
bx = 80; by = 111; bl = 146; bw = 20; // Started cordinate for PendingLabel (center of object)
}
double price=0;
static string strade = "";
datetime tm; // not used
int sw; // not used
if(ChartXYToTimePrice(0, curX, curY+2, sw, tm, price))
price = NormalizeDouble(price, Digits);
int al = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
// Mic v1.704 Disable/enable moving trade level when mouse is over MT panel or trade is open
if(TradeMode == TRADE_BUY || TradeMode == TRADE_SELL) {
if(ChartGetInteger(CID, CHART_DRAG_TRADE_LEVELS))
ChartSetInteger(CID, CHART_DRAG_TRADE_LEVELS, false);
}
else {
if(lparam >= (al - (int)(160*DPIScaling))) { // On MT panel
if(ChartGetInteger(CID, CHART_DRAG_TRADE_LEVELS))
ChartSetInteger(CID, CHART_DRAG_TRADE_LEVELS, false);
}
else { // left from MT panel
if(!ChartGetInteger(CID, CHART_DRAG_TRADE_LEVELS))
ChartSetInteger(CID, CHART_DRAG_TRADE_LEVELS, true); // Moving pending stops and targets
}
}
if(MousePressed && !MouseOld) { // first mouse press
// if klik on object, hook and start move
int hl = bl/2;
int cxb = al - bx - hl;
int cxs = cxb + hl;
int cy = by - bw/2;
if((lparam >= cxb && lparam <= cxb+hl) && ((int)dparam >= cy && (int)dparam <= cy+bw)) { // if click inside button sell region
hook = HOOK_SELL; strade = "SELL";
ObjectSetInteger(CID, _PENDING, OBJPROP_STATE, true);
ObjectSetInteger(CID,_LAB61, OBJPROP_COLOR, PendingColorSell);
Click();
}
else if((lparam >= cxs && lparam <= cxs+hl) && ((int)dparam >= cy && (int)dparam <= cy+bw)) { // if click inside button buy region
hook = HOOK_BUY; strade = "BUY";
ObjectSetInteger(0, _PENDING, OBJPROP_STATE, true);
ObjectSetInteger(CID,_LAB61, OBJPROP_COLOR, PendingColorBuy);
Click();
}
}
else if(!MousePressed && MouseOld) { // first mouse release
//if object hooked, release, put pending and return object to start
if(hook == HOOK_BUY || hook == HOOK_SELL) {
ObjectSetInteger(0, _PENDING, OBJPROP_STATE, true);
ObjectSetInteger(CID, _LAB61, OBJPROP_SELECTABLE, false);
ObjectSetInteger(CID, _LAB61, OBJPROP_SELECTED, false);
ChartRedraw();
if(curX > bx+bl/2 && (price > Ask+Pt || price < Bid-Pt)) { // If mooved left from button and price not inside spread
string warn = "";
bool is_warn = false;
// Warning if You place counter Order
if((TradeMode == TRADE_BUY && hook == HOOK_SELL) || (TradeMode == TRADE_SELL && hook == HOOK_BUY)) {
if(SoundsOn()) PlaySound("alert2.wav");
warn = "WARNING! HEDGE TRADING!\nYou tried to place a "+strade+" pending order!\n\n";
is_warn = true;
}
else {
if(SoundsOn()) PlaySound("::Sounds\\button.wav");
}
if((!PendingConfirm && !is_warn) || MessageBox(warn+"Are you sure you want to place a "+strade+" pending order?", "Pending Order", MB_YESNO) == IDYES) {
// Set pending order Order
bool trade = true;
int ticket;
double slp = 0.0;
double tpp = 0.0;
double volume = MarketInfo(_Symbol, MODE_MINLOT);
if(TradeMode != TRADE_BUY && TradeMode != TRADE_SELL) {
volume = MathMax(AvailLots, volume); // if no trades, size = AvailLots else size = MINLOT
trade = false;
}
if(hook == HOOK_BUY) {
if(!trade) { // if no open trades, set sl/tp
if(PendingSL>=MinPip) slp = NormalizeDouble(price - PendingSL * Pt, Digits);
if(PendingTP>=MinPip) tpp = NormalizeDouble(price + PendingTP * Pt, Digits);
}
if(price > Ask) {
ticket = OrderSendReliable(_Symbol, OP_BUYSTOP, volume, price, 0, slp, tpp, NULL, MagicNumber);
if(SoundsOn()) {if (ticket > 0) PlaySound("ok.wav"); else PlaySound("timeout.wav");}
}
else if(price < Bid) {
ticket = OrderSendReliable(_Symbol, OP_BUYLIMIT, volume, price, 0, slp, tpp, NULL, MagicNumber);
if(SoundsOn()) {if (ticket > 0) PlaySound("ok.wav"); else PlaySound("timeout.wav");}
}
}
else if(hook == HOOK_SELL) {
if(!trade) { // if no open trades, set sl/tp
if(PendingSL>=MinPip) slp = NormalizeDouble(price + PendingSL * Pt, Digits);
if(PendingTP>=MinPip) tpp = NormalizeDouble(price - PendingTP * Pt, Digits);
}
if(price > Ask) {
ticket = OrderSendReliable(_Symbol, OP_SELLLIMIT, volume, price, 0, slp, tpp, NULL, MagicNumber);
if(SoundsOn()) {if (ticket > 0) PlaySound("ok.wav"); else PlaySound("timeout.wav");}
}
else if(price < Bid) {
ticket = OrderSendReliable(_Symbol, OP_SELLSTOP, volume, price, 0, slp, tpp, NULL, MagicNumber);
if(SoundsOn()) {if (ticket > 0) PlaySound("ok.wav"); else PlaySound("timeout.wav");}
}
}
}
}
// animated return label to pending button
if(curX > bx*2) {
ReturnMove(bx+(int)(220*DPIScaling), by, 4, PendingReturnSpeed); // Speed ms, pixel step
ReturnMove(bx-(int)(20*DPIScaling), by, 4, PendingReturnSpeed/4); // Speed ms, pixel step
}
else
ReturnMove(bx-(int)(20*DPIScaling), by, 4, PendingReturnSpeed); // Speed ms, pixel step
ObjectSetString(CID,_LAB61,OBJPROP_TEXT,"–––– Pending ––––"); // this string must be dimension like pending button
ObjectSetInteger(CID,_LAB61, OBJPROP_COLOR, clrNONE); // Invisible
ChartRedraw();
//Click();
} // end if hook
hook = HOOK_NONE;
strade = "";
} // end mouse release
if(hook == HOOK_BUY) {
if(price > Ask+Pt)
ObjectSetString(CID,_LAB61,OBJPROP_TEXT,"––––––––––––– Buy Stop –––––––––––––");
else if(price < Bid-Pt)
ObjectSetString(CID,_LAB61,OBJPROP_TEXT,"––––––––––––– Buy Limit ––––––––––––");
else
ObjectSetString(CID,_LAB61,OBJPROP_TEXT,"–––––– NO ORDER ––––––");
ChartRedraw();
}
else if(hook == HOOK_SELL) {
if(price > Ask+Pt)
ObjectSetString(CID,_LAB61,OBJPROP_TEXT,"––––––––––––– Sell Limit ––––––––––––");
else if(price < Bid-Pt)
ObjectSetString(CID,_LAB61,OBJPROP_TEXT,"––––––––––––– Sell Stop –––––––––––––");
else
ObjectSetString(CID,_LAB61,OBJPROP_TEXT,"–––––– NO ORDER ––––––");
ChartRedraw();
}
else {
int hl = bl/2;
int cxb = al - bx - hl;
int cxs = cxb + hl;
int cy = by - bw/2;
int oy = (int)ObjectGetInteger(0,_LAB61,OBJPROP_YDISTANCE);
// in some situation like double click, label deselect and button state is change, we correct that here.
// if we continualy set object parameter when mouse move, this disturb ML edit field in selected mode (MT4 bug???).
// Workaround: When we use if, thats not happen
if(ObjectGetInteger(CID, _PENDING, OBJPROP_STATE)) {
ObjectSetInteger(CID, _PENDING, OBJPROP_STATE, false);
ObjectSetInteger(CID, _LAB61, OBJPROP_SELECTABLE, true);
ObjectSetInteger(CID, _LAB61, OBJPROP_SELECTED, true);
}
else if(oy < cy || oy > cy+bw) {
// if grab and drag pending label and pending button and hook not activated, delete/reset pending label
// this can happen because of object magnet, you can grab selected object 10 pip away
// !!! you cannot delete an object while dragging it on the chart, you can only delete it when you release it.
// here we are hide and deselect, and while be deleted after release. This is best we can do
ObjectSetInteger(CID, _LAB61, OBJPROP_COLOR, clrNONE);
ObjectSetInteger(CID, _LAB61, OBJPROP_SELECTED, false);
ObjectDelete(CID, _LAB61);
}
// if mouse move inside buttons, follow mouse by label
if((lparam > cxb+1 && lparam < cxb+bl-1) && ((int)dparam > cy+2 && (int)dparam < cy+bw-1)) {
ObjectSetInteger(CID, _LAB61, OBJPROP_XDISTANCE, al-lparam);
ObjectSetInteger(CID, _LAB61, OBJPROP_YDISTANCE, (int)dparam);
}
else { // return to ceneter of button
if(ObjectGetInteger(CID, _LAB61, OBJPROP_XDISTANCE) != bx)
ObjectSetInteger(CID, _LAB61, OBJPROP_XDISTANCE, bx);
if(ObjectGetInteger(CID, _LAB61, OBJPROP_XDISTANCE) != by)
ObjectSetInteger(CID, _LAB61, OBJPROP_YDISTANCE, by);
}
}
//Comment(IntegerToString(x++), " ", IntegerToString(id), " ", IntegerToString(lparam), " ", DoubleToString(dparam,0), " ", sparam, " M: ",MousePressed, " hook: ", hook);
MouseOld = MousePressed;
}
//-- Mic add for Margin Limit edit field v1.65
else if(id == CHARTEVENT_OBJECT_ENDEDIT) {
if(sparam == _VAL06E) { // Edit Object Name
string text = ObjectGetString(0,_VAL06E,OBJPROP_TEXT);
int num = (int)StringToInteger(text);
if(num >= 100 && num <= MaxMarginLimit) {
MarginLimit = num;
GlobalVariableSet(_gMarginLimit, MarginLimit);
Click();
}
else {
if(SoundsOn())
PlaySound("timeout.wav");
}
//Print("Edit value: ", text, " Num: ", num);
}
} //-- Mic end Margin Limit edit field
}
//+------------------------------------------------------------------+
//| Animated label return - Mic v1.70 |
//+------------------------------------------------------------------+
bool ReturnMove(int bx, int by, int speed = 4, int mult = 16)
{
int curX = (int)ObjectGetInteger(0,_LAB61,OBJPROP_XDISTANCE);
int curY = (int)ObjectGetInteger(0,_LAB61,OBJPROP_YDISTANCE);
int lX = MathAbs(bx - curX);
int lY = MathAbs(by - curY);
double mx = curX;
double my = curY;
int steps = MathMax(lX, lY);
double addX = Divide(lX, steps) * mult;
double addY = Divide(lY, steps) * mult;
mult = MathMax(mult, 1);
mult = MathMin(mult, steps);
for(int a=0;a<steps;a+=mult) {
if(bx > mx) {
mx += addX;
if(mx > bx)
mx = bx;
}
else if(bx < mx) {
mx -= addX;
if(mx < bx)
mx = bx;
}
if(by > my) {
my += addY;
if(my > by)
my = by;
}
else if(by < my) {
my -= addY;
if(my < by)
my = by;
}
// Move label
ObjectSetInteger(CID,_LAB61,OBJPROP_XDISTANCE,(int)MathRound(mx));
ObjectSetInteger(CID,_LAB61,OBJPROP_YDISTANCE,(int)MathRound(my));
//if(a + 250 > steps) {
// ObjectSetString(0,_LAB61,OBJPROP_TEXT,"–––––– Pending ––––––");
// ObjectSetInteger(CID,_LAB61, OBJPROP_COLOR, clrNONE);
//}
ChartRedraw();
Sleep(speed);
}
return(false);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void Run () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Here's the main loop. It runs on every tick (if used in strategy tester) or on timer event (live). |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
int i, ttype, count = 0; //, tt[]; Mic v1.67
double Balance;
bool result;
static double McBalance = AccountBalance();
// We're running for the first time
if(FirstRun) {
FirstRun = false;
// hide MT4 OneClick Trading buttons
if(DisableOneClick) ChartSetInteger(CID, CHART_SHOW_ONE_CLICK, false);
else ChartSetInteger(CID, CHART_SHOW_ONE_CLICK, true);
// disable trade level movement
//ChartSetInteger(CID, CHART_DRAG_TRADE_LEVELS, true); // Mic v1.692 moved to pos #441; v1.704 moved to OnChartEvent
// disable 'chart in foreground'
ChartSetInteger(CID, CHART_FOREGROUND, false);
// enable chart shift
ChartSetInteger(CID, CHART_SHIFT, true);
// show object descriptions Mic v1.65
ChartSetInteger(CID, CHART_SHOW_OBJECT_DESCR, true);
// background
panelBkg_add = (int)(160*DPIScaling);
if (panelBkg_add > 160) {
panelBkg_add-=160;
} else {
panelBkg_add=0;
}
Panel(_BKG, CORNER_RIGHT_UPPER, BORDER_FLAT, (int)(160*DPIScaling), 0, (int)(160*DPIScaling), 5000, BackgroundColor);
// logos
Bitmap(_PFGT, CORNER_RIGHT_UPPER, (int)(33*DPIScaling), 4, 77, 40, _BMP_FGT);
Bitmap(_PDRAGON, CORNER_RIGHT_UPPER, (int)(114*DPIScaling), 4, 42, 42, _BMP_DRAGON);
// thin lines
Bitmap(_PTHL01, CORNER_RIGHT_UPPER, (int)(4*DPIScaling)+panelBkg_add/2, 48, 152, 5, _BMP_THIN);
Bitmap(_PTHL04, CORNER_RIGHT_LOWER, (int)(4*DPIScaling)+panelBkg_add/2, (int)(55*DPIScaling), 152, 5, _BMP_THIN);
Bitmap(_PTHL05, CORNER_RIGHT_LOWER, (int)(4*DPIScaling)+panelBkg_add/2, (int)(129*DPIScaling), 152, 5, _BMP_THIN);
// headers
Bitmap(_PMLM, CORNER_RIGHT_UPPER, (int)(4*DPIScaling)+panelBkg_add, (int)(159*DPIScaling), 146, 18, _BMP_MLM);
Bitmap(_PMNG, CORNER_RIGHT_UPPER, (int)(4*DPIScaling)+panelBkg_add, (int)(234*DPIScaling), 146, 18, _BMP_MNG);
Bitmap(_PTRD, CORNER_RIGHT_UPPER, (int)(4*DPIScaling)+panelBkg_add, (int)(312*DPIScaling), 146, 18, _BMP_TRD);
Bitmap(_PACC, CORNER_RIGHT_LOWER, (int)(4*DPIScaling)+panelBkg_add, (int)(185*DPIScaling), 146, 18, _BMP_ACC);
Bitmap(_PMLV, CORNER_RIGHT_LOWER, (int)(4*DPIScaling)+panelBkg_add, (int)(100*DPIScaling), 146, 18, _BMP_MLV);
Bitmap(_PSPT, CORNER_RIGHT_LOWER, (int)(4*DPIScaling)+panelBkg_add, (int)(26*DPIScaling), 146, 18, _BMP_SPT);
// speakers
BmpButton(_SPK, CORNER_RIGHT_UPPER, (int)(6*DPIScaling), (int)(15*DPIScaling), 20, 20, _BMP_SPK_ON, _BMP_SPK_OFF);
ObjectSetInteger(CID, _SPK, OBJPROP_STATE, SoundsOn());
OldSoundsOn = SoundsOn();
// automation
Label(_LAB01, CORNER_RIGHT_UPPER, (int)(120*DPIScaling), (int)(147*DPIScaling), "Add automatically", 10, White, _MFONT, ANCHOR_LEFT_LOWER);
BmpButton(_ADD, CORNER_RIGHT_UPPER, (int)(121*DPIScaling), (int)(128*DPIScaling), 22, 19, _BMP_CHK_ON, _BMP_CHK_OFF);
ObjectSetInteger(CID, _ADD, OBJPROP_STATE, AutoAdd());
OldAutoAdd = AutoAdd();
// margin limit
MarginLimit = int(GlobalVariableGet(_gMarginLimit));
Bitmap(_PPLUS, CORNER_RIGHT_UPPER, (int)(115*DPIScaling), (int)(185*DPIScaling), 38, 38, _BMP_AUP_DIS);
Bitmap(_PMINUS, CORNER_RIGHT_UPPER, (int)(7*DPIScaling)+panelBkg_add/2, (int)(185*DPIScaling), 38, 38, _BMP_ADN_DIS);
Bitmap(_PBUY, CORNER_RIGHT_UPPER, (int)(5*DPIScaling)+panelBkg_add/2, (int)(57*DPIScaling), 74, 40, _BMP_BUY_DIS);
Bitmap(_PSELL, CORNER_RIGHT_UPPER, (int)(81*DPIScaling), (int)(57*DPIScaling), 74, 40, _BMP_SELL_DIS);
Bitmap(_PCLOSE, CORNER_RIGHT_UPPER, (int)(5*DPIScaling)+panelBkg_add/2, (int)(261*DPIScaling), 74, 40, _BMP_CLOSE);
Bitmap(_PTPSL, CORNER_RIGHT_UPPER, (int)(81*DPIScaling), (int)(261*DPIScaling), 74, 40, _BMP_TPSL);
// session reset
Button(_ID + "Reset", CORNER_RIGHT_LOWER, (int)(49*DPIScaling)+panelBkg_add, (int)(205*DPIScaling), 43, 14, "RESET", 7, Black, Silver, Black, "Consolas");
// Pending button Mic v1.70
// LAB61 string must be dimension like pending button
PendingLabel(_LAB61, CORNER_RIGHT_UPPER, (int)(80*DPIScaling), (int)(111*DPIScaling), "–––– Pending ––––", 10, clrNONE, "Arial Bold", ANCHOR_CENTER);
BmpButton(_PENDING, CORNER_RIGHT_UPPER, (int)(7*DPIScaling)+panelBkg_add/2, (int)(102*DPIScaling), 146, 20, _BMP_PEND_ON, _BMP_PEND_OFF);
ObjectSetString(CID, _LAB61, OBJPROP_TOOLTIP, "Click, Drag and Drop");
// enable monitoring of mouse movement
ChartSetInteger(CID, CHART_EVENT_MOUSE_MOVE, true);
// We're NOT running for the first time!
} else {
// let's define and set all necessary things...
RefreshRates();
tickvalue = (MarketInfo(_Symbol, MODE_TICKVALUE) / MarketInfo(_Symbol, MODE_TICKSIZE)) * _Point;
SessionReset();
SelectLine();
MakeStats();
MakeLabels();
ShowSpread();
CandleTime();
MakeValues();
StopAddingPips = 3.0 * SpreadAverage * Pt;
Sl = 0.0;
Tp = 0.0;
PnL = 0.0;
// toggle sound events
bool SoundsOn = ObjectGetInteger(CID, _SPK, OBJPROP_STATE);
if(SoundsOn != OldSoundsOn) {
OldSoundsOn = SoundsOn;
GlobalVariableSet(_gSoundsOn, SoundsOn);
PlaySound("::Sounds\\button.wav");
}
// toggle automatic additions (pyramiding)
bool AutoAdd = ObjectGetInteger(CID, _ADD, OBJPROP_STATE);
if(AutoAdd != OldAutoAdd) {
OldAutoAdd = AutoAdd;
GlobalVariableSet(_gAutoAdd, AutoAdd);
if(SoundsOn()) Click();
}
// find out the margin
Fmp = 100.0 * Divide(AccountEquity(), AccountMargin());
// find out available lots
AvailLots = (Divide(AccountEquity(), (MarginLimit + MLPadding) / 100.0) - AccountMargin()) / MarketInfo(_Symbol, MODE_MARGINREQUIRED);
AvailLots = NormalizeDouble(MathMax(AvailLots, 0.0), Lp);
// find out additional lots
AddLots = NormalizeDouble(MathMax(MarketInfo(_Symbol, MODE_MINLOT), (AccountLeverage() * AccountEquity() / 5000000.0)), Lp);
// let's find out which trades are running
Total = OrdersTotal();
// if the current balance differs from recorded...
if(AccountBalance() != McBalance) {
ObjectSetInteger(CID, _BUY, OBJPROP_STATE, false);
ObjectSetInteger(CID, _SELL, OBJPROP_STATE, false);
if(CloseAllOnBalanceChange) CloseAllTrades();
McBalance = AccountBalance();
return;
}
// TradeMode determination new rutine Mic v1.67
//----------------------------------------------------------------
TradeMode = TRADE_NONE;
int first_type = -1;
for(i = 0; i < Total; i++) {
result = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
ttype = OrderType();
if(OrderSymbol() == _Symbol && (ttype == OP_BUY || ttype == OP_SELL) && (!OnlyManageOwnTrades || OrderMagicNumber() == MagicNumber)) { // All trades on current symbol
if(first_type == -1) {
first_type = ttype;
if(ttype == OP_BUY)
TradeMode = TRADE_BUY;
else
TradeMode = TRADE_SELL;
}
if(first_type != ttype) { // If hedge
TradeMode = TRADE_MISMATCH;
break;
}
Sl = OrderStopLoss();
Tp = OrderTakeProfit();
PnL += OrderProfit() + OrderCommission() + OrderSwap();
count++;
}
else if(ttype == OP_BUY || ttype == OP_SELL) { // Trade on other symbol or manual
if(OrderSymbol() == _Symbol)
TradeMode = TRADE_MANUAL;
else
TradeMode = TRADE_OTHER;
break;
}
}
//----------------------------------------------------------------
// ain't we trading another market?
//if(GlobalVariableGet(_gIsTrading) != 0.0 && GlobalVariableGet(_gIsTrading) != Sym) TradeMode = TRADE_OTHER;
// let's adjust the arrows displayed due to MarginLimit:
if(MarginLimit > 100 && MarginLimit < MaxMarginLimit) {
BmpButton(_PLUS, CORNER_RIGHT_UPPER, (int)(115*DPIScaling), (int)(185*DPIScaling), 38, 38, _BMP_AUP_ON, _BMP_AUP_OFF);
BmpButton(_MINUS, CORNER_RIGHT_UPPER, (int)(7*DPIScaling)+panelBkg_add/2, (int)(185*DPIScaling), 38, 38, _BMP_ADN_ON, _BMP_ADN_OFF);
} else if(MarginLimit == 100) {
if(ObjectFind(CID, _MINUS) != -1) ObjectDelete(CID, _MINUS);
BmpButton(_PLUS, CORNER_RIGHT_UPPER, (int)(115*DPIScaling), (int)(185*DPIScaling), 38, 38, _BMP_AUP_ON, _BMP_AUP_OFF);
} else {
if(ObjectFind(CID, _PLUS) != -1) ObjectDelete(CID, _PLUS);
BmpButton(_MINUS, CORNER_RIGHT_UPPER, (int)(7*DPIScaling)+panelBkg_add/2, (int)(185*DPIScaling), 38, 38, _BMP_ADN_ON, _BMP_ADN_OFF);
}
// we decide what to display according to state of running trades:
switch(TradeMode) { // pos #441
case TRADE_BUY: if(ObjectFind(CID, _SELL) != -1) ObjectDelete(CID, _SELL);
if(AutoAdd()) {
if(ObjectFind(CID, _BUY) != -1) ObjectDelete(CID, _BUY);
BmpButton(_BUYING, CORNER_RIGHT_UPPER, (int)(5*DPIScaling)+panelBkg_add/2, (int)(57*DPIScaling), 151, 40, _BMP_BUYING, _BMP_BUYING);
} else {
if(ObjectFind(CID, _BUYING) != -1) ObjectDelete(CID, _BUYING);
BmpButton(_BUY, CORNER_RIGHT_UPPER, (int)(5*DPIScaling)+panelBkg_add/2, (int)(57*DPIScaling), 74, 40, _BMP_BUY_ON, _BMP_BUY_OFF);
}
BmpButton(_CLOSE, CORNER_RIGHT_UPPER, (int)(5*DPIScaling)+panelBkg_add/2, (int)(261*DPIScaling), 74, 40, _BMP_CLOSE_ON, _BMP_CLOSE_OFF);
MakePriceLine();
GlobalVariableSet(_gIsTrading, Sym);
break;
case TRADE_SELL: if(ObjectFind(CID, _BUY) != -1) ObjectDelete(CID, _BUY);
if(AutoAdd()) {
if(ObjectFind(CID, _SELL) != -1) ObjectDelete(CID, _SELL);
BmpButton(_SELLING, CORNER_RIGHT_UPPER, (int)(5*DPIScaling)+panelBkg_add/2, (int)(57*DPIScaling), 151, 40, _BMP_SELLING, _BMP_SELLING);
} else {
if(ObjectFind(CID, _SELLING) != -1) ObjectDelete(CID, _SELLING);
BmpButton(_SELL, CORNER_RIGHT_UPPER, (int)(81*DPIScaling), (int)(57*DPIScaling), 74, 40, _BMP_SELL_ON, _BMP_SELL_OFF);
}
BmpButton(_CLOSE, CORNER_RIGHT_UPPER, (int)(5*DPIScaling)+panelBkg_add/2, (int)(261*DPIScaling), 74, 40, _BMP_CLOSE_ON, _BMP_CLOSE_OFF);
MakePriceLine();
GlobalVariableSet(_gIsTrading, Sym);
break;
case TRADE_MISMATCH: if(ObjectFind(CID, _SELL) != -1) ObjectDelete(CID, _SELL);
if(ObjectFind(CID, _SELLING) != -1) ObjectDelete(CID, _SELLING);
if(ObjectFind(CID, _BUY) != -1) ObjectDelete(CID, _BUY);
if(ObjectFind(CID, _BUYING) != -1) ObjectDelete(CID, _BUYING);
if(ObjectFind(CID, _CLOSE) != -1) ObjectDelete(CID, _CLOSE);
ObjectDelete(_PLINE);
LineMode = LINE_INVALID;
GlobalVariableSet(_gIsTrading, 0.0);
break;
case TRADE_MANUAL: // Mic v1.69 add TRADE_MANUAL
case TRADE_OTHER: if(ObjectFind(CID, _SELL) != -1) ObjectDelete(CID, _SELL);
if(ObjectFind(CID, _SELLING) != -1) ObjectDelete(CID, _SELLING);
if(ObjectFind(CID, _BUY) != -1) ObjectDelete(CID, _BUY);
if(ObjectFind(CID, _BUYING) != -1) ObjectDelete(CID, _BUYING);
if(ObjectFind(CID, _CLOSE) != -1) ObjectDelete(CID, _CLOSE);
ObjectDelete(_PLINE);
LineMode = LINE_INVALID;
break;
default: if(ObjectFind(CID, _BUYING) != -1) ObjectDelete(CID, _BUYING);
if(ObjectFind(CID, _SELLING) != -1) ObjectDelete(CID, _SELLING);
if(ObjectFind(CID, _CLOSE) != -1) ObjectDelete(CID, _CLOSE);
BmpButton(_BUY, CORNER_RIGHT_UPPER, (int)(5*DPIScaling)+panelBkg_add/2, (int)(57*DPIScaling), 74, 40, _BMP_BUY_ON, _BMP_BUY_OFF);
BmpButton(_SELL, CORNER_RIGHT_UPPER, (int)(81*DPIScaling), (int)(57*DPIScaling), 74, 40, _BMP_SELL_ON, _BMP_SELL_OFF);
if(ObjectFind(_PLINE) != -1) ObjectDelete(_PLINE);
LineMode = LINE_INVALID;
GlobalVariableSet(_gIsTrading, 0.0);
break;
}
// we decide the mode of the TP/SL button according to position of the line
switch(LineMode) {
case LINE_INVALID: if(ObjectFind(CID, _STOP) != -1) ObjectDelete(CID, _STOP);
if(ObjectFind(CID, _TAKE) != -1) ObjectDelete(CID, _TAKE);
break;
case LINE_SL: if(ObjectFind(CID, _TAKE) != -1) ObjectDelete(CID, _TAKE);
BmpButton(_STOP, CORNER_RIGHT_UPPER, (int)(81*DPIScaling), (int)(261*DPIScaling), 74, 40, _BMP_SL_ON, _BMP_SL_OFF);
break;
case LINE_TP: if(ObjectFind(CID, _STOP) != -1) ObjectDelete(CID, _STOP);
BmpButton(_TAKE, CORNER_RIGHT_UPPER, (int)(81*DPIScaling), (int)(261*DPIScaling), 74, 40, _BMP_TP_ON, _BMP_TP_OFF);
break;
}
// Mic v1.70 Recreate pending label and button if label is deleted (label is always selected)
if(ObjectFind(CID, _LAB61) == -1) { // if pending label deleted, pending button must be recreated to be over pending label
if(ObjectFind(CID, _PENDING) != -1) ObjectDelete(CID, _PENDING);
PendingLabel(_LAB61, CORNER_RIGHT_UPPER, (int)(80*DPIScaling), (int)(111*DPIScaling), "–––– Pending ––––", 10, clrNONE, "Arial Bold", ANCHOR_CENTER);
BmpButton(_PENDING, CORNER_RIGHT_UPPER, (int)(7*DPIScaling), (int)(102*DPIScaling), 146, 20, _BMP_PEND_ON, _BMP_PEND_OFF);
ObjectSetString(CID, _PENDING, OBJPROP_TOOLTIP, "Click, Drag and Drop");
}
// BUY
//if(TradeMode != TRADE_SELL && TradeMode != TRADE_MISMATCH && TradeMode != TRADE_OTHER) {
if(TradeMode == TRADE_BUY || TradeMode == TRADE_NONE) { // Mic v1.68 new mode TRADE_MANUAL
// Was the BUY button pushed?
if(ObjectGetInteger(CID, _BUY, OBJPROP_STATE)) {
Buyer(true);
ObjectSetInteger(CID, _BUY, OBJPROP_STATE, false);
}
}
// SELL
//if(TradeMode != TRADE_BUY && TradeMode != TRADE_MISMATCH && TradeMode != TRADE_OTHER) {
if(TradeMode == TRADE_SELL || TradeMode == TRADE_NONE) { // Mic 1.68 new mode TRADE_MANUAL
// Was the SELL button pushed?
if(ObjectGetInteger(CID, _SELL, OBJPROP_STATE)) {
Seller(true);
ObjectSetInteger(CID, _SELL, OBJPROP_STATE, false);
}
}
// If the CLOSE button was pushed:
if(ObjectGetInteger(CID, _CLOSE, OBJPROP_STATE)) {
Balance = AccountBalance();
if(SoundsOn() && AccountProfit() > 0.0 && count >= 3) PlaySound("::Sounds\\counting.wav");
if(SoundsOn() && AccountProfit() <= 0.0) PlaySound("ok.wav");
CloseAllTrades();
Fmp = 100.0 * Divide(AccountEquity(), AccountMargin());
MakeValues();
ObjectSetInteger(CID, _CLOSE, OBJPROP_STATE, false);
if(SoundsOn()) PlaySound("::Sounds\\closing.wav");
}
// If the TP button was pushed:
if(ObjectGetInteger(CID, _TAKE, OBJPROP_STATE)) {
Target = NormalizeDouble(ObjectGet(_PLINE, OBJPROP_PRICE1), Digits);
for(i = Total - 1; i >= 0; i--) {
result = OrderSelect(i, SELECT_BY_POS);
ttype = OrderType();
if(ttype == OP_BUY || ttype == OP_SELL) {
if(OrderSymbol() == _Symbol && (!OnlyManageOwnTrades || OrderMagicNumber() == MagicNumber))
result = OrderModifyReliable(OrderTicket(), 0, OrderStopLoss(), Target, 0, CLR_NONE);
}
}
ObjectSetInteger(CID, _TAKE, OBJPROP_STATE, false);
if(SoundsOn()) PlaySound("::Sounds\\targets_set.wav");
}
// If the SL button was pushed:
if(ObjectGetInteger(CID, _STOP, OBJPROP_STATE)) {
Stop = NormalizeDouble(ObjectGet(_PLINE, OBJPROP_PRICE1), Digits);
for(i = Total - 1; i >= 0; i--) {
result = OrderSelect(i, SELECT_BY_POS);
ttype = OrderType();
if(ttype == OP_BUY || ttype == OP_SELL) {
if(OrderSymbol() == _Symbol && (!OnlyManageOwnTrades || OrderMagicNumber() == MagicNumber))
result = OrderModifyReliable(OrderTicket(), 0, Stop, OrderTakeProfit(), 0, CLR_NONE);
}
}
ObjectSetInteger(CID, _STOP, OBJPROP_STATE, false);
if(SoundsOn()) PlaySound("::Sounds\\stops_set.wav");
}
// If the UP button was pushed:
if(ObjectGetInteger(CID, _PLUS, OBJPROP_STATE)) {
if(MarginLimit >= 1000) {
MarginLimit += 100;
MarginLimit = (MarginLimit / 100) * 100;
} else {
MarginLimit += 10;
MarginLimit = (MarginLimit / 10) * 10;
}
MarginLimit = MathMin(MarginLimit, MaxMarginLimit);
GlobalVariableSet(_gMarginLimit, MarginLimit);
Click();
ObjectSetInteger(CID, _PLUS, OBJPROP_STATE, false);
}
// If the DOWN button was pushed:
if(ObjectGetInteger(CID, _MINUS, OBJPROP_STATE)) {
if(MarginLimit > 1000) { // Mic v1.68 change ">=" to ">"
MarginLimit -= 100;
MarginLimit = int(MathCeil((double)MarginLimit / 100) * 100); // Mic v1.69
} else {
MarginLimit -= 10;
MarginLimit = int(MathCeil((double)MarginLimit / 10) * 10); // Mic v1.69
}
MarginLimit = MathMax(MarginLimit, 100);
GlobalVariableSet(_gMarginLimit, MarginLimit);
Click();
ObjectSetInteger(CID, _MINUS, OBJPROP_STATE, false);
}
// and let's go trading!:
Buyer();
Seller();
}
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void Buyer (bool BuyClick = false) {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Buy and (eventually) keep on buying. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
int ticket;
// If the load is less than minimum, get out now:
if(AvailLots < MarketInfo(_Symbol, MODE_MINLOT)) return;
if(AddLots < MarketInfo(_Symbol, MODE_MINLOT)) return;
// If the trade is a single shot/first shot:
if(BuyClick && (TradeMode == TRADE_NONE || TradeMode == TRADE_BUY)) {
// If the trade doesn't go through,
if(AccountFreeMarginCheck(_Symbol, OP_BUY, AvailLots) <= 0 || GetLastError() == 134) {
// we decrease the trade size by a minimal lotsize
AvailLots -= MarketInfo(_Symbol, MODE_MINLOT);
// ...and if the acceptable result is less than minimal lotsize, get out:
if(AvailLots < MarketInfo(_Symbol, MODE_MINLOT)) return;
}
ticket = OrderSendReliable(_Symbol, OP_BUY, AvailLots, Ask, 0, Sl, Tp, NULL, MagicNumber, 0, CLR_NONE);
if(SoundsOn()) {if (ticket > 0) PlaySound("ok.wav"); else PlaySound("timeout.wav");}
// If it's an auto-addition:
} else if(TradeMode == TRADE_BUY && AutoAdd()) {
AddLots = MathMax(AddLots, AvailLots); //Mic v1.691
// If the trade doesn't go through,
if(AccountFreeMarginCheck(_Symbol, OP_BUY, AddLots) <= 0 || GetLastError() == 134) {
// we decrease the trade size by a minimal lotsize
AddLots -= MarketInfo(_Symbol, MODE_MINLOT);
// ...and if the acceptable result is less than minimal lotsize, get out:
if(AddLots < MarketInfo(_Symbol, MODE_MINLOT)) return;
}
// we'll add to position, if the TP is not set, or if we are distinctly below it:
if(Ask < Tp - StopAddingPips || Tp == 0.0) {
ticket = OrderSendReliable(_Symbol, OP_BUY, AddLots, Ask, 0, Sl, Tp, NULL, MagicNumber, 0, CLR_NONE);
if(SoundsOn() && ticket > 0) PlaySound("::Sounds\\coin.wav");
}
}
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void Seller (bool SellClick = false) {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Sell and (eventually) keep on selling. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
int ticket;
// If the load is less than minimum, get out now:
if(AvailLots < MarketInfo(_Symbol, MODE_MINLOT)) return;
if(AddLots < MarketInfo(_Symbol, MODE_MINLOT)) return;
// If the trade is a single shot/first shot:
if(SellClick && (TradeMode == TRADE_NONE || TradeMode == TRADE_SELL)) {
// If the trade doesn't go through,
if(AccountFreeMarginCheck(_Symbol, OP_SELL, AvailLots) <= 0 || GetLastError() == 134) {
// we decrease the trade size by a minimal lotsize
AvailLots -= MarketInfo(_Symbol, MODE_MINLOT);
// ...and if the acceptable result is less than minimal lotsize, get out:
if(AvailLots < MarketInfo(_Symbol, MODE_MINLOT)) return;
}
ticket = OrderSendReliable(_Symbol, OP_SELL, AvailLots, Bid, 0, Sl, Tp, NULL, MagicNumber, 0, CLR_NONE);
if(SoundsOn()) {if (ticket > 0) PlaySound("ok.wav"); else PlaySound("timeout.wav");}
// If it's an auto-addition:
} else if(TradeMode == TRADE_SELL && AutoAdd()) {
AddLots = MathMax(AddLots, AvailLots); //Mic v1.691
// If the trade doesn't go through,
if(AccountFreeMarginCheck(_Symbol, OP_SELL, AddLots) <= 0 || GetLastError() == 134) {
// we decrease the trade size by a minimal lotsize
AddLots -= MarketInfo(_Symbol, MODE_MINLOT);
// ...and if the acceptable result is less than minimal lotsize, get out:
if(AddLots < MarketInfo(_Symbol, MODE_MINLOT)) return;
}
// we'll add to position, if the TP is not set, or if we are distinctly above it:
if(Bid > Tp + StopAddingPips || Tp == 0.0) {
ticket = OrderSendReliable(_Symbol, OP_SELL, AddLots, Bid, 0, Sl, Tp, NULL, MagicNumber, 0, CLR_NONE);
if(SoundsOn() && ticket > 0) PlaySound("::Sounds\\coin.wav");
}
}
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void CloseAllTrades () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Close all running trades. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
for(int i = Total - 1; i >= 0; i--) {
bool result = OrderSelect(i, SELECT_BY_POS);
int ttype = OrderType();
switch(ttype) {
// Close all longs
case OP_BUY: if(OrderSymbol() == _Symbol && (!OnlyManageOwnTrades || OrderMagicNumber() == MagicNumber)) {
result = OrderCloseReliable(OrderTicket(), OrderLots(), OrderClosePrice(), 0, CLR_NONE );
}
break;
// Close all shorts
case OP_SELL: if(OrderSymbol() == _Symbol && (!OnlyManageOwnTrades || OrderMagicNumber() == MagicNumber)) {
result = OrderCloseReliable(OrderTicket(), OrderLots(), OrderClosePrice(), 0, CLR_NONE );
}
break;
}
}
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void MakeLabels () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Display labels across the panel and chart. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// server
Label(_LAB21, CORNER_LEFT_LOWER, (int)(4*DPIScaling), (int)(18*DPIScaling), "Server>", 7, LabelColor, _MFONT, ANCHOR_LEFT_LOWER);
// account
Label(_LAB22, CORNER_RIGHT_LOWER, (int)(151*DPIScaling), (int)(166*DPIScaling), "Balance", 9, LabelColor, _MFONT, ANCHOR_LEFT_LOWER);
Label(_LAB23, CORNER_RIGHT_LOWER, (int)(151*DPIScaling), (int)(151*DPIScaling), "Equity", 9, LabelColor, _MFONT, ANCHOR_LEFT_LOWER);
Label(_LAB24, CORNER_RIGHT_LOWER, (int)(151*DPIScaling), (int)(136*DPIScaling), "Session", 9, LabelColor, _MFONT, ANCHOR_LEFT_LOWER);
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void MakeValues () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Display values across the panel and chart. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
string _Trades, _Lots, _Avl, _PnL, _MG, _ML, _MGV, _MLV, _Fmp, _mLimit;
int t = 0, c_dig = 2, p_dig = 1;
double l = 0.0, x = 0.0, p = 0.0, c = 0.0, s = 0.0, PP = 0.0, PL = 0.0, SD = 0.0, SV = 0.0;
datetime d = 0;
int w = 0;
color pCol = LabelColor,
tCol = NeutralColor,
lCol = NegativeColor,
mCol = NeutralColor;
static double oldbs = 0.0, oldss = 0.0;
SetFont(MathMax(AccountBalance(), AccountEquity()));
for(int i = 0; i < OrdersTotal(); i++) {
bool result = OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
int ttype = OrderType();
if(OrderSymbol() == _Symbol && (ttype == OP_BUY || ttype == OP_SELL) && (!OnlyManageOwnTrades || OrderMagicNumber() == MagicNumber)) {
t++;
l += OrderLots();
p += OrderLots() * OrderOpenPrice();
c += OrderCommission();
s += OrderSwap();
}
}
double a = NormalizeDouble(Divide(p, l), _Digits);
if(t == 0) {
SV = AccountBalance() - AvailLots * MarketInfo(_Symbol, MODE_MARGINREQUIRED) * (AccountStopoutLevel() / 100.0);
SD = NormalizeDouble(Divide(Divide(SV, tickvalue), AvailLots) * _Point, _Digits);
} else {
SV = AccountBalance() - AccountMargin() * (AccountStopoutLevel() / 100.0);
SD = NormalizeDouble(Divide(Divide(SV + c + s, tickvalue), l) * _Point, _Digits);
}
if(Tp != 0) PP = l * MathAbs(Tp - a) / _Point * tickvalue + c + s; // Mic v1.66 add c and s for MaxGain
long width = ChartGetInteger(CID, CHART_WIDTH_IN_PIXELS);
ChartXYToTimePrice(CID, int(width - (int)(170*DPIScaling)), (int)(20*DPIScaling), w, d, p);
_Lots = DoubleToString(l, 2);
_Avl = DoubleToString(AvailLots, Lp) + " lots available.";
if(TradeMode == TRADE_NONE) {
_Trades = "No open trades.";
tCol = LabelColor;
ThinLines(false);
if(ObjectFind(CID, _AMARK) != -1) ObjectDelete(CID, _AMARK);
if(!MousePressed) {
x = NormalizeDouble(Bid - SD, _Digits);
oldbs = x;
Mark(_BSMARK, ANCHOR_CENTER, d, x, (int)(18*DPIScaling), Red, "Margin StopOut BUY: " + DoubleToString(x, _Digits), true, true);
x = NormalizeDouble(Ask + SD, _Digits);
oldss = x;
Mark(_SSMARK, ANCHOR_CENTER, d, x, (int)(18*DPIScaling), Red, "Margin StopOut SELL: " + DoubleToString(x, _Digits), true, true);
} else {
double bs = NormalizeDouble(ObjectGet(_BSMARK, OBJPROP_PRICE1), _Digits);
double ss = NormalizeDouble(ObjectGet(_SSMARK, OBJPROP_PRICE1), _Digits);
double sd, al, ml;
double e = AccountEquity();
double m = AccountMargin();
double i = MarketInfo(_Symbol, MODE_MARGINREQUIRED);
double q = AccountStopoutLevel();
if(bs != oldbs) {
oldbs = bs;
sd = (Bid - bs);
al = Divide(100.0 * AccountBalance() * _Point, 100.0 * tickvalue * sd + i * q * _Point);
ml = Divide(100.0 * e - m * MLPadding - i * al * MLPadding, i * al + m);
MarginLimit = int(MathMax(int(ml), 100.0));
if(MarginLimit > MaxMarginLimit) // Mic v1.65 limit max margin limit
MarginLimit = MaxMarginLimit;
GlobalVariableSet(_gMarginLimit, MarginLimit);
}
if(ss != oldss) {
oldss = ss;
sd = (ss - Ask);
al = Divide(100.0 * AccountBalance() * _Point, 100.0 * tickvalue * sd + i * q * _Point);
ml = Divide(100.0 * e - m * MLPadding - i * al * MLPadding, i * al + m);
MarginLimit = int(MathMax(int(ml), 100.0));
if(MarginLimit > MaxMarginLimit) // Mic v1.65 limit max value
MarginLimit = MaxMarginLimit;
GlobalVariableSet(_gMarginLimit, MarginLimit);
}
}
} else if(TradeMode == TRADE_MISMATCH) {
_Trades = "Trades are hedged.";
_Avl = "Can't enter new trades.";
ThinLines(false);
if(ObjectFind(CID, _AMARK) != -1) ObjectDelete(CID, _AMARK);
if(ObjectFind(CID, _BSMARK) != -1) ObjectDelete(CID, _BSMARK);
if(ObjectFind(CID, _SSMARK) != -1) ObjectDelete(CID, _SSMARK);
} else if(TradeMode == TRADE_OTHER) {
_Trades = "Trading another symbol."; // Mic v1.67 change "market" to "symbol"
_Avl = "Can't enter new trades.";
ThinLines(false);
if(ObjectFind(CID, _AMARK) != -1) ObjectDelete(CID, _AMARK);
if(ObjectFind(CID, _BSMARK) != -1) ObjectDelete(CID, _BSMARK);
if(ObjectFind(CID, _SSMARK) != -1) ObjectDelete(CID, _SSMARK);
} else if(TradeMode == TRADE_MANUAL) { // Mic v1.67
_Trades = "Traded by Terminal.";
_Avl = "Can't enter new trades.";
ThinLines(false);
if(ObjectFind(CID, _AMARK) != -1) ObjectDelete(CID, _AMARK);
if(ObjectFind(CID, _BSMARK) != -1) ObjectDelete(CID, _BSMARK);
if(ObjectFind(CID, _SSMARK) != -1) ObjectDelete(CID, _SSMARK);
} else if(TradeMode == TRADE_BUY) {
if(ObjectFind(CID, _SSMARK) != -1) ObjectDelete(CID, _SSMARK);
// average entry
Mark(_AMARK, ANCHOR_CENTER, d, a, 18, LimeGreen, "Average Entry: " + DoubleToString(a, _Digits));
// margin stopout
x = a - SD;
Mark(_BSMARK, ANCHOR_CENTER, d, x, 18, Red, "Margin StopOut BUY: " + DoubleToString(x, _Digits));
// priceline description
double PLv = NormalizeDouble(ObjectGet(_PLINE, OBJPROP_PRICE1), _Digits);
double PLx = l * (PLv - a) / _Point * tickvalue + c + s; // Mic v1.66
string _PL;
if(LineMode == LINE_SL) _PL = " STOP LOSS @" + DoubleToString(PLv, Digits) + _S + AccountCurrency() + _S + DoubleToString(PLx, 2) + " (" + DoubleToString(Divide(PLx, AccountBalance()) * 100.0, 1) + _C + ")";
if(LineMode == LINE_TP) _PL = " TAKE PROFIT @" + DoubleToString(PLv, Digits) + _S + AccountCurrency() + _S + DoubleToString(PLx, 2) + " (" + DoubleToString(Divide(PLx, AccountBalance()) * 100.0, 1) + _C + ")";
ObjectSetText(_PLINE, _PL);
if(t == 1) _Trades = _Lots + " lots in " + IntegerToString(t) + " trade.";
else _Trades = _Lots + " lots in " + IntegerToString(t) + " trades.";
if(MathAbs(PnL) >= 1000.0) c_dig = 0; else c_dig = 2;
if(MathAbs(PnL) / AccountBalance() >= 1) p_dig = 0; else p_dig = 1;
if(AccountProfit() >= 0) {
_PnL = "Winning " + _A + DoubleToString(PnL, c_dig) + "(" + DoubleToString(PnL / AccountBalance() * 100.0, p_dig) + _C + ")";
pCol = PositiveColor;
} else {
_PnL = "Losing " + _A + DoubleToString(MathAbs(PnL), c_dig) + "(" + DoubleToString(MathAbs(PnL / AccountBalance()) * 100.0, p_dig) + _C + ")";
pCol = NegativeColor;
}
_MG = "MaxGain:";
if(Tp == 0.0) _MGV = "TP not set";
else {
if(PP >= 1000.0) c_dig = 0; else c_dig = 2;
if(PP / AccountBalance() >= 1) p_dig = 0; else p_dig = 1;
_MGV = _A + DoubleToString(PP, c_dig) + "(" + DoubleToString(PP / AccountBalance() * 100.0, p_dig) + _C + ")";
}
_ML = "MaxLoss:";
if(Sl == 0.0) {
PL = l * -SD / _Point * tickvalue; // Mic v1.62 - SD sign
} else {
PL = l * (Sl - a) / _Point * tickvalue; // Mic v1.62 - Remove MathAbs
PL += (c + s); // Mic v1.66
}
if(PL >= 0) { // Mic v1.62 - >= instead <=
// xxx
_ML = "Secured:";
lCol = PositiveColor;
}
PL = MathAbs(PL); // Mic v1.62 - move here from xxx
if(PL >= 1000.0) c_dig = 0; else c_dig = 2;
if(PL / AccountBalance() >= 1) p_dig = 0; else p_dig = 1;
_MLV = _A + DoubleToString(PL, c_dig) + "(" + DoubleToString(PL / AccountBalance() * 100.0, p_dig) + _C + ")";
tCol = DeepSkyBlue;
ThinLines(true);
} else {
if(ObjectFind(CID, _BSMARK) != -1) ObjectDelete(CID, _BSMARK);
// average entry
Mark(_AMARK, ANCHOR_CENTER, d, a, 18, LimeGreen, "Average Entry: " + DoubleToString(a, _Digits));
// margin stopout
x = a + SD;
Mark(_SSMARK, ANCHOR_CENTER, d, x, 18, Red, "Margin StopOut SELL: " + DoubleToString(x, _Digits));
// priceline description
double PLv = NormalizeDouble(ObjectGet(_PLINE, OBJPROP_PRICE1), _Digits);
double PLx = l * (a - PLv) / _Point * tickvalue + c + s; // Mic v1.66
string _PL;
if(LineMode == LINE_SL) _PL = " STOP LOSS @" + DoubleToString(PLv, Digits) + _S + AccountCurrency() + _S + DoubleToString(PLx, 2) + " (" + DoubleToString(Divide(PLx, AccountBalance()) * 100.0, 1) + _C + ")";
if(LineMode == LINE_TP) _PL = " TAKE PROFIT @" + DoubleToString(PLv, Digits) + _S + AccountCurrency() + _S + DoubleToString(PLx, 2) + " (" + DoubleToString(Divide(PLx, AccountBalance()) * 100.0, 1) + _C + ")";
ObjectSetText(_PLINE, _PL);
if(t == 1) _Trades = _Lots + " lots in " + IntegerToString(t) + " trade.";
else _Trades = _Lots + " lots in " + IntegerToString(t) + " trades.";
if(MathAbs(PnL) >= 1000.0) c_dig = 0; else c_dig = 2;
if(MathAbs(PnL) / AccountBalance() >= 1) p_dig = 0; else p_dig = 1;
if(AccountProfit() >= 0) {
_PnL = "Winning " + _A + DoubleToString(PnL, c_dig) + "(" + DoubleToString(PnL / AccountBalance() * 100.0, p_dig) + _C + ")";
pCol = PositiveColor;
} else {
_PnL = "Losing " + _A + DoubleToString(MathAbs(PnL), c_dig) + "(" + DoubleToString(MathAbs(PnL / AccountBalance()) * 100.0, p_dig) + _C + ")";
pCol = NegativeColor;
}
_MG = "MaxGain:";
if(Tp == 0.0) _MGV = "TP not set";
else {
if(PP >= 1000.0) c_dig = 0; else c_dig = 2;
if(PP / AccountBalance() >= 1) p_dig = 0; else p_dig = 1;
_MGV = _A + DoubleToString(PP, c_dig) + "(" + DoubleToString(PP / AccountBalance() * 100.0, p_dig) + _C + ")";
}
_ML = "MaxLoss:";
if(Sl == 0.0) {
PL = l * -SD / _Point * tickvalue;
} else {
PL = l * (a - Sl) / _Point * tickvalue; // Mic v1.62
PL += (c + s); // Mic v1.66
}
if(PL >= 0) {
_ML = "Secured:";
lCol = PositiveColor;
}
PL = MathAbs(PL); // Mic v1.62
if(PL >= 1000.0) c_dig = 0; else c_dig = 2;
if(PL / AccountBalance() >= 1) p_dig = 0; else p_dig = 1;
_MLV = _A + DoubleToString(PL, c_dig) + "(" + DoubleToString(PL / AccountBalance() * 100.0, p_dig) + _C + ")";
tCol = DarkOrange;
ThinLines(true);
}
color fmpCol = NeutralColor;
if(Fmp > MarginLimit) fmpCol = MediumSpringGreen;
if(Fmp < 100.00) fmpCol = Orange;
if(Fmp < 80.00) fmpCol = OrangeRed;
if(Fmp < 65.00) fmpCol = Red;
if(Fmp == 0.00) fmpCol = NeutralColor;
if(Fmp != 0.00) _Fmp = DoubleToString(Fmp, 2) + _C;
else _Fmp = " ";
char ts = 19;
if(Fmp < 10000) ts = 24;
if(Fmp < 1000) ts = 26;
if(Fmp < 100) ts = 30;
_mLimit = IntegerToString(MarginLimit) + _C;
if(MarginLimit == 100) mCol = NegativeColor;
Label(_LAB02, CORNER_RIGHT_UPPER, (int)(151*DPIScaling), (int)(385*DPIScaling), _MG, 9, LabelColor, _MFONT, ANCHOR_LEFT_UPPER);
Label(_LAB03, CORNER_RIGHT_UPPER, (int)(151*DPIScaling), (int)(400*DPIScaling), _ML, 9, LabelColor, _MFONT, ANCHOR_LEFT_UPPER);
Label(_VAL01, CORNER_RIGHT_UPPER, (int)(151*DPIScaling), (int)(335*DPIScaling), _Trades, 9, tCol, _MFONT, ANCHOR_LEFT_UPPER);
Label(_VAL02, CORNER_RIGHT_UPPER, (int)(151*DPIScaling), (int)(350*DPIScaling), _Avl, 9, tCol, _MFONT, ANCHOR_LEFT_UPPER);
Label(_VAL03, CORNER_RIGHT_UPPER, (int)(151*DPIScaling), (int)(365*DPIScaling), _PnL, fs, pCol, _F, ANCHOR_LEFT_UPPER);
Label(_VAL04, CORNER_RIGHT_UPPER, 5, (int)(385*DPIScaling), _MGV, fs, NeutralColor, _F , ANCHOR_RIGHT_UPPER);
Label(_VAL05, CORNER_RIGHT_UPPER, 5, (int)(400*DPIScaling), _MLV, fs, lCol, _F , ANCHOR_RIGHT_UPPER);
//Label(_VAL06, CORNER_RIGHT_UPPER, 80, 178, _mLimit, 16, mCol, _MFONT, ANCHOR_CENTER); // Mic v1.65 remove
Label(_VAL07, CORNER_RIGHT_LOWER, (int)(80*DPIScaling), (int)(80*DPIScaling), _Fmp, ts, fmpCol, _MFONT, ANCHOR_CENTER);
// v1.65 Mic added for Margin limit edit field. This update edit field with arrows
// Edit field replace clasic Label
Edit(_VAL06E, (int)(115*DPIScaling), (int)(187*DPIScaling), 74, 30, _mLimit, _MFONT, 16, ALIGN_CENTER, CORNER_RIGHT_UPPER, mCol, BackgroundColor, BackgroundColor);
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void MakeStats () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Displays account stats and server error messages. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
int ErrorCode, xO = 87;
datetime ErrorTime;
string _Err;
if(!GlobalVariableCheck(_gErrorCode)) ErrorCode = ERR_NO_MESSAGE_YET;
else ErrorCode = int(GlobalVariableGet(_gErrorCode));
ErrorTime = datetime(GlobalVariableGet(_gErrorTime));
double Equity = AccountEquity();
double Balance = AccountBalance() + AccountCredit();
double Sbalance = GlobalVariableGet(_gSbalance);
double SessPL = Equity - Sbalance;
double SessPer = Divide(SessPL, Sbalance) * 100;
int c_dig = 2, p_dig = 1;
if(MathAbs(SessPL) >= 1000.0) c_dig = 0;
if(MathAbs(SessPer) >= 100) p_dig = 0;
string _Balance = _A + DoubleToString(Balance, 2);
string _Equity = _A + DoubleToString(Equity, 2);
string _SessPer = DoubleToString(MathAbs(SessPer), p_dig) + _C;
string _Sess = _A + DoubleToString(MathAbs(SessPL), c_dig) + "(" + _SessPer + ")";
color EqCol = NeutralColor;
color PLCol = NeutralColor;
color PerCol = NeutralColor;
if(Balance > Equity) EqCol = NegativeColor;
if(Balance < Equity) EqCol = PositiveColor;
if(SessPL < 0) PLCol = NegativeColor;
if(SessPL > 0) PLCol = PositiveColor;
if(SessPer < 0) PerCol = NegativeColor;
if(SessPer > 0) PerCol = PositiveColor;
if(ErrorCode == ERR_NO_MESSAGE_YET) _Err = ErrorString(ErrorCode);
else _Err = StringConcatenate("(", TimeToStr(ErrorTime, TIME_MINUTES), ") ", ErrorString(ErrorCode));
// list of server stats
Label(_VAL21, CORNER_LEFT_LOWER, (int)(43*DPIScaling), (int)(18*DPIScaling), _Err, 7, NeutralColor, _MFONT, ANCHOR_LEFT_LOWER);
// list of account stats
Label(_VAL22, CORNER_RIGHT_LOWER, (int)(4*DPIScaling), (int)(166*DPIScaling), _Balance, fs, NeutralColor, _F, ANCHOR_RIGHT_LOWER);
Label(_VAL23, CORNER_RIGHT_LOWER, (int)(4*DPIScaling), (int)(151*DPIScaling), _Equity, fs, EqCol, _F, ANCHOR_RIGHT_LOWER);
Label(_VAL24, CORNER_RIGHT_LOWER, (int)(4*DPIScaling), (int)(136*DPIScaling), _Sess, fs, PerCol, _F, ANCHOR_RIGHT_LOWER);
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void ShowSpread () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Displays current and average spread. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
double bidprice = Bid; double askprice = Ask;
double spread = (askprice - bidprice) / Pt;
double SpreadHistorySum = 0.0;
ArrayCopy(SpreadHistory, SpreadHistory, 0, 1, 99);
SpreadHistory[99] = spread;
if(SpreadHistoryCount < 100) SpreadHistoryCount++;
for(int i = 99; i >= 100 - SpreadHistoryCount; i--) SpreadHistorySum += SpreadHistory[i];
SpreadAverage = SpreadHistorySum / SpreadHistoryCount;
string _s = DoubleToStr(spread, 1) + " @" + DoubleToStr(SpreadAverage, 1);
// spread
Label(_VAL47, CORNER_RIGHT_LOWER, (int)(150*DPIScaling), (int)(5*DPIScaling), _s, 11, NeutralColor, _MFONT, ANCHOR_LEFT_LOWER);
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void CandleTime () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Displays the remaining time to the close of current candle. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
static datetime last_timecurrent;
static string _OldCandleTime;
int secondsleft;
int TimeShift = int(TimeLocal() - TimeCurrent());
int LocalHoursShift = int(MathRound(TimeShift / 3600.0));
if(IsTesting()) {
if(TimeCurrent() - last_timecurrent == 0) return;
last_timecurrent = TimeCurrent();
} else {
if(TimeLocal() - last_timecurrent == 0) return;
last_timecurrent = TimeLocal();
}
if(_Period < PERIOD_W1) {
if(IsTesting()) secondsleft = int(Time[0] + PeriodSeconds(_Period) - TimeCurrent());
else secondsleft = int(Time[0] + LocalHoursShift * 3600 + PeriodSeconds(_Period) - TimeLocal());
int s = secondsleft % 60;
int m = ((secondsleft - s) / 60) % 60;
int h = ((secondsleft - s - m * 60) / 3600) % 24;
int d = (secondsleft - s - m * 60 - h * 3600) / 86400;
string _CandleTime;
color CCol = NeutralColor;
if(secondsleft>=0 && h == 0 && d == 0) {
_CandleTime= StringSubstr(TimeToStr(secondsleft, TIME_MINUTES|TIME_SECONDS), 3);
} else if(secondsleft >= 0 && d > 0) {
_CandleTime = StringConcatenate(d, "_", h, ":", StringSubstr(TimeToStr(secondsleft, TIME_MINUTES|TIME_SECONDS), 3));
} else if(secondsleft >= 0 && h > 0) {
_CandleTime = StringConcatenate(h, ":", StringSubstr(TimeToStr(secondsleft, TIME_MINUTES|TIME_SECONDS), 3));
} else if(h == 0 && d == 0) {
CCol=Red;
_CandleTime = StringSubstr(TimeToStr(-1 * secondsleft, TIME_MINUTES|TIME_SECONDS), 3);
} else if(d == 0) {
CCol=Red;
_CandleTime = StringConcatenate(-1 * h, ":", StringSubstr(TimeToStr(-1 * secondsleft, TIME_MINUTES|TIME_SECONDS), 3));
} else {
CCol=Red;
_CandleTime = StringConcatenate(-1 * d, "_", -1 * h, ":", StringSubstr(TimeToStr(-1 * secondsleft, TIME_MINUTES|TIME_SECONDS), 3));
}
if(_CandleTime != _OldCandleTime) {
Label(_VAL48, CORNER_RIGHT_LOWER, (int)(6*DPIScaling), (int)(3*DPIScaling), _CandleTime, 15, CCol, _CFONT, ANCHOR_RIGHT_LOWER);
_OldCandleTime = _CandleTime;
//WindowRedraw();
ChartRedraw(0);
}
}
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void MakePriceLine () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Take care about the priceline. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
double lp = ChartGetDouble(CID, CHART_PRICE_MIN);
double hp = ChartGetDouble(CID, CHART_PRICE_MAX);
if (ObjectFind(_PLINE) < 0) {
ObjectCreate(_PLINE, OBJ_HLINE, 0, 0, 0);
ObjectSet(_PLINE, OBJPROP_WIDTH, PriceLineWidth);
ObjectSet(_PLINE, OBJPROP_STYLE, PriceLineStyle);
ObjectSet(_PLINE, OBJPROP_BACK, true);
ObjectSet(_PLINE, OBJPROP_SELECTABLE, true);
ObjectSet(_PLINE, OBJPROP_SELECTED, true);
ObjectSet(_PLINE, OBJPROP_PRICE1, NormalizeDouble((hp + lp) / 2.0, _Digits));
} else {
double p = ObjectGet(_PLINE, OBJPROP_PRICE1);
double bs = ObjectGet(_BSMARK, OBJPROP_PRICE1);
double ss = ObjectGet(_SSMARK, OBJPROP_PRICE1);
switch(TradeMode) {
case TRADE_BUY: if(p > Ask) {
ObjectSet(_PLINE, OBJPROP_COLOR, LimeGreen);
LineMode = LINE_TP;
} else if(p < Bid) {
ObjectSet(_PLINE, OBJPROP_COLOR, Red);
LineMode = LINE_SL;
} else {
ObjectSet(_PLINE, OBJPROP_COLOR, DarkGray);
LineMode = LINE_INVALID;
}
if(p < bs) ObjectSet(_PLINE, OBJPROP_PRICE1, bs);
break;
case TRADE_SELL: if(p < Bid) {
ObjectSet(_PLINE, OBJPROP_COLOR, LimeGreen);
LineMode = LINE_TP;
} else if(p > Ask) {
ObjectSet(_PLINE, OBJPROP_COLOR, Red);
LineMode = LINE_SL;
} else {
ObjectSet(_PLINE, OBJPROP_COLOR, DarkGray);
LineMode = LINE_INVALID;
}
if(p > ss) ObjectSet(_PLINE, OBJPROP_PRICE1, ss);
break;
}
}
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void SelectLine () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// This code 'selects' the priceline - it's desirable that it's always 'selected', to be able to move it instantly. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
if(ObjectFind(_PLINE ) != -1)
if(!ObjectGet(_PLINE , OBJPROP_SELECTED)) ObjectSet(_PLINE , OBJPROP_SELECTED, true);
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
bool SoundsOn () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Inquiry if sounds are enabled. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
return(bool(GlobalVariableGet(StringConcatenate(_gSoundsOn))));
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
bool AutoAdd () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Inquiry if auto additions (pyramiding) are enabled. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
return(bool(GlobalVariableGet(StringConcatenate(_gAutoAdd))));
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void Click () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Play click sound if sounds are enabled. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
if(SoundsOn()) PlaySound("::Sounds\\click.wav");
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void ThinLines (bool show) {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Show / hide thin lines. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
if(show) {
Bitmap(_PTHL02, CORNER_RIGHT_UPPER, (int)(4*DPIScaling), (int)(380*DPIScaling), 152, 5, _BMP_THIN);
Bitmap(_PTHL03, CORNER_RIGHT_UPPER, (int)(4*DPIScaling), (int)(415*DPIScaling), 152, 5, _BMP_THIN);
} else {
if(ObjectFind(CID, _PTHL02) != -1) ObjectDelete(CID, _PTHL02);
if(ObjectFind(CID, _PTHL03) != -1) ObjectDelete(CID, _PTHL03);
}
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void SetFont (double value) {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Set font size. Decrease if numbers become too large. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
if(value >= 10000.0) {
_F = _DFONT;
fs = 10;
} else {
_F = _MFONT;
fs = 9;
}
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void DefineGlobals () {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Read / define global variables. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
_gSbalance = StringConcatenate(_ID, AccountNumber(), "_gSbalance");
if(!GlobalVariableCheck(_gSbalance)) SessionReset(true);
_gSoundsOn = StringConcatenate(_ID, AccountNumber(), "_", _Symbol,"_gSoundsOn");
if(!GlobalVariableCheck(_gSoundsOn)) GlobalVariableSet(_gSoundsOn, true);
_gAutoAdd = StringConcatenate(_ID, AccountNumber(), "_", _Symbol,"_gAutoAdd");
if(!GlobalVariableCheck(_gAutoAdd)) GlobalVariableSet(_gAutoAdd, false);
_gMarginLimit = StringConcatenate(_ID, AccountNumber(), "_", _Symbol,"_gMarginLimit");
if(!GlobalVariableCheck(_gMarginLimit)) GlobalVariableSet(_gMarginLimit, 200.00);
_gIsTrading = StringConcatenate(_ID, AccountNumber(), "_gIsTrading");
if(!GlobalVariableCheck(_gIsTrading)) GlobalVariableSet(_gIsTrading, false);
_gErrorCode = StringConcatenate(_ID, AccountNumber(), "_", _Symbol, "_gErrorCode");
_gErrorTime = StringConcatenate(_ID, AccountNumber(), "_", _Symbol, "_gErrorTime");
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
void SessionReset (bool force = false) {
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
// Reset the stats upon push of the RESET button. |
// ---------------------------------------------------------------------------------------------------------------------------------------------------+
if(ObjectGetInteger(CID, _ID + "Reset", OBJPROP_STATE) || force) {
ObjectSetInteger(CID, _ID + "Reset", OBJPROP_STATE, false);
GlobalVariableSet(_gSbalance, AccountBalance() + AccountCredit());
}
}
//+------------------------------------------------------------------------------------------------------------------------------------------------------+