forked from nique_372/MQLArticles
738 lines
26 KiB
MQL5
738 lines
26 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| Main.mqh |
| |
//| Copyright 2025, Niquel Mendoza. |
| |
//| https://www.mql5.com/es/users/nique_372/news |
| |
//+------------------------------------------------------------------+
| |
#property copyright "Copyright 2025, Niquel Mendoza."
| |
#property link "https://www.mql5.com/es/users/nique_372/news"
| |
#property strict
| |
| |
| |
//+------------------------------------------------------------------+
| |
//| Include |
| |
//+------------------------------------------------------------------+
| |
#define CACCOUNT_STATUS_ACTIVE_ON_POSITION_MODIFIED
| |
| |
//---
| |
// 1. Siempre primero as cases de MQLArticles
| |
#include "..\\..\\..\\PosMgmt\\Breakeven.mqh"
| |
#include <TSN\\Std\\PtrClean\\AutoDelete.mqh>
| |
#include <Trade\\SymbolInfo.mqh>
| |
| |
//---
| |
#define private public
| |
#define protected public
| |
// https://forge.mql5.io/nique_372/EasyAndFastMod
| |
| |
#include "..\\..\\..\\..\\EasyAndFastMod\\WndCreate.mqh"
| |
#undef private
| |
#undef protected
| |
| |
| |
//+------------------------------------------------------------------+
| |
//| Inputs |
| |
//+------------------------------------------------------------------+
| |
sinput group ""
| |
sinput group "-------| Account Status |-------"
| |
input ENUM_VERBOSE_LOG_LEVEL InpLogLevelAccountStatus = VERBOSE_LOG_LEVEL_ALL; //(Account Status|Ticket Mangement) log level:
| |
| |
sinput group ""
| |
sinput group "-------| Breakeven |-------"
| |
input TSN::ENUM_BREAKEVEN_TYPE InpBeType = TSN::BREAKEVEN_TYPE_RR; // Calculation method (RR, ATR, or fixed points)
| |
input ENUM_VERBOSE_LOG_LEVEL InpBeLogLevel = VERBOSE_LOG_LEVEL_ALL; // Break Even log level:
| |
| |
//+------------------------------------------------------------------+
| |
sinput group "--- Breakeven based on Risk/Reward (RR) ---"
| |
input string InpBeRrAdv = "Requires a configured Stop Loss."; // Warning: Stop Loss is required to calculate RR
| |
input double InpBeRrRatio = 1.0; // Risk/Reward ratio to activate Breakeven (e.g. 1.0)
| |
input TSN::ENUM_TYPE_EXTRA_BE_BY_RRR InpBeRrTypeExtra = TSN::EXTRA_BE_RRR_BY_ATR;// Method to adjust Breakeven price (ATR or points)
| |
input double InpBeRrExtraPointsOrAtrMultiplier = 1.0; // Adjustment value: ATR multiplier (atr 14 period) if method = ATR, or fixed points if method = Points
| |
| |
sinput group "--- Breakeven based solely on ATR ---"
| |
input double InpBeAtrMultiplier = 2.0; // ATR multiplier to trigger Breakeven (atr 14 period)
| |
input double InpBeAtrMultiplierExtra = 1.0; // Additional multiplier for precise Breakeven adjustment (atr 14 period)
| |
| |
sinput group "--- Breakeven based on fixed points ---"
| |
input int InpBeFixedPointsToPutBe = 200; // Minimum distance (in points) to trigger Breakeven
| |
input int InpBeFixedPointsExtra = 100; // Extra points added when Breakeven is triggered
| |
| |
//+------------------------------------------------------------------+
| |
//| Resource |
| |
//+------------------------------------------------------------------+
| |
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_up.bmp"
| |
#resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_down.bmp"
| |
#resource "\\Images\\EasyAndFastGUI\\Controls\\checkbox_off.bmp"
| |
#resource"\\Images\\EasyAndFastGUI\\Controls\\checkbox_on.bmp"
| |
| |
const static string image_array[2] =
| |
{
| |
"Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_up.bmp",
| |
"Images\\EasyAndFastGUI\\Icons\\bmp16\\arrow_down.bmp"
| |
};
| |
| |
| |
//+------------------------------------------------------------------+
| |
//| Defines |
| |
//+------------------------------------------------------------------+
| |
#define YSIZE_CAPTION 40
| |
#define X_OFFSET_PANEL 5
| |
#define Y_OFFSET_PANEL 5
| |
| |
#define TABLE_P_TICKET 0
| |
#define TABLE_P_TYPE 1
| |
#define TABLE_P_VOLUME 2
| |
#define TABLE_P_ENTRY 3
| |
#define TABLE_P_TAKEPROFIT 4
| |
#define TABLE_P_STOPLOSS 5
| |
#define TABLE_P_TRAILINGSTOP_CHECKBOX 6
| |
| |
#define PANEL_TABLE_IMAGE_IDX_UP 0
| |
#define PANEL_TABLE_IMAGE_IDX_DOWN 1
| |
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
#define BREAKEVEN_PANEL_MAX_POS (256)
| |
| |
//+------------------------------------------------------------------+
| |
//| Global variables |
| |
//+------------------------------------------------------------------+
| |
TSN::CAtrUltraOptimized atr_ultra_optimized;
| |
| |
| |
//+------------------------------------------------------------------+
| |
//| CBreakEvenPanel class |
| |
//+------------------------------------------------------------------+
| |
class CBreakEvenPanel : public CWndCreate
| |
{
| |
private:
| |
//---
| |
int m_width_panel;
| |
TSN::ENUM_BREAKEVEN_TYPE m_mode_breakeven;
| |
bool m_enable_to_trailing;
| |
| |
//---
| |
TSN::CBreakEven* m_breakevens[BREAKEVEN_PANEL_MAX_POS];
| |
CSymbolInfo* m_symbol_array[BREAKEVEN_PANEL_MAX_POS];
| |
int m_data_s;
| |
| |
TSN::ROnOpenPosition m_row_por_posicion[BREAKEVEN_PANEL_MAX_POS];
| |
int m_row_por_posicion_s;
| |
| |
//---
| |
CHashMapFast(string, int) m_hasmap_symbol_por_pos; // delveullve la poscoin en el array en base al simbolo
| |
CHashMapFastP(ulong, int, _fibbo) m_hashmap_pos_por_ticket; // em nase al ticket te da el idx en csymbol y trailing stop
| |
CHashMapFastP(ulong, int, _fibbo) m_hhasmap_ticket_row; // en base al ticket te da la psocion en el array de posiciones
| |
| |
//---
| |
CWindow m_window;
| |
CTabs m_tabs;
| |
| |
//---
| |
CTable m_table_principal;
| |
| |
//---
| |
CTextLabel m_label_text;
| |
CComboBox m_combox_be_type;
| |
CTextBox m_text_box1;
| |
| |
//---
| |
void OnChangeComboxTSL();
| |
void RedrawCompletePanel();
| |
| |
//---
| |
class CAccountGestorInt : public TSN::CAccountGestor
| |
{
| |
private:
| |
CBreakEvenPanel* m_padre;
| |
| |
public:
| |
//--- Constructor
| |
CAccountGestorInt(CBreakEvenPanel* p) : m_padre(p)
| |
{
| |
TSN::account_status.RegisterEvents(&this,
| |
ACCOUNT_STATUS_REG_FLAG_ON_CLOSE_POSITION |
| |
ACCOUNT_STATUS_REG_FLAG_ON_OPEN_POSITION |
| |
ACCOUNT_STATUS_REG_FLAG_ON_POSITION_MODIFY |
| |
ACCOUNT_STATUS_REG_FLAG_ON_INIT_NEW_POS);
| |
}
| |
| |
//--- Destructor
| |
~CAccountGestorInt(void)
| |
{
| |
if(TSN::account_status.IsActive())
| |
TSN::account_status.UnregisterEvents(&this,
| |
ACCOUNT_STATUS_REG_FLAG_ON_CLOSE_POSITION |
| |
ACCOUNT_STATUS_REG_FLAG_ON_OPEN_POSITION |
| |
ACCOUNT_STATUS_REG_FLAG_ON_POSITION_MODIFY |
| |
ACCOUNT_STATUS_REG_FLAG_ON_INIT_NEW_POS);
| |
}
| |
| |
//---
| |
void OnOpenPosition(const TSN::ROnOpenPosition &pos) override final { m_padre.OnOpenPosition(pos); }
| |
void OnClosePosition(const TSN::ROnClosePosition &pos, const int global_pos_index) override final { m_padre.OnClosePosition(pos, global_pos_index); }
| |
void OnPositionModify(const TSN::Position& pos, const uint8_t change_flags) override final { m_padre.OnPositionModify(pos, change_flags); }
| |
void OnInitNewPos(const TSN::ROnOpenPosition &position) override final { m_padre.OnInitNewPos(position); }
| |
};
| |
CAccountGestorInt* m_gestor;
| |
| |
| |
public:
| |
CBreakEvenPanel();
| |
~CBreakEvenPanel() { if(m_gestor != NULL) delete m_gestor; }
| |
| |
//---
| |
void OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam) override;
| |
void OnDeinitEvent(const int reason);
| |
void OnTickEvent();
| |
| |
//
| |
void OnOpenPosition(const TSN::ROnOpenPosition &pos);
| |
void OnClosePosition(const TSN::ROnClosePosition &pos, const int global_pos_index);
| |
void OnPositionModify(const TSN::Position& pos, const uint8_t change_flags);
| |
void OnInitNewPos(const TSN::ROnOpenPosition &position);
| |
| |
//---
| |
CAccountGestorInt* GetGestorInt() { return m_gestor; }
| |
| |
//---
| |
void CreateGUI(int WIDTH_PANEL, int HEIGHT_PANEL);
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
CBreakEvenPanel::CBreakEvenPanel(void)
| |
: m_row_por_posicion_s(0), m_data_s(0),
| |
m_hasmap_symbol_por_pos(BREAKEVEN_PANEL_MAX_POS), m_hashmap_pos_por_ticket(BREAKEVEN_PANEL_MAX_POS), m_hhasmap_ticket_row(BREAKEVEN_PANEL_MAX_POS),
| |
m_enable_to_trailing(false)
| |
{
| |
m_gestor = new CAccountGestorInt(&this);
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void CBreakEvenPanel::OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
| |
{
| |
if(id == CHARTEVENT_CUSTOM + ON_CLICK_CHECKBOX)
| |
{
| |
if(m_enable_to_trailing && lparam == m_table_principal.Id())
| |
{
| |
string res[];
| |
StringSplit(sparam, '_', res);
| |
int row = (int)StringToInteger(res[1]);
| |
//uint col = StringToInteger(res[1]);
| |
bool state = (bool)dparam;
| |
//Print(sparam);
| |
Print(state);
| |
| |
if(state)
| |
{
| |
const ulong pos = m_row_por_posicion[row].position.ticket;
| |
// pos
| |
| |
//--- Obtenemos la posicion en base al ticket
| |
int pos_index;
| |
m_hashmap_pos_por_ticket.TryGet(pos, pos_index);
| |
| |
//--- Agrgamos
| |
Print(pos);
| |
| |
m_breakevens[pos_index].obj.Add(pos);
| |
}
| |
else
| |
{
| |
const ulong pos = m_row_por_posicion[row].position.ticket;
| |
// pos
| |
| |
//--- Obtenemos la posicion en base al ticket
| |
int pos_index;
| |
m_hashmap_pos_por_ticket.TryGet(pos, pos_index);
| |
| |
//---
| |
m_breakevens[pos_index].obj.Remove(pos);
| |
}
| |
}
| |
return;
| |
}
| |
| |
if(id == CHARTEVENT_CUSTOM + ON_CLICK_COMBOBOX_ITEM)
| |
{
| |
if(lparam == m_combox_be_type.Id())
| |
{
| |
OnChangeComboxTSL();
| |
}
| |
return;
| |
}
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void CBreakEvenPanel::OnChangeComboxTSL(void)
| |
{
| |
//---
| |
const string slected = m_combox_be_type.GetValue();
| |
const int idx = m_combox_be_type.GetListViewPointer().SelectedItemIndex();
| |
TSN::ENUM_BREAKEVEN_TYPE mode = (TSN::ENUM_BREAKEVEN_TYPE)idx;
| |
| |
//---
| |
for(int k = 0; k < m_data_s; k++)
| |
m_breakevens[k].SetInternalPointer(mode);
| |
| |
//---
| |
for(int k = 0; k < (int)m_table_principal.RowsTotal(); k++)
| |
m_table_principal.ChangeImage(TABLE_P_TRAILINGSTOP_CHECKBOX, k, 0);
| |
| |
//---
| |
m_table_principal.Update(true);
| |
Print("Nuevo modo de breakeven: ", slected, " | ", TSN::g_breakevens_types_str[mode]);
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void CBreakEvenPanel::OnDeinitEvent(const int reason)
| |
{
| |
//---
| |
for(int i = 0; i < m_data_s; i++)
| |
{
| |
delete m_symbol_array[i];
| |
delete m_breakevens[i]; //cuidado no se elimna rel putnero interno eso lo hace account status
| |
}
| |
//---
| |
CWndEvents::Destroy();
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void CBreakEvenPanel::OnTickEvent(void)
| |
{
| |
for(int i = 0; i < m_data_s; i++)
| |
m_breakevens[i].obj.BreakEven();
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void CBreakEvenPanel::CreateGUI(int WIDTH_PANEL, int HEIGHT_PANEL)
| |
{
| |
//---
| |
this.m_mode_breakeven = InpBeType;
| |
| |
//---
| |
m_width_panel = fmax(WIDTH_PANEL, 200);
| |
| |
m_window.CaptionColor(clrGray);
| |
m_window.CaptionColorHover(clrGray);
| |
m_window.CaptionColorLocked(clrBlack);
| |
m_window.BorderColor(C'212,212,212');
| |
m_window.BackColorPressed(clrBlue);
| |
m_window.Font("Arial Black");
| |
CWndCreate::CreateWindow(m_window, "BreakevenManager", 0, 0, m_width_panel, HEIGHT_PANEL, true, false, true, true);
| |
| |
| |
//--- Tabs
| |
string texts[2] = { "General", "Configuracion"};
| |
int widts[2] = {100, 90};
| |
color clrs[2] = {clrNONE, clrNONE}; // defa
| |
| |
int x = m_window.X() + X_OFFSET_PANEL;
| |
int y = m_window.Y() + (YSIZE_CAPTION + Y_OFFSET_PANEL);
| |
| |
int xsize_tabs = (m_window.XSize()) - (X_OFFSET_PANEL * 2);
| |
int ysize_tabs = (m_window.YSize() - YSIZE_CAPTION) - (Y_OFFSET_PANEL * 2);
| |
| |
m_tabs.BackColor(C'191,191,191');
| |
m_tabs.BackColorPressed(C'201,203,205');
| |
CWndCreate::CreateTabs(m_tabs, m_window, 0, x, y, xsize_tabs, ysize_tabs, texts, widts, clrs, clrs);
| |
| |
//---
| |
#define X_OFFSET_INTERNO 7
| |
| |
x += X_OFFSET_INTERNO;
| |
y += 20;
| |
| |
int x_table = x;
| |
int y_table = y;
| |
| |
Print(m_tabs.YGap());
| |
Print(m_tabs.XGap());
| |
| |
//--- Pestaña 1
| |
#define COLS_TOTAL_TABLE 7
| |
string headers[COLS_TOTAL_TABLE] = {"Ticket", "Type", "Volume", "Entry", "Takeprofit", "Stoploss", "Breakeven"};
| |
| |
| |
| |
int xsize_table = xsize_tabs - (X_OFFSET_INTERNO * 2);
| |
int ysize_table = ysize_tabs - (Y_OFFSET_PANEL * 2) - (20); //tamaño util | tmaaño dellos offeset | tamaño del header tabs
| |
| |
#define HEADER_YSIZE_TABLE 30
| |
m_table_principal.HeaderYSize(HEADER_YSIZE_TABLE);
| |
| |
CWndCreate::CreateTable(m_table_principal, m_window, 0, m_tabs, 0, COLS_TOTAL_TABLE, 1, headers, x_table, y_table, xsize_table, ysize_table, false, false);
| |
| |
ENUM_ALIGN_MODE align[COLS_TOTAL_TABLE];
| |
::ArrayInitialize(align, ALIGN_LEFT);
| |
//align[TABLE_P_TYPE] = ALIGN_RIGHT;
| |
//align[TABLE_P_TRAILINGSTOP_CHECKBOX] = ALIGN_LEFT;
| |
| |
//Print(xsize_table);
| |
| |
//---
| |
int widths[COLS_TOTAL_TABLE];
| |
const double col_proportions[COLS_TOTAL_TABLE] = {0.162, 0.102, 0.122, 0.142, 0.142, 0.142, 0.182};
| |
int sum = 0;
| |
| |
for(int i = 0; i < COLS_TOTAL_TABLE; i++)
| |
{
| |
widths[i] = (int)(xsize_table * col_proportions[i]);
| |
sum += widths[i];
| |
}
| |
| |
int rest = xsize_table - sum;
| |
| |
widths[COLS_TOTAL_TABLE - 1] += rest < 0 ? 0 : rest;
| |
//ArrayPrint(widths);
| |
| |
//Print(m_table_principal.XSize());
| |
| |
| |
//--- Setemoas offeset imagen
| |
//ofeset de los iconos imagenes
| |
int imge_x_offset[COLS_TOTAL_TABLE] = {0, 8, 0, 0, 0, 0, 8};
| |
int imge_y_offset[COLS_TOTAL_TABLE] = {0, 7, 0, 0, 0, 0, 7};
| |
| |
m_table_principal.ImageXOffset(imge_x_offset);
| |
m_table_principal.ImageYOffset(imge_y_offset);
| |
| |
| |
//--- Propiedades generales
| |
int ysize_utilizable = ysize_table - HEADER_YSIZE_TABLE;
| |
| |
m_table_principal.TextAlign(align);
| |
m_table_principal.ColumnsWidth(widths);
| |
m_table_principal.HeadersColor(C'0x06,0x9C,0xCE');
| |
m_table_principal.CellColor(clrWhiteSmoke);
| |
m_table_principal.CellYSize(30);
| |
| |
//--- Array of text offset along the X axis in the columns
| |
int text_x_offset[COLS_TOTAL_TABLE];
| |
::ArrayInitialize(text_x_offset, 5);
| |
text_x_offset[TABLE_P_TRAILINGSTOP_CHECKBOX] += 22;
| |
text_x_offset[TABLE_P_TYPE] += 20;
| |
| |
| |
m_table_principal.TextXOffset(text_x_offset);
| |
| |
| |
m_table_principal.SetImages(TABLE_P_TYPE, 0, image_array);
| |
| |
| |
m_table_principal.DataType(TABLE_P_TICKET, TYPE_ULONG);
| |
m_table_principal.DataType(TABLE_P_TYPE, TYPE_STRING);
| |
m_table_principal.DataType(TABLE_P_VOLUME, TYPE_DOUBLE);
| |
m_table_principal.DataType(TABLE_P_ENTRY, TYPE_DOUBLE);
| |
m_table_principal.DataType(TABLE_P_TAKEPROFIT, TYPE_DOUBLE);
| |
m_table_principal.DataType(TABLE_P_STOPLOSS, TYPE_DOUBLE);
| |
| |
//---
| |
int x_label = x;
| |
int y_label = y;
| |
CWndCreate::CreateTextLabel(m_label_text, "Elija el tipo de breakeven", m_window, 0, m_tabs, 1, x_label, y_label, 210, 40);
| |
m_label_text.BackColor(C'201,203,205');
| |
m_label_text.FontSize(12);
| |
| |
y += 30;
| |
| |
string trailign_stop_type[3] = { "Breakeven by rr", "Breakeven by fixed points", "Breakeven by atr"};
| |
| |
int pos = (int)this.m_mode_breakeven;
| |
| |
CWndCreate::CreateCombobox(m_combox_be_type, "Tipo de breakeven: ", m_window, 0, m_tabs, 1, false, x, y, 262, 150, trailign_stop_type, 65, pos);
| |
m_combox_be_type.BackColor(C'201,203,205');
| |
m_combox_be_type.FontSize(10);
| |
| |
//--- Final
| |
CWndEvents::CompletedGUI();
| |
}
| |
| |
/*
| |
#define TABLE_P_TICKET 0
| |
#define TABLE_P_TYPE 1
| |
#define TABLE_P_VOLUME 2
| |
#define TABLE_P_ENTRY 3
| |
#define TABLE_P_TAKEPROFIT 4
| |
#define TABLE_P_STOPLOSS 5
| |
#define TABLE_P_TRAILINGSTOP_CHECKBOX 6
| |
| |
*/
| |
//+------------------------------------------------------------------+
| |
void CBreakEvenPanel::OnOpenPosition(const TSN::ROnOpenPosition &pos)
| |
{
| |
m_enable_to_trailing = true;
| |
const string symbol_name = TSN::account_status.LastTransctionSymbol();
| |
CSymbolInfo* ptr_symbol;
| |
int pos_symbol;
| |
| |
//--- Obtemos info del simbolo
| |
if(m_hasmap_symbol_por_pos.TryGet(symbol_name, pos_symbol)) //obtenemos datos del simbolo
| |
{
| |
ptr_symbol = m_symbol_array[pos_symbol];
| |
}
| |
else
| |
{
| |
ptr_symbol = new CSymbolInfo();
| |
ptr_symbol.Name(symbol_name);
| |
ptr_symbol.Refresh();
| |
| |
//--- Creacion del breakeven
| |
TSN::CBreakEven* new_be = new TSN::CBreakEven(NOT_MAGIC_NUMBER, symbol_name); // DAdo que siempre se leimiarna en OnDeinit
| |
new_be.SetBeByAtr(InpBeAtrMultiplier, InpBeAtrMultiplierExtra, GetPointer(atr_ultra_optimized));
| |
new_be.SetBeByFixedPoints(InpBeFixedPointsToPutBe, InpBeFixedPointsExtra);
| |
new_be.SetBeByRR(InpBeRrRatio, InpBeRrTypeExtra, InpBeRrExtraPointsOrAtrMultiplier, GetPointer(atr_ultra_optimized));
| |
new_be.SetInternalPointer(InpBeType);
| |
new_be.obj.AddLogFlags(InpBeLogLevel);
| |
new_be.obj.Automatic(false); // No sera automatico
| |
| |
//---
| |
m_symbol_array[m_data_s] = ptr_symbol;
| |
m_breakevens[m_data_s] = new_be;
| |
| |
//---
| |
m_hasmap_symbol_por_pos.Add(symbol_name, m_data_s);
| |
pos_symbol = m_data_s++;
| |
}
| |
| |
| |
//--- Aumentamos el taamaño de tickets por row
| |
m_row_por_posicion[m_row_por_posicion_s++] = pos;
| |
| |
//--- obteneos el row, y si no coincide entonces resize
| |
int row_index = int(m_table_principal.RowsTotal() - 1);
| |
if(row_index != m_row_por_posicion_s - 1)
| |
{
| |
row_index++;
| |
m_table_principal.AddRow(row_index);
| |
m_table_principal.SetImages(TABLE_P_TYPE, row_index, image_array);
| |
}
| |
| |
//---
| |
m_hhasmap_ticket_row.Add(pos.position.ticket, row_index);
| |
m_hashmap_pos_por_ticket.Add(pos.position.ticket, pos_symbol); //ticket -> posciion en larray
| |
| |
//---
| |
//PrintFormat("Row = %d | Ticket = %I64u | Digitos %d", row_index, pos.position.ticket, ptr_symbol.Digits());
| |
| |
//--- ticket
| |
m_table_principal.SetValue(TABLE_P_TICKET, row_index, IntegerToString(pos.position.ticket), 0);
| |
| |
//--- Tipo
| |
const static string type_entrys[2] = { "Buy", "Sell"};
| |
const static uint image_index[2] = { PANEL_TABLE_IMAGE_IDX_UP, PANEL_TABLE_IMAGE_IDX_DOWN};
| |
const static color clr_index[2] = { clrGreen, clrRed};
| |
const uint8_t t = (uint8_t)pos.position.type;
| |
| |
//---
| |
m_table_principal.SetValue(TABLE_P_TYPE, row_index, type_entrys[t]);
| |
m_table_principal.TextColor(TABLE_P_TYPE, row_index, clr_index[t]);
| |
m_table_principal.ChangeImage(TABLE_P_TYPE, row_index, t);
| |
| |
//--- voluemn
| |
m_table_principal.SetValue(TABLE_P_VOLUME, row_index, DoubleToString(pos.position.volume), 3);
| |
| |
//--- entry_price
| |
m_table_principal.SetValue(TABLE_P_ENTRY, row_index, DoubleToString(pos.position.open_price), ptr_symbol.Digits());
| |
| |
//--- tp
| |
m_table_principal.SetValue(TABLE_P_TAKEPROFIT, row_index, DoubleToString(pos.position.tp), ptr_symbol.Digits());
| |
| |
//--- sl
| |
m_table_principal.SetValue(TABLE_P_STOPLOSS, row_index, DoubleToString(pos.position.sl), ptr_symbol.Digits());
| |
| |
//--- trailing stop
| |
const string image_array_chekbox[2] =
| |
{
| |
"Images\\EasyAndFastGUI\\Controls\\checkbox_off.bmp",
| |
"Images\\EasyAndFastGUI\\Controls\\checkbox_on.bmp"
| |
};
| |
| |
//---
| |
m_table_principal.SetImages(TABLE_P_TRAILINGSTOP_CHECKBOX, row_index, image_array_chekbox);
| |
m_table_principal.ChangeImage(TABLE_P_TRAILINGSTOP_CHECKBOX, row_index, 0); //0 por defecto
| |
m_table_principal.SetValue(TABLE_P_TRAILINGSTOP_CHECKBOX, row_index, "Breakeven", 0);
| |
m_table_principal.CellType(TABLE_P_TRAILINGSTOP_CHECKBOX, row_index, CELL_CHECKBOX);
| |
m_table_principal.Update(true);
| |
//Sleep(5000);
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
void CBreakEvenPanel::OnClosePosition(const TSN::ROnClosePosition &pos, const int global_pos_index)
| |
{
| |
int row_index;
| |
if(m_hhasmap_ticket_row.TryGet(pos.position.ticket, row_index)) //obtnemos el row de la posicion en base al ticket
| |
{
| |
//--- eliminamos la fila de la tabla
| |
if(m_table_principal.RowsTotal() > 1) //mas de 1 fila
| |
{
| |
m_table_principal.DeleteRow(row_index, true); //eliminamos la fila
| |
}
| |
else //1 fila
| |
{
| |
//--- ticket
| |
for(int i = 0; i < COLS_TOTAL_TABLE; i++)
| |
{
| |
m_table_principal.SetValue(i, 0); //reset a null
| |
}
| |
| |
m_table_principal.Update(true);
| |
m_enable_to_trailing = false;
| |
}
| |
| |
//---
| |
m_hhasmap_ticket_row.Remove(pos.position.ticket); //la eliminamos del hashmap de ticekt->row
| |
m_hashmap_pos_por_ticket.Remove(pos.position.ticket); //eliminamso del hashmap de ticket->pos(en simbolo - traiing stop)
| |
| |
//--- eliiminamos el indice del array de posicoines [row -> (posicion = ticket)]
| |
int index_to_remove[1];
| |
index_to_remove[0] = row_index;
| |
RemoveMultipleIndexesWithVSize(m_row_por_posicion, m_row_por_posicion_s, index_to_remove);
| |
}
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
// Funcion que se ejecuta en OnInit, solo si hay posiciones abiertas
| |
void CBreakEvenPanel::OnInitNewPos(const TSN::ROnOpenPosition &position)
| |
{
| |
m_enable_to_trailing = true;
| |
const string symbol_name = TSN::account_status.LastTransctionSymbol();
| |
CSymbolInfo* ptr_symbol;
| |
int pos_symbol;
| |
| |
//--- Obtemos info del simbolo
| |
if(m_hasmap_symbol_por_pos.TryGet(symbol_name, pos_symbol)) //obtenemos datos del simbolo
| |
{
| |
ptr_symbol = m_symbol_array[pos_symbol];
| |
}
| |
else
| |
{
| |
ptr_symbol = new CSymbolInfo();
| |
ptr_symbol.Name(symbol_name);
| |
ptr_symbol.Refresh();
| |
| |
//--- Creacion del breakeven
| |
TSN::CBreakEven* new_be = new TSN::CBreakEven(NOT_MAGIC_NUMBER, symbol_name);
| |
new_be.SetBeByAtr(InpBeAtrMultiplier, InpBeAtrMultiplierExtra, GetPointer(atr_ultra_optimized));
| |
new_be.SetBeByFixedPoints(InpBeFixedPointsToPutBe, InpBeFixedPointsExtra);
| |
new_be.SetBeByRR(InpBeRrRatio, InpBeRrTypeExtra, InpBeRrExtraPointsOrAtrMultiplier, GetPointer(atr_ultra_optimized));
| |
new_be.SetInternalPointer(InpBeType);
| |
new_be.obj.AddLogFlags(InpBeLogLevel);
| |
new_be.obj.Automatic(false); // No sera automatico
| |
| |
//---
| |
m_symbol_array[m_data_s] = ptr_symbol;
| |
m_breakevens[m_data_s] = new_be;
| |
| |
//---
| |
m_hasmap_symbol_por_pos.Add(symbol_name, m_data_s);
| |
pos_symbol = m_data_s++;
| |
}
| |
| |
| |
//--- Aumentamos el taamaño de tickets por row
| |
m_row_por_posicion[m_row_por_posicion_s++] = position;
| |
| |
//--- obteneos el row, y si no coincide entonces resize
| |
int row_index = int(m_table_principal.RowsTotal() - 1);
| |
if(row_index != m_row_por_posicion_s - 1)
| |
{
| |
row_index++;
| |
m_table_principal.AddRow(row_index);
| |
m_table_principal.SetImages(TABLE_P_TYPE, row_index, image_array);
| |
// Print("Resize");
| |
}
| |
| |
//---
| |
m_hhasmap_ticket_row.Add(position.position.ticket, row_index);
| |
m_hashmap_pos_por_ticket.Add(position.position.ticket, pos_symbol); //ticket -> posciion en larray
| |
| |
| |
//---
| |
PrintFormat("Row = %d | Ticket = %I64u | Digitos %d", row_index, position.position.ticket, ptr_symbol.Digits());
| |
| |
| |
//--- ticket
| |
m_table_principal.SetValue(TABLE_P_TICKET, row_index, IntegerToString(position.position.ticket), 0);
| |
| |
//--- Tipo
| |
const static string type_entrys[2] = { "Buy", "Sell"};
| |
const static uint image_index[2] = { PANEL_TABLE_IMAGE_IDX_UP, PANEL_TABLE_IMAGE_IDX_DOWN};
| |
const static color clr_index[2] = { clrGreen, clrRed};
| |
const uint8_t t = (uint8_t)position.position.type;
| |
| |
| |
//---
| |
m_table_principal.SetValue(TABLE_P_TYPE, row_index, type_entrys[t]);
| |
m_table_principal.TextColor(TABLE_P_TYPE, row_index, clr_index[t]);
| |
m_table_principal.ChangeImage(TABLE_P_TYPE, row_index, t);
| |
| |
| |
//--- voluemn
| |
m_table_principal.SetValue(TABLE_P_VOLUME, row_index, DoubleToString(position.position.volume), 3);
| |
| |
//--- entry_price
| |
m_table_principal.SetValue(TABLE_P_ENTRY, row_index, DoubleToString(position.position.open_price), ptr_symbol.Digits());
| |
| |
//--- tp
| |
m_table_principal.SetValue(TABLE_P_TAKEPROFIT, row_index, DoubleToString(position.position.tp), ptr_symbol.Digits());
| |
| |
//--- sl
| |
m_table_principal.SetValue(TABLE_P_STOPLOSS, row_index, DoubleToString(position.position.sl), ptr_symbol.Digits());
| |
| |
| |
//--- trailing stop
| |
const string image_array_chekbox[2] =
| |
{
| |
"Images\\EasyAndFastGUI\\Controls\\checkbox_off.bmp",
| |
"Images\\EasyAndFastGUI\\Controls\\checkbox_on.bmp"
| |
};
| |
| |
//---
| |
m_table_principal.SetImages(TABLE_P_TRAILINGSTOP_CHECKBOX, row_index, image_array_chekbox);
| |
m_table_principal.ChangeImage(TABLE_P_TRAILINGSTOP_CHECKBOX, row_index, 0); //0 por defecto
| |
m_table_principal.SetValue(TABLE_P_TRAILINGSTOP_CHECKBOX, row_index, "Breakeven", 0);
| |
m_table_principal.CellType(TABLE_P_TRAILINGSTOP_CHECKBOX, row_index, CELL_CHECKBOX);
| |
m_table_principal.Update(true);
| |
//Sleep(5000);
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
void CBreakEvenPanel::OnPositionModify(const TSN::Position &pos, const uchar change_flags)
| |
{
| |
int row;
| |
if(m_hashmap_pos_por_ticket.TryGet(pos.ticket, row))
| |
{
| |
const string symbol_name = TSN::account_status.LastTransctionSymbol();
| |
CSymbolInfo* ptr_symbol;
| |
int pos_symbol;
| |
| |
//--- Obtemos info del simbolo
| |
m_hasmap_symbol_por_pos.TryGet(symbol_name, pos_symbol); //obtenemos datos del simbolo
| |
ptr_symbol = m_symbol_array[pos_symbol];
| |
| |
//---
| |
if((change_flags & ACCOUNTSTATUS_ON_POS_MODIFY_FLAG_CHANGE_SL) != 0)
| |
m_table_principal.SetValue(TABLE_P_STOPLOSS, row, DoubleToString(pos.sl), ptr_symbol.Digits());
| |
| |
if((change_flags & ACCOUNTSTATUS_ON_POS_MODIFY_FLAG_CHANGE_TP) != 0)
| |
m_table_principal.SetValue(TABLE_P_TAKEPROFIT, row, DoubleToString(pos.tp), ptr_symbol.Digits());
| |
| |
//---
| |
m_table_principal.Update(true);
| |
}
| |
}
| |
//+------------------------------------------------------------------+
|