ProfitLossCalculator/profitlosscalculatorRone.mqh

805 lines
31 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:17:29 +02:00
//+------------------------------------------------------------------+
//| ProfitLossCalculatorRone.mqh |
//| Copyright 2013, Rone |
//| rone.sergey@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, Rone"
#property link "rone.sergey@gmail.com"
#property version "1.00"
#property description "Profit Loss Calculator"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include <Controls\Dialog.mqh>
#include <Controls\RadioButton.mqh>
#include <Controls\Button.mqh>
#include <Controls\Label.mqh>
#include <Controls\SpinEdit.mqh>
#include <Controls\Edit.mqh>
#include <ChartObjects\ChartObjectsLines.mqh>
#include <Trade\SymbolInfo.mqh>
#include "DoubleSpinEdit.mqh"
//+------------------------------------------------------------------+
//| defines |
//+------------------------------------------------------------------+
#define INDENT_LEFT (11) // indent from left (with allowance for border width)
#define INDENT_TOP (11) // indent from top (with allowance for border width)
#define INDENT_RIGHT (11) // indent from right (with allowance for border width)
#define INDENT_BOTTOM (11) // indent from bottom (with allowance for border width)
#define CONTROLS_GAP_X (5) // gap by X coordinate
#define CONTROLS_GAP_Y (5) // gap by Y coordinate
//---
#define CONTROLS_WIDTH (70)
#define CONTROLS_HEIGHT (20)
#define EDIT_WIDTH (80)
//---
#define FIELDS_TOTAL (6)
#define LINES_TOTAL (3)
#define RADIO_TOTAL (2)
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
enum EDIT_ALIAS
{
ENTRY_EDIT = 0,
LOT_EDIT = 1,
LOSS_PIPS_EDIT = 2,
PROFIT_PIPS_EDIT = 3,
LOSS_MONEY_EDIT = 4,
PROFIT_MONEY_EDIT = 5
};
enum LINE_ALIAS
{
ENTRY_LINE = 0,
LOSS_LINE = 1,
PROFIT_LINE = 2
};
//---
string label_name[FIELDS_TOTAL] =
{
"EntryLabel", "LotLabel", "LossPipsLabel", "ProfitPipsLabel", "LossMoneyLabel", "ProfitMoneyLabel"
};
string label_text[FIELDS_TOTAL] =
{
"Entry:", "Lot:", "Loss, pips:", "Profit, pips:", "Loss, ", "Profit, "
};
string spinedit_name[FIELDS_TOTAL] =
{
"EntryEdit", "LotEdit", "LossPipsEdit", "ProfitPipsEdit", "LossMoneyEdit", "ProfitMoneyEdit"
};
string line_name[LINES_TOTAL] = { "PLC_EntryLine", "PLC_LossLine", "PLC_ProfitLine" };
color line_color[LINES_TOTAL] = { clrOrange, clrRed, clrGreen };
string radio_name[RADIO_TOTAL] = { "Buy", "Sell" };
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CProfitLossCalculatorRone : public CAppDialog
{
private:
CSymbolInfo m_sym;
long m_order_type;
double m_entry_price;
double m_stop_price;
double m_profit_price;
double m_lot_value;
//---
CRadioButton m_type_radio[RADIO_TOTAL];
CButton m_reset_button;
CLabel m_label[FIELDS_TOTAL];
CDoubleSpinEdit m_spinedit[FIELDS_TOTAL];
CChartObjectHLine m_line[LINES_TOTAL];
public:
CProfitLossCalculatorRone();
~CProfitLossCalculatorRone();
virtual bool Create(const long chart, const string name, const int subwin,
const int x1, const int y1, const int x2, const int y2);
virtual bool OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam);
virtual bool OnEventLine(const int id, const long &lparam, const double &dparam, const string &sparam);
protected:
//--- create lines and controls
bool CreateLines();
bool CreateRadioButtons();
bool CreateResetButton();
bool CreateLabels();
bool CreateDoubleSpinEdits();
//--- handlers of the dependent controls events
bool OnChangeType(int index);
bool OnChangeDoubleSpinEdit(int index);
void OnChangeEntry();
void OnChangeLot();
void OnChangeLossPips();
void OnChangeProfitPips();
void OnChangeLossMoney();
void OnChangeProfitMoney();
void OnChangeEntryLine();
void OnChangeLossLine();
void OnChangeProfitLine();
//---
void ResetData();
void UpdateProfitLoss();
int LossPips();
int MaxLossPips();
int ProfitPips();
int MaxProfitPips();
double CalculateMoney(double exit_price);
double LossMoney();
double MinLossMoney();
double MaxLossMoney();
double ProfitMoney();
double MinProfitMoney();
double MaxProfitMoney();
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CProfitLossCalculatorRone::CProfitLossCalculatorRone()
{
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CProfitLossCalculatorRone::~CProfitLossCalculatorRone()
{
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CProfitLossCalculatorRone)
ON_INDEXED_EVENT(ON_CHANGE, m_type_radio, OnChangeType)
ON_EVENT(ON_CLICK, m_reset_button, ResetData)
ON_INDEXED_EVENT(ON_CHANGE, m_spinedit, OnChangeDoubleSpinEdit)
EVENT_MAP_END(CAppDialog)
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CProfitLossCalculatorRone::Create(const long chart, const string name, const int subwin,
const int x1, const int y1, const int x2, const int y2)
{
//---
bool ok = true;
ok &= CreateLines();
ok &= CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2);
ok &= CreateRadioButtons();
ok &= CreateResetButton();
ok &= CreateLabels();
ok &= CreateDoubleSpinEdits();
ResetData();
//---
return(ok);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CProfitLossCalculatorRone::CreateLines(void)
{
//---
bool ok = true;
for(int i = 0; i < LINES_TOTAL; i++)
{
if(ObjectFind(0, line_name[i]) < 0)
{
ok = m_line[i].Create(0, line_name[i], 0, 0.0);
ok &= m_line[i].Color(line_color[i]);
ok &= m_line[i].Selectable(true);
if(!ok)
{
return(false);
}
}
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CProfitLossCalculatorRone::CreateRadioButtons(void)
{
//---
int x1 = INDENT_LEFT;
int y1 = INDENT_TOP;
int x2 = x1 + CONTROLS_WIDTH;
int y2 = y1 + CONTROLS_HEIGHT;
bool ok = true;
for(int i = 0; i < RADIO_TOTAL; i++)
{
ok = m_type_radio[i].Create(m_chart_id, m_name+radio_name[i], m_subwin, x1, y1, x2, y2);
ok &= m_type_radio[i].Text(radio_name[i]);
ok &= Add(m_type_radio[i]);
if(!ok)
{
return(false);
}
x1 = x2 + CONTROLS_GAP_X;
x2 = x1 + CONTROLS_WIDTH;
}
ok &= m_type_radio[0].State(true);
//---
return(ok);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CProfitLossCalculatorRone::CreateResetButton(void)
{
//---
int x1 = INDENT_LEFT + 2 * CONTROLS_WIDTH + 3 * CONTROLS_GAP_X + EDIT_WIDTH;
int y1 = INDENT_TOP;
int x2 = x1 + EDIT_WIDTH;
int y2 = y1 + CONTROLS_HEIGHT;
bool ok = m_reset_button.Create(m_chart_id, m_name+"ResetButton", m_subwin, x1, y1, x2, y2);
ok &= m_reset_button.Text("Reset");
ok &= Add(m_reset_button);
//---
return(ok);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CProfitLossCalculatorRone::CreateLabels(void)
{
//---
int x1, x2, y1, y2;
bool ok = true;
string currency = AccountInfoString(ACCOUNT_CURRENCY);
for(int row = 1, index = 0; row <= 3; row++)
{
y1 = INDENT_TOP + row * (CONTROLS_HEIGHT + CONTROLS_GAP_Y);
y2 = y1 + CONTROLS_HEIGHT;
for(int col = 0; col < 2; col++)
{
x1 = INDENT_LEFT + col * (CONTROLS_WIDTH + EDIT_WIDTH + 2 * CONTROLS_GAP_X);
x2 = x1 + CONTROLS_WIDTH;
string text = label_text[index];
if(index == LOSS_MONEY_EDIT || index == PROFIT_MONEY_EDIT)
{
text += currency + ":";
}
ok &= m_label[index].Create(m_chart_id, m_name+label_name[index], m_subwin, x1, y1, x2, y2);
ok &= m_label[index].Text(text);
ok &= Add(m_label[index]);
if(!ok)
{
return(false);
}
index += 1;
}
}
//---
return(ok);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CProfitLossCalculatorRone::CreateDoubleSpinEdits(void)
{
//---
int x1, x2, y1, y2;
bool ok = true;
for(int row = 1, index = 0; row <= 3; row++)
{
y1 = INDENT_TOP + row * (CONTROLS_HEIGHT + CONTROLS_GAP_Y);
y2 = y1 + CONTROLS_HEIGHT;
for(int col = 0; col < 2; col++)
{
x1 = INDENT_LEFT + CONTROLS_WIDTH + CONTROLS_GAP_X
+ col * (CONTROLS_WIDTH + EDIT_WIDTH + 2 * CONTROLS_GAP_X);
x2 = x1 + EDIT_WIDTH;
ok &= m_spinedit[index].Create(m_chart_id, m_name+spinedit_name[index], m_subwin, x1, y1, x2, y2);
ok &= m_spinedit[index].ReadOnly(false);
ok &= Add(m_spinedit[index]);
if(!ok)
{
return(false);
}
PrintFormat("ok: SpinEdit[%d,%s].Create(%d,%s,%d,%d,%d,%d,%d) ... x2-x1=%d y2-y1=%d",index,EnumToString((EDIT_ALIAS)index),
m_chart_id, m_name+spinedit_name[index], m_subwin, x1, y1, x2, y2, x2-x1, y2-y1);
index += 1;
}
}
//---
return(ok);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CProfitLossCalculatorRone::ResetData(void)
{
//---
bool ok = false;
double min_price = 0.0, max_price = 0.0;
m_sym.Name(_Symbol);
for(int tries = 1; tries < 5; tries++)
{
if(m_sym.IsSynchronized() && m_sym.Refresh()
&& ChartGetDouble(m_chart_id, CHART_PRICE_MIN, m_subwin, min_price)
&& ChartGetDouble(m_chart_id, CHART_PRICE_MAX, m_subwin, max_price))
{
ok = true;
break;
}
Sleep(1000);
}
if(ok)
{
//--- members
m_order_type = (long)ORDER_TYPE_BUY;
m_entry_price = NormalizeDouble((max_price+min_price)/2, m_sym.Digits());
m_stop_price = NormalizeDouble(m_entry_price-(m_entry_price-min_price)/2, m_sym.Digits());
m_profit_price = NormalizeDouble(max_price-(max_price-m_entry_price)/2, m_sym.Digits());
m_lot_value = NormalizeDouble(10*m_sym.LotsMin(), 2);
//--- lines
m_line[ENTRY_LINE].Price(0, m_entry_price);
m_line[LOSS_LINE].Price(0, m_stop_price);
m_line[PROFIT_LINE].Price(0, m_profit_price);
for(int i = 0; i < LINES_TOTAL; i++)
{
m_line[i].Selected(false);
}
//--- controls
m_type_radio[0].State(true);
m_type_radio[1].State(false);
m_spinedit[ENTRY_EDIT].SetParameters(m_entry_price, min_price, max_price, 100*m_sym.TickSize(), m_sym.Digits());
m_spinedit[LOT_EDIT].SetParameters(m_lot_value, m_sym.LotsMin(), m_sym.LotsMax(), 10*m_sym.LotsStep(),
(int)NormalizeDouble(MathCeil(MathLog10(1/m_sym.LotsStep())), 0));
UpdateProfitLoss();
}
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CProfitLossCalculatorRone::UpdateProfitLoss(void)
{
//---
m_spinedit[LOSS_PIPS_EDIT].SetParameters(LossPips(), m_sym.StopsLevel(), MaxLossPips(),
100*m_sym.TickSize()/m_sym.Point(), 0);
m_spinedit[PROFIT_PIPS_EDIT].SetParameters(ProfitPips(), m_sym.StopsLevel(), MaxProfitPips(),
100*m_sym.TickSize()/m_sym.Point(), 0);
m_spinedit[LOSS_MONEY_EDIT].SetParameters(LossMoney(), MinLossMoney(),
MaxLossMoney(), 10, 2);
m_spinedit[PROFIT_MONEY_EDIT].SetParameters(ProfitMoney(), MinProfitMoney(),
MaxProfitMoney(), 10, 2);
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CProfitLossCalculatorRone::LossPips(void)
{
return(int(MathAbs(MathRound((m_entry_price - m_stop_price)/m_sym.Point()))));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CProfitLossCalculatorRone::MaxLossPips(void)
{
double price = ((m_order_type == (long)ORDER_TYPE_BUY)
? m_spinedit[ENTRY_EDIT].MinValue() : m_spinedit[ENTRY_EDIT].MaxValue());
return(int(MathAbs(MathRound((m_entry_price - price)/m_sym.Point()))) + m_sym.StopsLevel());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CProfitLossCalculatorRone::ProfitPips(void)
{
return(int(MathAbs(MathRound((m_entry_price - m_profit_price)/m_sym.Point()))));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CProfitLossCalculatorRone::MaxProfitPips(void)
{
double price = ((m_order_type == (long)ORDER_TYPE_BUY)
? m_spinedit[ENTRY_EDIT].MaxValue() : m_spinedit[ENTRY_EDIT].MinValue());
return(int(MathAbs(MathRound((m_entry_price - price)/m_sym.Point()))) + m_sym.StopsLevel());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CProfitLossCalculatorRone::CalculateMoney(double exit_price)
{
double result = 0.0;
ResetLastError();
if(!OrderCalcProfit((ENUM_ORDER_TYPE)m_order_type, m_sym.Name(), m_lot_value,
m_entry_price, exit_price, result))
{
Print(__FUNCTION__, ": calculating money failed. Error #", GetLastError());
}
//---
return(NormalizeDouble(MathAbs(result), 2));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CProfitLossCalculatorRone::LossMoney(void)
{
return(CalculateMoney(m_stop_price));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CProfitLossCalculatorRone::MinLossMoney(void)
{
double price = ((m_order_type == (long)ORDER_TYPE_BUY)
? m_entry_price - m_sym.StopsLevel() * m_sym.Point()
: m_entry_price + m_sym.StopsLevel() * m_sym.Point());
return(CalculateMoney(price));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CProfitLossCalculatorRone::MaxLossMoney(void)
{
double price = ((m_order_type == (long)ORDER_TYPE_BUY)
? m_spinedit[ENTRY_EDIT].MinValue() - m_sym.StopsLevel() * m_sym.Point()
: m_spinedit[ENTRY_EDIT].MaxValue() + m_sym.StopsLevel() * m_sym.Point());
return(CalculateMoney(price));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CProfitLossCalculatorRone::ProfitMoney(void)
{
return(CalculateMoney(m_profit_price));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CProfitLossCalculatorRone::MinProfitMoney(void)
{
double price = ((m_order_type == (long)ORDER_TYPE_BUY)
? m_entry_price + m_sym.StopsLevel() * m_sym.Point()
: m_entry_price - m_sym.StopsLevel() * m_sym.Point());
return(CalculateMoney(price));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CProfitLossCalculatorRone::MaxProfitMoney(void)
{
double price = ((m_order_type == (long)ORDER_TYPE_BUY)
? m_spinedit[ENTRY_EDIT].MaxValue() + m_sym.StopsLevel() * m_sym.Point()
: m_spinedit[ENTRY_EDIT].MinValue() - m_sym.StopsLevel() * m_sym.Point());
return(CalculateMoney(price));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CProfitLossCalculatorRone::OnChangeType(int index)
{
//---
if(m_type_radio[index].State())
{
int other_index = MathAbs(index-1);
bool other_prev_state = m_type_radio[other_index].State();
m_type_radio[other_index].State(false);
m_order_type = (index == 0) ? (long)ORDER_TYPE_BUY : (long)ORDER_TYPE_SELL;
if(other_prev_state != m_type_radio[other_index].State())
{
double tmp = m_stop_price;
m_stop_price = m_profit_price;
m_profit_price = tmp;
m_line[LOSS_LINE].Price(0, m_stop_price);
m_line[PROFIT_LINE].Price(0, m_profit_price);
UpdateProfitLoss();
}
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CProfitLossCalculatorRone::OnChangeDoubleSpinEdit(int index)
{
//---
switch(index)
{
case ENTRY_EDIT:
OnChangeEntry();
break;
case LOT_EDIT:
OnChangeLot();
break;
case LOSS_PIPS_EDIT:
OnChangeLossPips();
break;
case PROFIT_PIPS_EDIT:
OnChangeProfitPips();
break;
case LOSS_MONEY_EDIT:
OnChangeLossMoney();
break;
case PROFIT_MONEY_EDIT:
OnChangeProfitMoney();
break;
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CProfitLossCalculatorRone::OnChangeEntry(void)
{
//---
double new_entry = m_spinedit[ENTRY_EDIT].Value();
double valid_max = MathMax(m_stop_price, m_profit_price) - m_sym.StopsLevel() * m_sym.Point();
double valid_min = MathMin(m_stop_price, m_profit_price) + m_sym.StopsLevel() * m_sym.Point();
if(new_entry > valid_max || new_entry < valid_min)
{
m_spinedit[ENTRY_EDIT].Value(m_entry_price);
return;
}
if(new_entry != m_entry_price)
{
m_entry_price = new_entry;
m_line[ENTRY_LINE].Price(0, m_entry_price);
m_spinedit[LOSS_PIPS_EDIT].Value(LossPips());
m_spinedit[PROFIT_PIPS_EDIT].Value(ProfitPips());
m_spinedit[LOSS_MONEY_EDIT].Value(LossMoney());
m_spinedit[PROFIT_MONEY_EDIT].Value(ProfitMoney());
}
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CProfitLossCalculatorRone::OnChangeLot(void)
{
//---
double new_lot = m_spinedit[1].Value();
if(new_lot != m_lot_value)
{
m_lot_value = new_lot;
UpdateProfitLoss();
}
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CProfitLossCalculatorRone::OnChangeLossPips(void)
{
//---
int old_value = LossPips();
int new_value = (int)m_spinedit[LOSS_PIPS_EDIT].Value();
if(new_value != old_value)
{
if(m_order_type == (long)ORDER_TYPE_BUY)
{
m_stop_price = NormalizeDouble(m_entry_price-new_value*m_sym.Point(), m_sym.Digits());
}
else
{
m_stop_price = NormalizeDouble(m_entry_price+new_value*m_sym.Point(), m_sym.Digits());
}
m_line[LOSS_LINE].Price(0, m_stop_price);
m_spinedit[LOSS_MONEY_EDIT].Value(LossMoney());
}
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CProfitLossCalculatorRone::OnChangeProfitPips(void)
{
//---
int old_value = ProfitPips();
int new_value = (int)m_spinedit[PROFIT_PIPS_EDIT].Value();
if(new_value != old_value)
{
if(m_order_type == (long)ORDER_TYPE_BUY)
{
m_profit_price = NormalizeDouble(m_entry_price+new_value*m_sym.Point(), m_sym.Digits());
}
else
{
m_profit_price = NormalizeDouble(m_entry_price-new_value*m_sym.Point(), m_sym.Digits());
}
m_line[PROFIT_LINE].Price(0, m_profit_price);
m_spinedit[PROFIT_MONEY_EDIT].Value(ProfitMoney());
}
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CProfitLossCalculatorRone::OnChangeLossMoney(void)
{
//---
double old_value = LossMoney();
double new_value = m_spinedit[LOSS_MONEY_EDIT].Value();
if(new_value != old_value)
{
int loss_pips = int(new_value/(m_lot_value*m_sym.TickValueLoss()));
m_spinedit[LOSS_PIPS_EDIT].Value(loss_pips);
if(m_order_type == (long)ORDER_TYPE_BUY)
{
m_stop_price = NormalizeDouble(m_entry_price-loss_pips*m_sym.Point(), m_sym.Digits());
}
else
{
m_stop_price = NormalizeDouble(m_entry_price+loss_pips*m_sym.Point(), m_sym.Digits());
}
m_line[LOSS_LINE].Price(0, m_stop_price);
}
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CProfitLossCalculatorRone::OnChangeProfitMoney(void)
{
//---
double old_value = ProfitMoney();
double new_value = m_spinedit[PROFIT_MONEY_EDIT].Value();
if(new_value != old_value)
{
int profit_pips = int(new_value/(m_lot_value*m_sym.TickValueProfit()));
m_spinedit[PROFIT_PIPS_EDIT].Value(profit_pips);
if(m_order_type == (long)ORDER_TYPE_BUY)
{
m_profit_price = NormalizeDouble(m_entry_price+profit_pips*m_sym.Point(), m_sym.Digits());
}
else
{
m_profit_price = NormalizeDouble(m_entry_price-profit_pips*m_sym.Point(), m_sym.Digits());
}
m_line[PROFIT_LINE].Price(0, m_profit_price);
}
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CProfitLossCalculatorRone::OnEventLine(const int id, const long &lparam,
const double &dparam,const string &sparam)
{
//---
if(id == CHARTEVENT_OBJECT_CHANGE || id == CHARTEVENT_OBJECT_DRAG)
{
if(sparam == line_name[ENTRY_LINE])
{
OnChangeEntryLine();
}
else
if(sparam == line_name[LOSS_LINE])
{
OnChangeLossLine();
}
else
if(sparam == line_name[PROFIT_LINE])
{
OnChangeProfitLine();
}
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CProfitLossCalculatorRone::OnChangeEntryLine(void)
{
//---
double new_price = NormalizeDouble(ObjectGetDouble(0, line_name[ENTRY_LINE], OBJPROP_PRICE), _Digits);
double stops_level = m_sym.StopsLevel() * m_sym.Point();
bool valid_buy_entry = (m_order_type == (long)ORDER_TYPE_SELL
&& new_price < m_stop_price - stops_level
&& new_price > m_profit_price + stops_level);
bool valid_sell_entry = (m_order_type == (long)ORDER_TYPE_BUY
&& new_price < m_profit_price - stops_level
&& new_price > m_stop_price + stops_level);
if(!valid_buy_entry && !valid_sell_entry)
{
m_line[ENTRY_LINE].Price(0, m_entry_price);
ChartRedraw();
return;
}
m_entry_price = new_price;
m_spinedit[ENTRY_EDIT].Value(new_price);
m_spinedit[LOSS_PIPS_EDIT].Value(LossPips());
m_spinedit[PROFIT_PIPS_EDIT].Value(ProfitPips());
m_spinedit[LOSS_MONEY_EDIT].Value(LossMoney());
m_spinedit[PROFIT_MONEY_EDIT].Value(ProfitMoney());
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CProfitLossCalculatorRone::OnChangeLossLine(void)
{
//---
double new_price = NormalizeDouble(ObjectGetDouble(0, line_name[LOSS_LINE], OBJPROP_PRICE), _Digits);
double stops_level = m_sym.StopsLevel() * m_sym.Point();
bool valid_buy_loss = (m_order_type == (long)ORDER_TYPE_BUY
&& new_price >= m_spinedit[ENTRY_EDIT].MinValue() - stops_level
&& new_price <= m_entry_price - stops_level);
bool valis_sell_loss = (m_order_type == (long)ORDER_TYPE_SELL
&& new_price <= m_spinedit[ENTRY_EDIT].MaxValue() + stops_level
&& new_price >= m_entry_price + stops_level);
if(!valid_buy_loss && !valis_sell_loss)
{
m_line[LOSS_LINE].Price(0, m_stop_price);
ChartRedraw();
return;
}
m_stop_price = new_price;
m_spinedit[LOSS_PIPS_EDIT].Value(LossPips());
m_spinedit[LOSS_MONEY_EDIT].Value(LossMoney());
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CProfitLossCalculatorRone::OnChangeProfitLine(void)
{
//---
double new_price = NormalizeDouble(ObjectGetDouble(0, line_name[PROFIT_LINE], OBJPROP_PRICE), _Digits);
double stops_level = m_sym.StopsLevel() * m_sym.Point();
bool valid_buy_profit = (m_order_type == (long)ORDER_TYPE_BUY
&& new_price <= m_spinedit[ENTRY_EDIT].MaxValue() + stops_level
&& new_price >= m_entry_price + stops_level);
bool valid_sell_profit = (m_order_type == (long)ORDER_TYPE_SELL
&& new_price >= m_spinedit[ENTRY_EDIT].MinValue() - stops_level
&& new_price <= m_entry_price - stops_level);
if(!valid_buy_profit && !valid_sell_profit)
{
m_line[PROFIT_LINE].Price(0, m_profit_price);
ChartRedraw();
return;
}
m_profit_price = new_price;
m_spinedit[PROFIT_PIPS_EDIT].Value(ProfitPips());
m_spinedit[PROFIT_MONEY_EDIT].Value(ProfitMoney());
//---
}
//+------------------------------------------------------------------+