update EA

This commit is contained in:
Kunthawat Greethong
2026-01-08 13:21:40 +07:00
parent 92391f9d18
commit 2d2a6d30a0
2 changed files with 237 additions and 245 deletions

View File

@@ -38,6 +38,7 @@ enum ENUM_OI_SOURCE {
}; };
input ENUM_OI_SOURCE InpOISource = OI_SOURCE_MANUAL; input ENUM_OI_SOURCE InpOISource = OI_SOURCE_MANUAL;
input string InpOICsvPath = "\\Files\\oi_data.csv"; // Path to CSV file input string InpOICsvPath = "\\Files\\oi_data.csv"; // Path to CSV file
input int InpCSVReloadInterval = 60; // CSV reload interval (minutes, 0=disabled)
input double InpManualFuturePrice = 0.0; // Manual future price input input double InpManualFuturePrice = 0.0; // Manual future price input
// OI Levels (Manual Input - สามารถใส่ได้ถึง 3 ระดับ) // OI Levels (Manual Input - สามารถใส่ได้ถึง 3 ระดับ)
@@ -170,6 +171,12 @@ bool NewsBlockActive = false;
datetime NewsBlockStart = 0; datetime NewsBlockStart = 0;
datetime NewsBlockEnd = 0; datetime NewsBlockEnd = 0;
// CSV Cache Variables
double CachedFuturePrice = -1;
string LoadedCSVPath = "";
bool CSVLoadLogged = false;
datetime LastCSVReloadTime = 0;
//=== NEW: Control Panel Variables === //=== NEW: Control Panel Variables ===
// Control Panel Position - Moved below dashboard // Control Panel Position - Moved below dashboard
int ControlPanelX = 10; int ControlPanelX = 10;
@@ -357,21 +364,31 @@ void OnTick()
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
void OnTimer() void OnTimer()
{ {
//--- Update dashboard periodically //--- Update dashboard periodically
if(InpEnableDashboard) if(InpEnableDashboard)
{ {
UpdateDashboard(); UpdateDashboard();
UpdateControlPanel(); UpdateControlPanel();
} }
//--- Check news events //--- Check news events
if(InpAvoidHighImpactNews) if(InpAvoidHighImpactNews)
{ {
CheckNewsEvents(); CheckNewsEvents();
} }
//--- Reset daily statistics if new day //--- Reset daily statistics if new day
CheckDailyReset(); CheckDailyReset();
//--- CSV reload check
if(InpOISource == OI_SOURCE_CSV_FILE && InpCSVReloadInterval > 0) {
if(TimeCurrent() - LastCSVReloadTime >= InpCSVReloadInterval * 60) {
Print("CSV Reload: Scheduled reload triggered");
LastCSVReloadTime = TimeCurrent();
CachedFuturePrice = -1;
LoadOIFromCSV();
}
}
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -1094,64 +1111,91 @@ void InitializeOILevels()
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
void LoadOIFromCSV() void LoadOIFromCSV()
{ {
string filename = InpOICsvPath; string filename = InpOICsvPath;
int filehandle = FileOpen(filename, FILE_READ|FILE_CSV|FILE_ANSI, ','); int filehandle = FileOpen(filename, FILE_READ|FILE_CSV|FILE_ANSI, ',');
if(filehandle == INVALID_HANDLE) if(filehandle == INVALID_HANDLE)
{ {
Print("Error opening CSV file: ", filename); Print("Error opening CSV file: ", filename);
// Fall back to manual levels InitializeOILevels();
InitializeOILevels(); return;
return; }
}
// Skip header if exists int callIndex = 0;
FileReadString(filehandle); int putIndex = 0;
double futurePrice = 0.0;
bool isFirstLine = true;
int callIndex = 0; while(!FileIsEnding(filehandle) && (callIndex < 3 || putIndex < 3))
int putIndex = 0; {
string row = FileReadString(filehandle);
while(!FileIsEnding(filehandle) && (callIndex < 3 || putIndex < 3)) if(isFirstLine) {
{ isFirstLine = false;
string row = FileReadString(filehandle); if(StringFind(row, "Type") >= 0 || StringFind(row, "Strike") >= 0 || StringFind(row, "OI") >= 0) {
string data[]; continue;
int count = StringSplit(row, ',', data); }
}
if(count >= 3) string data[];
{ int count = StringSplit(row, ',', data);
string type = data[0];
double strike = StringToDouble(data[1]);
int oi = (int)StringToInteger(data[2]);
if(type == "CALL" && callIndex < 3) if(count >= 3)
{ {
CallLevels[callIndex] = strike; string type = data[0];
CallOI[callIndex] = oi; double strike = StringToDouble(data[1]);
callIndex++; int oi = (int)StringToInteger(data[2]);
}
else if(type == "PUT" && putIndex < 3)
{
PutLevels[putIndex] = strike;
PutOI[putIndex] = oi;
putIndex++;
}
}
}
FileClose(filehandle); if(StringFind(type, "Future") >= 0)
{
futurePrice = strike;
if(!CSVLoadLogged) {
Print("DEBUG: Parsed Future price: ", futurePrice);
}
}
else if(type == "CALL" && callIndex < 3)
{
CallLevels[callIndex] = strike;
CallOI[callIndex] = oi;
callIndex++;
}
else if(type == "PUT" && putIndex < 3)
{
PutLevels[putIndex] = strike;
PutOI[putIndex] = oi;
putIndex++;
}
}
}
// Fill any missing levels with zeros FileClose(filehandle);
for(int i = callIndex; i < 3; i++)
{
CallLevels[i] = 0;
CallOI[i] = 0;
}
for(int i = putIndex; i < 3; i++) for(int i = callIndex; i < 3; i++)
{ {
PutLevels[i] = 0; CallLevels[i] = 0;
PutOI[i] = 0; CallOI[i] = 0;
} }
for(int i = putIndex; i < 3; i++)
{
PutLevels[i] = 0;
PutOI[i] = 0;
}
if(futurePrice > 0) {
CachedFuturePrice = futurePrice;
DynamicFuturePrice = futurePrice;
FuturePrice = futurePrice;
LoadedCSVPath = filename;
CSVLoadLogged = true;
Print("CSV SUCCESS: FuturePrice=", futurePrice, ", CALL=[", CallLevels[0], ",", CallLevels[1], ",", CallLevels[2], "], PUT=[", PutLevels[0], ",", PutLevels[1], ",", PutLevels[2], "] loaded from ", filename);
} else {
if(!CSVLoadLogged) {
Print("CSV ERROR: No valid price found in ", filename);
CSVLoadLogged = true;
}
CachedFuturePrice = 0;
}
} }
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
@@ -1214,32 +1258,36 @@ bool InitializeIndicators()
//+------------------------------------------------------------------+ //+------------------------------------------------------------------+
bool UpdateMarketData() bool UpdateMarketData()
{ {
// Get current prices // Get current prices
SpotPrice = SymbolInfo.Bid(); SpotPrice = SymbolInfo.Bid();
SymbolInfo.RefreshRates(); SymbolInfo.RefreshRates();
// Get future price (manual or from symbol) // Get future price (CSV cache, manual or from symbol)
if(DynamicFuturePrice > 0) if(CachedFuturePrice > 0)
{ {
FuturePrice = DynamicFuturePrice; FuturePrice = CachedFuturePrice;
} }
else if(InpManualFuturePrice > 0) else if(DynamicFuturePrice > 0)
{ {
FuturePrice = InpManualFuturePrice; FuturePrice = DynamicFuturePrice;
} }
else else if(InpManualFuturePrice > 0)
{ {
// In real implementation, you might get this from a different symbol FuturePrice = InpManualFuturePrice;
// For now, use spot price with a small offset }
FuturePrice = SpotPrice; else
} {
// In real implementation, you might get this from a different symbol
// For now, use spot price with a small offset
FuturePrice = SpotPrice;
}
// Calculate Delta // Calculate Delta
double previousDelta = DeltaPrice; double previousDelta = DeltaPrice;
DeltaPrice = FuturePrice - SpotPrice; DeltaPrice = FuturePrice - SpotPrice;
// Update Delta EMA // Update Delta EMA
UpdateDeltaEMA(); UpdateDeltaEMA();
// Calculate Deviation // Calculate Deviation
DeltaDeviation = DeltaPrice - DeltaEMA; DeltaDeviation = DeltaPrice - DeltaEMA;

View File

@@ -98,6 +98,7 @@ input int InpTrailingStepPoints = 50;
input bool InpUseSoftStopLoss = true; input bool InpUseSoftStopLoss = true;
input bool InpUseAutoRecovery = true; input bool InpUseAutoRecovery = true;
input bool InpEnableDashboard = true; input bool InpEnableDashboard = true;
input int InpCSVReloadInterval = 60;
CTrade Trade; CTrade Trade;
CSymbolInfo SymbolInfo; CSymbolInfo SymbolInfo;
@@ -199,6 +200,7 @@ double LastPrice = 0.0;
double CachedFuturePrice = -1; double CachedFuturePrice = -1;
string LoadedCSVPath = ""; string LoadedCSVPath = "";
bool CSVLoadLogged = false; bool CSVLoadLogged = false;
datetime LastCSVReloadTime = 0;
int OnInit() { int OnInit() {
Trade.SetExpertMagicNumber(InpMagicNumber); Trade.SetExpertMagicNumber(InpMagicNumber);
@@ -301,13 +303,22 @@ void OnTick() {
} }
void OnTimer() { void OnTimer() {
if(InpEnableDashboard && TimeCurrent() - LastDashboardUpdate >= 1) { if(InpEnableDashboard && TimeCurrent() - LastDashboardUpdate >= 1) {
UpdateDashboard(); UpdateDashboard();
UpdateControlPanel(); UpdateControlPanel();
LastDashboardUpdate = TimeCurrent(); LastDashboardUpdate = TimeCurrent();
} }
CheckDailyReset(); CheckDailyReset();
if(InpOISource == OI_SOURCE_CSV_FILE && InpCSVReloadInterval > 0) {
if(TimeCurrent() - LastCSVReloadTime >= InpCSVReloadInterval * 60) {
Print("CSV Reload: Scheduled reload triggered");
LastCSVReloadTime = TimeCurrent();
CachedFuturePrice = -1;
LoadOIFromCSV();
}
}
} }
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) {
@@ -1007,111 +1018,71 @@ bool InitializeIndicators() {
void LoadOIFromCSV() void LoadOIFromCSV()
{ {
string paths[]; int filehandle = FileOpen(InpOICsvPath, FILE_READ | FILE_CSV | FILE_ANSI, ',');
int pathCount = 0;
ArrayResize(paths, 5); if(filehandle == INVALID_HANDLE)
paths[pathCount++] = InpOICsvPath; {
paths[pathCount++] = "oi_data.csv"; Print("CSV ERROR: Cannot open ", InpOICsvPath);
paths[pathCount++] = "\\Files\\oi_data.csv"; return;
paths[pathCount++] = "..\\oi_scraper\\oi_data.csv"; }
paths[pathCount++] = "../oi_scraper/oi_data.csv";
int filehandle = INVALID_HANDLE; int callIndex = 0;
string foundPath = ""; int putIndex = 0;
double futurePrice = 0.0;
bool isFirstLine = true;
for(int i = 0; i < pathCount; i++) { while(!FileIsEnding(filehandle) && (callIndex < 3 || putIndex < 3))
if(!CSVLoadLogged) { {
Print("Trying CSV path: ", paths[i]); string row = FileReadString(filehandle);
}
filehandle = FileOpen(paths[i], FILE_READ | FILE_CSV | FILE_ANSI, ',');
if(filehandle != INVALID_HANDLE) {
foundPath = paths[i];
if(!CSVLoadLogged) {
Print("Found CSV file at: ", foundPath);
}
break;
}
}
if(filehandle == INVALID_HANDLE) { if(isFirstLine) {
if(!CSVLoadLogged) { isFirstLine = false;
Print("CSV ERROR: File not found. Searched paths:"); if(StringFind(row, "Type") >= 0 || StringFind(row, "Strike") >= 0 || StringFind(row, "OI") >= 0) {
for(int i = 0; i < pathCount; i++) { continue;
Print(" - ", paths[i]); }
} }
CSVLoadLogged = true;
}
return;
}
int callIndex = 0; string data[];
int putIndex = 0; int count = StringSplit(row, ',', data);
double futurePrice = 0.0;
while(!FileIsEnding(filehandle) && (callIndex < 3 || putIndex < 3)) if(count >= 3)
{ {
string row = FileReadString(filehandle); string type = data[0];
string data[]; double strike = StringToDouble(data[1]);
int count = StringSplit(row, ',', data); int oi = (int)StringToInteger(data[2]);
if(count >= 3) if(StringFind(type, "Future") >= 0)
{ {
string type = data[0]; futurePrice = strike;
double strike = StringToDouble(data[1]); }
int oi = (int)StringToInteger(data[2]); else if(type == "CALL" && callIndex < 3)
{
CallLevels[callIndex] = strike;
CallOI[callIndex] = oi;
callIndex++;
}
else if(type == "PUT" && putIndex < 3)
{
PutLevels[putIndex] = strike;
PutOI[putIndex] = oi;
putIndex++;
}
}
}
if(StringFind(type, "Future") >= 0) FileClose(filehandle);
{
futurePrice = strike;
if(!CSVLoadLogged) {
Print("DEBUG: Parsed Future price: ", futurePrice);
}
}
else if(type == "CALL" && callIndex < 3)
{
CallLevels[callIndex] = strike;
CallOI[callIndex] = oi;
callIndex++;
}
else if(type == "PUT" && putIndex < 3)
{
PutLevels[putIndex] = strike;
PutOI[putIndex] = oi;
putIndex++;
}
}
}
FileClose(filehandle); for(int i = callIndex; i < 3; i++) { CallLevels[i] = 0; CallOI[i] = 0; }
for(int i = putIndex; i < 3; i++) { PutLevels[i] = 0; PutOI[i] = 0; }
for(int i = callIndex; i < 3; i++) if(futurePrice > 0) {
{ CachedFuturePrice = futurePrice;
CallLevels[i] = 0; DynamicFuturePrice = futurePrice;
CallOI[i] = 0; FuturePrice = futurePrice;
} Print("CSV SUCCESS: FuturePrice=", futurePrice);
}
for(int i = putIndex; i < 3; i++) InitializeKeyLevels();
{
PutLevels[i] = 0;
PutOI[i] = 0;
}
if(futurePrice > 0) {
CachedFuturePrice = futurePrice;
DynamicFuturePrice = futurePrice;
LoadedCSVPath = foundPath;
CSVLoadLogged = true;
Print("CSV SUCCESS: FuturePrice=", futurePrice, ", CALL=[", CallLevels[0], ",", CallLevels[1], ",", CallLevels[2], "], PUT=[", PutLevels[0], ",", PutLevels[1], ",", PutLevels[2], "] loaded from ", foundPath);
} else {
if(!CSVLoadLogged) {
Print("CSV ERROR: No valid price found in ", foundPath);
CSVLoadLogged = true;
}
CachedFuturePrice = 0;
}
InitializeKeyLevels();
} }
void CheckExistingPositions() { void CheckExistingPositions() {
@@ -1355,34 +1326,6 @@ void UpdateInputValues() {
DynamicFuturePrice = StringToDouble(value); DynamicFuturePrice = StringToDouble(value);
} }
if(ObjectGetString(chart_id, "CP_CallStrike1", OBJPROP_TEXT, 0, value)) {
DynamicCallStrike1 = StringToDouble(value);
}
if(ObjectGetString(chart_id, "CP_CallStrike2", OBJPROP_TEXT, 0, value)) {
DynamicCallStrike2 = StringToDouble(value);
}
if(ObjectGetString(chart_id, "CP_CallStrike3", OBJPROP_TEXT, 0, value)) {
DynamicCallStrike3 = StringToDouble(value);
}
if(ObjectGetString(chart_id, "CP_PutStrike1", OBJPROP_TEXT, 0, value)) {
DynamicPutStrike1 = StringToDouble(value);
}
if(ObjectGetString(chart_id, "CP_PutStrike2", OBJPROP_TEXT, 0, value)) {
DynamicPutStrike2 = StringToDouble(value);
}
if(ObjectGetString(chart_id, "CP_PutStrike3", OBJPROP_TEXT, 0, value)) {
DynamicPutStrike3 = StringToDouble(value);
}
InitializeOILevels();
InitializeKeyLevels();
if(InpOISource == OI_SOURCE_CSV_FILE) {
CachedFuturePrice = -1;
LoadOIFromCSV();
}
}
if(ObjectGetString(chart_id, "CP_CallStrike1", OBJPROP_TEXT, 0, value)) { if(ObjectGetString(chart_id, "CP_CallStrike1", OBJPROP_TEXT, 0, value)) {
DynamicCallStrike1 = StringToDouble(value); DynamicCallStrike1 = StringToDouble(value);
} }
@@ -1403,9 +1346,10 @@ void UpdateInputValues() {
} }
InitializeOILevels(); InitializeOILevels();
InitializeKeyLevels(); InitializeKeyLevels();
if(InpOISource == OI_SOURCE_CSV_FILE) { if(InpOISource == OI_SOURCE_CSV_FILE) {
LoadOIFromCSV(); CachedFuturePrice = -1;
} LoadOIFromCSV();
} }
}