New EA and Indi

This commit is contained in:
Kunthawat Greethong
2026-01-25 10:34:54 +07:00
parent 39ce46877e
commit 04aa2eb2e6
37 changed files with 17051 additions and 0 deletions

View File

@@ -0,0 +1,444 @@
//+------------------------------------------------------------------+
//| MoneyManager.mqh |
//| Universal Buffer Reader EA v2.0 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025"
#property link ""
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| CMoneyManager - Calculates lot sizes and manages daily profit |
//+------------------------------------------------------------------+
class CMoneyManager
{
private:
double m_base_lot_size;
bool m_use_percent_balance;
double m_percent_of_balance_for_profit;
double m_daily_profit_target_percent;
double m_min_lot;
double m_max_lot;
double m_lot_step;
double m_point_value;
double m_tick_value;
// State
double m_daily_profit_accumulated;
double m_daily_start_balance;
// Logging
bool m_enable_debug;
public:
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CMoneyManager()
{
m_base_lot_size = 0.03;
m_use_percent_balance = true;
m_percent_of_balance_for_profit = 1.0;
m_daily_profit_target_percent = 2.0;
m_min_lot = 0.01;
m_max_lot = 100.0;
m_lot_step = 0.01;
m_point_value = 0;
m_tick_value = 0;
m_daily_profit_accumulated = 0;
m_daily_start_balance = 0;
m_enable_debug = false;
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
~CMoneyManager()
{
}
//+------------------------------------------------------------------+
//| Set parameters |
//+------------------------------------------------------------------+
void SetParameters(
double base_lot_size,
bool use_percent_balance, double percent_of_balance_for_profit,
double daily_profit_target_percent,
double min_lot, double max_lot, double lot_step,
double point_value, double tick_value,
bool enable_debug = false
)
{
// Validate parameters
if(base_lot_size <= 0)
{
Print("[ERROR] Invalid base lot size: ", base_lot_size, ". Using default 0.01");
m_base_lot_size = 0.01;
}
else
{
m_base_lot_size = base_lot_size;
}
if(percent_of_balance_for_profit <= 0)
{
Print("[ERROR] Invalid percent of balance for profit: ", percent_of_balance_for_profit, ". Using default 1.0");
m_percent_of_balance_for_profit = 1.0;
}
else
{
m_percent_of_balance_for_profit = percent_of_balance_for_profit;
}
if(daily_profit_target_percent < 0)
{
Print("[ERROR] Invalid daily profit target percent: ", daily_profit_target_percent, ". Using default 2.0");
m_daily_profit_target_percent = 2.0;
}
else
{
m_daily_profit_target_percent = daily_profit_target_percent;
}
if(min_lot <= 0)
{
Print("[ERROR] Invalid min lot: ", min_lot, ". Using default 0.01");
m_min_lot = 0.01;
}
else
{
m_min_lot = min_lot;
}
if(max_lot <= 0 || max_lot < min_lot)
{
Print("[ERROR] Invalid max lot: ", max_lot, ". Using default 100.0");
m_max_lot = 100.0;
}
else
{
m_max_lot = max_lot;
}
if(lot_step <= 0)
{
Print("[ERROR] Invalid lot step: ", lot_step, ". Using default 0.01");
m_lot_step = 0.01;
}
else
{
m_lot_step = lot_step;
}
if(point_value <= 0)
{
Print("[ERROR] Invalid point value: ", point_value);
}
m_point_value = point_value;
if(tick_value <= 0)
{
Print("[ERROR] Invalid tick value: ", tick_value);
}
m_tick_value = tick_value;
m_use_percent_balance = use_percent_balance;
m_enable_debug = enable_debug;
if(m_enable_debug)
{
Print("[MoneyManager] Parameters set:");
Print(" Base lot size: ", m_base_lot_size);
Print(" Use % balance: ", m_use_percent_balance);
Print(" % of balance for profit: ", m_percent_of_balance_for_profit);
Print(" Daily profit target %: ", m_daily_profit_target_percent);
Print(" Min lot: ", m_min_lot, ", Max lot: ", m_max_lot, ", Lot step: ", m_lot_step);
Print(" Point value: ", m_point_value, ", Tick value: ", m_tick_value);
}
}
//+------------------------------------------------------------------+
//| Set debug mode |
//+------------------------------------------------------------------+
void SetDebugMode(bool enable_debug)
{
m_enable_debug = enable_debug;
}
//+------------------------------------------------------------------+
//| Calculate lot size (pure function) |
//+------------------------------------------------------------------+
double CalculateLotSize(
bool is_buy,
double open_price,
double tp_price,
double account_balance
)
{
if(m_enable_debug)
{
Print("[MoneyManager] Calculating lot size...");
Print(" Direction: ", (is_buy ? "BUY" : "SELL"));
Print(" Open price: ", open_price);
Print(" TP price: ", tp_price);
Print(" Account balance: ", account_balance);
}
// Validate inputs
if(open_price <= 0)
{
Print("[ERROR] Invalid open price: ", open_price);
return m_base_lot_size;
}
if(tp_price <= 0)
{
Print("[ERROR] Invalid TP price: ", tp_price);
return m_base_lot_size;
}
if(account_balance <= 0)
{
Print("[ERROR] Invalid account balance: ", account_balance);
return m_base_lot_size;
}
// Calculate TP points
double tp_points = 0;
if(is_buy)
{
tp_points = (tp_price - open_price) / m_point_value;
}
else
{
tp_points = (open_price - tp_price) / m_point_value;
}
if(m_enable_debug)
{
Print(" TP points: ", tp_points);
}
if(tp_points <= 0)
{
Print("[WARNING] TP points <= 0. Using base lot size: ", m_base_lot_size);
return m_base_lot_size;
}
// Calculate base lot
double base_lot = m_base_lot_size;
if(m_use_percent_balance)
{
base_lot = CalculateBaseLot(tp_points, account_balance);
if(m_enable_debug)
{
Print(" Base lot from % balance: ", base_lot);
}
}
else
{
if(m_enable_debug)
{
Print(" Using fixed base lot: ", base_lot);
}
}
// Normalize and return
double normalized_lot = NormalizeLotSize(base_lot);
if(m_enable_debug)
{
Print(" Normalized lot: ", normalized_lot);
Print("[MoneyManager] Lot size calculation complete: ", normalized_lot);
}
return normalized_lot;
}
//+------------------------------------------------------------------+
//| Reset daily profit tracking |
//+------------------------------------------------------------------+
void ResetDailyProfit(double current_balance)
{
if(current_balance <= 0)
{
Print("[ERROR] Invalid current balance for daily profit reset: ", current_balance);
return;
}
m_daily_start_balance = current_balance;
m_daily_profit_accumulated = 0;
if(m_enable_debug)
{
Print("[MoneyManager] Daily profit tracking reset");
Print(" Start balance: ", m_daily_start_balance);
Print(" Target profit: ", GetDailyProfitTarget());
}
}
//+------------------------------------------------------------------+
//| Check if daily profit target reached |
//+------------------------------------------------------------------+
bool IsDailyProfitTargetReached()
{
if(m_daily_profit_target_percent <= 0)
{
if(m_enable_debug)
{
Print("[MoneyManager] Daily profit target disabled (0%)");
}
return false;
}
double target_profit = GetDailyProfitTarget();
bool reached = (m_daily_profit_accumulated >= target_profit);
if(m_enable_debug)
{
Print("[MoneyManager] Daily profit check:");
Print(" Accumulated: ", m_daily_profit_accumulated);
Print(" Target: ", target_profit);
Print(" Reached: ", (reached ? "YES" : "NO"));
}
return reached;
}
//+------------------------------------------------------------------+
//| Get daily profit target |
//+------------------------------------------------------------------+
double GetDailyProfitTarget()
{
if(m_daily_start_balance <= 0) return 0;
return m_daily_start_balance * m_daily_profit_target_percent / 100.0;
}
//+------------------------------------------------------------------+
//| Get daily profit accumulated |
//+------------------------------------------------------------------+
double GetDailyProfitAccumulated()
{
return m_daily_profit_accumulated;
}
//+------------------------------------------------------------------+
//| Get daily profit percentage |
//+------------------------------------------------------------------+
double GetDailyProfitPercent()
{
if(m_daily_start_balance <= 0) return 0;
return (m_daily_profit_accumulated / m_daily_start_balance) * 100.0;
}
//+------------------------------------------------------------------+
//| Set daily profit accumulated (for tracking) |
//+------------------------------------------------------------------+
void SetDailyProfitAccumulated(double value)
{
m_daily_profit_accumulated = value;
if(m_enable_debug)
{
Print("[MoneyManager] Daily profit accumulated set to: ", value);
}
}
private:
//+------------------------------------------------------------------+
//| Calculate base lot based on % balance |
//+------------------------------------------------------------------+
double CalculateBaseLot(double tp_points, double account_balance)
{
if(tp_points <= 0)
{
Print("[ERROR] Invalid TP points for base lot calculation: ", tp_points);
return m_base_lot_size;
}
if(m_tick_value <= 0)
{
Print("[ERROR] Invalid tick value for base lot calculation: ", m_tick_value);
return m_base_lot_size;
}
if(account_balance <= 0)
{
Print("[ERROR] Invalid account balance for base lot calculation: ", account_balance);
return m_base_lot_size;
}
double target_profit = account_balance * (m_percent_of_balance_for_profit / 100.0);
double profit_per_lot = tp_points * m_tick_value;
if(m_enable_debug)
{
Print("[MoneyManager] Base lot calculation:");
Print(" Target profit: ", target_profit, " (", m_percent_of_balance_for_profit, "% of balance)");
Print(" Profit per lot: ", profit_per_lot);
}
if(profit_per_lot <= 0)
{
Print("[ERROR] Invalid profit per lot: ", profit_per_lot);
return m_base_lot_size;
}
double lot = target_profit / profit_per_lot;
if(m_enable_debug)
{
Print(" Calculated lot: ", lot);
}
return lot;
}
//+------------------------------------------------------------------+
//| Normalize lot size to broker requirements |
//+------------------------------------------------------------------+
double NormalizeLotSize(double lot)
{
if(m_enable_debug)
{
Print("[MoneyManager] Normalizing lot size: ", lot);
}
// Round to lot step
double rounded_lot = MathFloor(lot / m_lot_step) * m_lot_step;
if(m_enable_debug && rounded_lot != lot)
{
Print(" Rounded to lot step: ", rounded_lot, " (step: ", m_lot_step, ")");
}
// Ensure within min/max
double min_adjusted = MathMax(rounded_lot, m_min_lot);
double max_adjusted = MathMin(min_adjusted, m_max_lot);
if(m_enable_debug)
{
if(min_adjusted != rounded_lot)
{
Print(" Adjusted to min lot: ", min_adjusted, " (min: ", m_min_lot, ")");
}
if(max_adjusted != min_adjusted)
{
Print(" Adjusted to max lot: ", max_adjusted, " (max: ", m_max_lot, ")");
}
}
double normalized = NormalizeDouble(max_adjusted, 2);
if(m_enable_debug)
{
Print(" Final normalized lot: ", normalized);
}
return normalized;
}
};
//+------------------------------------------------------------------+