Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6208bbd9c5 |
@@ -68,6 +68,11 @@ public:
|
|||||||
|
|
||||||
if(m_ma_slow_handle == INVALID_HANDLE)
|
if(m_ma_slow_handle == INVALID_HANDLE)
|
||||||
{
|
{
|
||||||
|
if(m_ma_fast_handle != INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
IndicatorRelease(m_ma_fast_handle);
|
||||||
|
m_ma_fast_handle = INVALID_HANDLE;
|
||||||
|
}
|
||||||
if(mp_logger)
|
if(mp_logger)
|
||||||
mp_logger.Error("Failed to create Slow MA indicator");
|
mp_logger.Error("Failed to create Slow MA indicator");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -98,17 +98,32 @@ private:
|
|||||||
{
|
{
|
||||||
double break_even_trigger = CUtilities::PointsToPrice(mp_market_data.GetSymbol(),
|
double break_even_trigger = CUtilities::PointsToPrice(mp_market_data.GetSymbol(),
|
||||||
g_break_even_profit);
|
g_break_even_profit);
|
||||||
double break_even_distance = CUtilities::PointsToPrice(mp_market_data.GetSymbol(),
|
double break_even_buffer = CUtilities::PointsToPrice(mp_market_data.GetSymbol(),
|
||||||
g_break_even_sl);
|
g_break_even_sl);
|
||||||
|
double current_price = (pos_type == POSITION_TYPE_BUY) ? mp_market_data.GetBid() : mp_market_data.GetAsk();
|
||||||
|
double price_move = 0.0;
|
||||||
|
|
||||||
// Break-even only if profit threshold is reached
|
|
||||||
if(profit < break_even_trigger)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// For BUY: move SL to BE (open price + distance)
|
|
||||||
if(pos_type == POSITION_TYPE_BUY)
|
if(pos_type == POSITION_TYPE_BUY)
|
||||||
{
|
{
|
||||||
double be_sl = open_price + break_even_distance;
|
price_move = current_price - open_price;
|
||||||
|
}
|
||||||
|
else if(pos_type == POSITION_TYPE_SELL)
|
||||||
|
{
|
||||||
|
price_move = open_price - current_price;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Break-even only if price has moved enough from entry
|
||||||
|
if(price_move < break_even_trigger)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// For BUY: move SL to entry price plus optional buffer
|
||||||
|
if(pos_type == POSITION_TYPE_BUY)
|
||||||
|
{
|
||||||
|
double be_sl = open_price + break_even_buffer;
|
||||||
be_sl = CUtilities::NormalizePrice(mp_market_data.GetSymbol(), be_sl);
|
be_sl = CUtilities::NormalizePrice(mp_market_data.GetSymbol(), be_sl);
|
||||||
|
|
||||||
if(be_sl > current_sl)
|
if(be_sl > current_sl)
|
||||||
@@ -119,10 +134,10 @@ private:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// For SELL: move SL to BE (open price - distance)
|
// For SELL: move SL to entry price minus optional buffer
|
||||||
else if(pos_type == POSITION_TYPE_SELL)
|
else if(pos_type == POSITION_TYPE_SELL)
|
||||||
{
|
{
|
||||||
double be_sl = open_price - break_even_distance;
|
double be_sl = open_price - break_even_buffer;
|
||||||
be_sl = CUtilities::NormalizePrice(mp_market_data.GetSymbol(), be_sl);
|
be_sl = CUtilities::NormalizePrice(mp_market_data.GetSymbol(), be_sl);
|
||||||
|
|
||||||
if(be_sl < current_sl)
|
if(be_sl < current_sl)
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ public:
|
|||||||
double max_lot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
|
double max_lot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
|
||||||
double lot_step = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
|
double lot_step = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
|
||||||
|
|
||||||
|
// Guard against invalid broker volume data
|
||||||
|
if(min_lot <= 0.0 || max_lot <= 0.0 || lot_step <= 0.0 || max_lot < min_lot)
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
// Apply limits
|
// Apply limits
|
||||||
if(lot < min_lot) lot = min_lot;
|
if(lot < min_lot) lot = min_lot;
|
||||||
if(lot > max_lot) lot = max_lot;
|
if(lot > max_lot) lot = max_lot;
|
||||||
@@ -31,6 +35,9 @@ public:
|
|||||||
// Round to step
|
// Round to step
|
||||||
lot = MathFloor(lot / lot_step) * lot_step;
|
lot = MathFloor(lot / lot_step) * lot_step;
|
||||||
|
|
||||||
|
if(lot < min_lot)
|
||||||
|
lot = min_lot;
|
||||||
|
|
||||||
return NormalizeDouble(lot, 2);
|
return NormalizeDouble(lot, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
Binary file not shown.
+10
@@ -48,6 +48,10 @@ int OnInit()
|
|||||||
if(!g_market_data.IsTradingAllowed())
|
if(!g_market_data.IsTradingAllowed())
|
||||||
{
|
{
|
||||||
g_logger.Error("Trading not allowed for this symbol");
|
g_logger.Error("Trading not allowed for this symbol");
|
||||||
|
delete g_market_data;
|
||||||
|
g_market_data = NULL;
|
||||||
|
delete g_logger;
|
||||||
|
g_logger = NULL;
|
||||||
return INIT_FAILED;
|
return INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +60,12 @@ int OnInit()
|
|||||||
if(!g_strategy.Init())
|
if(!g_strategy.Init())
|
||||||
{
|
{
|
||||||
g_logger.Error("Failed to initialize strategy");
|
g_logger.Error("Failed to initialize strategy");
|
||||||
|
delete g_strategy;
|
||||||
|
g_strategy = NULL;
|
||||||
|
delete g_market_data;
|
||||||
|
g_market_data = NULL;
|
||||||
|
delete g_logger;
|
||||||
|
g_logger = NULL;
|
||||||
return INIT_FAILED;
|
return INIT_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user