Как экспортировать в файл CSV из существующего кода индикатора MT4
Я хотел бы экспортировать результаты в файл CSV. Это индикатор iExposure (iExposure.mq4) из MT4. В настоящее время есть способ, которым я знаю, как экспортировать значения в CSV
Это код, который я пытался использовать, который можно экспортировать в CSV.
int h1;
h1 = FileOpen("data3.csv", FILE_CSV | FILE_WRITE | FILE_READ, ',');
FileSeek( ExtSymbolsSummaries[i][DEALS]=0, ExtSymbolsSummaries[i],
[BUY_PRICE]=0,ExtSymbolsSummaries[i][SELL_LOTS]=0 ,ExtSymbolsSummaries[i]
[SELL_PRICE]=0,ExtSymbolsSummaries[i][NET_LOTS]=0, ExtSymbolsSummaries[i][PROFIT]=0, SEEK_END);
FileWrite(h1, Symbols[i]=SymbolName, ExtSymbolsSummaries[i][DEALS]=0, ExtSymbolsSummaries[i]
[BUY_PRICE]=0,ExtSymbolsSummaries[i][SELL_LOTS]=0 ,ExtSymbolsSummaries[i]
[SELL_PRICE]=0,ExtSymbolsSummaries[i][NET_LOTS]=0, ExtSymbolsSummaries[i][PROFIT]=0 );
FileClose(h1)
Это оригинальный код:
//+------------------------------------------------------------------+
//| iExposure.mq4 |
//| Copyright © 2007, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_minimum 0.0
#property indicator_maximum 0.1
#define SYMBOLS_MAX 1024
#define DEALS 0
#define BUY_LOTS 1
#define BUY_PRICE 2
#define SELL_LOTS 3
#define SELL_PRICE 4
#define NET_LOTS 5
#define PROFIT 6
extern color ExtColor=LightSeaGreen;
string ExtName="Exposure";
string ExtSymbols[SYMBOLS_MAX];
int ExtSymbolsTotal=0;
double ExtSymbolsSummaries[SYMBOLS_MAX][7];
int ExtLines=-1;
string ExtCols[8]={"Symbol",
"Deals",
"Buy lots",
"Buy price",
"Sell lots",
"Sell price",
"Net lots",
"Profit"};
int ExtShifts[8]={ 10, 80, 130, 180, 260, 310, 390, 460 };
int ExtVertShift=14;
double ExtMapBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void init()
{
IndicatorShortName(ExtName);
SetIndexBuffer(0,ExtMapBuffer);
SetIndexStyle(0,DRAW_NONE);
IndicatorDigits(0);
SetIndexEmptyValue(0,0.0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void deinit()
{
int windex=WindowFind(ExtName);
if(windex>0) ObjectsDeleteAll(windex);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
void start()
{
string name;
int i,col,line,windex=WindowFind(ExtName);
//----
if(windex<0) return;
//---- header line
if(ExtLines<0)
{
for(col=0; col<8; col++)
{
name="Head_"+col;
if(ObjectCreate(name,OBJ_LABEL,windex,0,0))
{
ObjectSet(name,OBJPROP_XDISTANCE,ExtShifts[col]);
ObjectSet(name,OBJPROP_YDISTANCE,ExtVertShift);
ObjectSetText(name,ExtCols[col],9,"Arial",ExtColor);
}
}
ExtLines=0;
}
//----
ArrayInitialize(ExtSymbolsSummaries,0.0);
int total=Analyze();
if(total>0)
{
line=0;
for(i=0; i<ExtSymbolsTotal; i++)
{
if(ExtSymbolsSummaries[i][DEALS]<=0) continue;
line++;
//---- add line
if(line>ExtLines)
{
int y_dist=ExtVertShift*(line+1)+1;
for(col=0; col<8; col++)
{
name="Line_"+line+"_"+col;
if(ObjectCreate(name,OBJ_LABEL,windex,0,0))
{
ObjectSet(name,OBJPROP_XDISTANCE,ExtShifts[col]);
ObjectSet(name,OBJPROP_YDISTANCE,y_dist);
}
}
ExtLines++;
}
//---- set line
int digits=MarketInfo(ExtSymbols[i],MODE_DIGITS);
double buy_lots=ExtSymbolsSummaries[i][BUY_LOTS];
double sell_lots=ExtSymbolsSummaries[i][SELL_LOTS];
double buy_price=0.0;
double sell_price=0.0;
if(buy_lots!=0) buy_price=ExtSymbolsSummaries[i][BUY_PRICE]/buy_lots;
if(sell_lots!=0) sell_price=ExtSymbolsSummaries[i][SELL_PRICE]/sell_lots;
name="Line_"+line+"_0";
ObjectSetText(name,ExtSymbols[i],9,"Arial",ExtColor);
name="Line_"+line+"_1";
ObjectSetText(name,DoubleToStr(ExtSymbolsSummaries[i][DEALS],0),9,"Arial",ExtColor);
name="Line_"+line+"_2";
ObjectSetText(name,DoubleToStr(buy_lots,2),9,"Arial",ExtColor);
name="Line_"+line+"_3";
ObjectSetText(name,DoubleToStr(buy_price,digits),9,"Arial",ExtColor);
name="Line_"+line+"_4";
ObjectSetText(name,DoubleToStr(sell_lots,2),9,"Arial",ExtColor);
name="Line_"+line+"_5";
ObjectSetText(name,DoubleToStr(sell_price,digits),9,"Arial",ExtColor);
name="Line_"+line+"_6";
ObjectSetText(name,DoubleToStr(buy_lots-sell_lots,2),9,"Arial",ExtColor);
name="Line_"+line+"_7";
ObjectSetText(name,DoubleToStr(ExtSymbolsSummaries[i][PROFIT],2),9,"Arial",ExtColor);
}
}
//---- remove lines
if(total<ExtLines)
{
for(line=ExtLines; line>total; line--)
{
name="Line_"+line+"_0 ";
ObjectSetText(name,"");
name="Line_"+line+"_1";
ObjectSetText(name,"");
name="Line_"+line+"_2";
ObjectSetText(name,"");
name="Line_"+line+"_3";
ObjectSetText(name,"");
name="Line_"+line+"_4";
ObjectSetText(name,"");
name="Line_"+line+"_5";
ObjectSetText(name,"");
name="Line_"+line+"_6";
ObjectSetText(name,""," ");
name="Line_"+line+"_7";
ObjectSetText(name,""," ");
}
}
//---- to avoid minimum==maximum
ExtMapBuffer[Bars-1]=-1;
//----
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int Analyze()
{
double profit;
int i,index,type,total=OrdersTotal();
//----
for(i=0; i<total; i++)
{
if(!OrderSelect(i,SELECT_BY_POS)) continue;
type=OrderType();
if(type!=OP_BUY && type!=OP_SELL) continue;
index=SymbolsIndex(OrderSymbol());
if(index<0 || index>=SYMBOLS_MAX) continue;
//----
ExtSymbolsSummaries[index][DEALS]++;
profit=OrderProfit()+OrderCommission()+OrderSwap();
ExtSymbolsSummaries[index][PROFIT]+=profit;
if(type==OP_BUY)
{
ExtSymbolsSummaries[index][BUY_LOTS]+=OrderLots();
ExtSymbolsSummaries[index][BUY_PRICE]+=OrderOpenPrice()*OrderLots();
}
else
{
ExtSymbolsSummaries[index][SELL_LOTS]+=OrderLots();
ExtSymbolsSummaries[index][SELL_PRICE]+=OrderOpenPrice()*OrderLots();
}
}
//----
total=0;
for(i=0; i<ExtSymbolsTotal; i++)
{
if(ExtSymbolsSummaries[i][DEALS]>0) total++;
}
//----
return(total);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int SymbolsIndex(string SymbolName)
{
bool found=false;
//----
for(int i=0; i<ExtSymbolsTotal; i++)
{
if(SymbolName==ExtSymbols[i])
{
found=true;
break;
}
}
//----
if(found) return(i);
if(ExtSymbolsTotal>=SYMBOLS_MAX) return(-1);
//----
i=ExtSymbolsTotal;
ExtSymbolsTotal++;
ExtSymbols[i]=SymbolName;
ExtSymbolsSummaries[i][DEALS]=0;
ExtSymbolsSummaries[i][BUY_LOTS]=0;
ExtSymbolsSummaries[i][BUY_PRICE]=0;
ExtSymbolsSummaries[i][SELL_LOTS]=0;
ExtSymbolsSummaries[i][SELL_PRICE]=0;
ExtSymbolsSummaries[i][NET_LOTS]=0;
ExtSymbolsSummaries[i][PROFIT]=0;
//----
return(i);
}
//+------------------------------------------------------------------+
Конец кода
1 ответ
Пример вывода CSV:
В этом примере я опишу способ достижения следующего:
- Добавьте входные строки для имен папок и файлов CSV.
- Создать кнопку для генерации CSV.
- Прослушайте события, чтобы мы могли определить, когда была нажата кнопка.
- Разобрать список объектов и записать имя и описание объектов в файл CSV.
Примечание. Если вы не можете выполнить шаг 2, перейдите к шагу 3 и посмотрите код внутри OnChartEvent()
, а затем настройте его, когда вы хотите написать файл CSV. Тем не менее, имейте в виду, что будет много записи файла, если вы пишете файл каждый раз, когда OnCalculate()
Событие происходит.
поскольку iExposure.mq4
поставляется по умолчанию (по крайней мере, для версии: 4.0 Build 765), давайте начнем с создания дубликата оригинала. Я назвал свой пример как iExposureTest.
Шаг 1: Добавьте входные строки для нашей папки и файла CSV.
Это один из наших самых простых шагов, просто добавьте входные строки для нашей папки и CSV-файла. Я добавил их рядом с другой входной переменной.
//Step 1
input string InputFileName="iExposure.csv"; // File name
input string InputDirectoryName="Data"; // Folder name
Шаг 2: Создайте кнопку CSV.
Включить заголовок для ChartObjectPanel.mqh
, Я решил разместить строку включения непосредственно над входными переменными.
//Part of Step 2
#include <ChartObjects\ChartObjectPanel.mqh>
Это дает нам доступ к созданию CChartObjectButton
типа, и нам нужно будет получить доступ к кнопке Globally
для этого примера, поэтому добавьте следующую строку кода перед OnInit()
,
//Part of Step 2
CChartObjectButton CSVButton;
У нас есть тип кнопки CChartObjectButton
, но он еще не создан. Давайте сделаем это с помощью функции, которую мы вызываем из OnInit()
,
внутри OnInit()
, добавьте это ниже:
//Part of Step 2
CreateCSVButton(0);
Теперь нам нужна актуальная функция, поэтому в конце кода индикатора давайте добавим эту функцию дальше.
//Part of Step 2
bool CreateCSVButton(const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property values
if(!CSVButton.Create(0,"CSVButton",0,10,25,75,15))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
CSVButton.Description("CSV");
CSVButton.FontSize(10);
CSVButton.Corner(CORNER_LEFT_LOWER);
CSVButton.Anchor(ANCHOR_CENTER);
CSVButton.State(false);
return true;
}
На этом этапе, когда мы компилируем, в окне должна быть доступна кнопка CSV. В основном это было создано, чтобы мы могли генерировать CSV одним щелчком мыши. Это должно выглядеть примерно так, как на картинке ниже.
Если у вас есть кнопка CSV, то мы закончили с шагом 2.
Шаг 3: Прослушайте события и запишите, что была нажата кнопка CSV.
Мы можем захватить нужное нам событие с помощью встроенного в OnChartEvent()
,
В нашем OnChartEvent()
мы проверяем, было ли событие CHARTEVENT_OBJECT_CLICK
событие, то если sparam
равно нашему CSVButton
и состояние кнопки истинно, мы делаем нашу работу с файлами.
Также обратите внимание, что мы вызываем функцию WriteCSVObjects
что еще не существует, который мы передаем file_handle
к. Мы создадим это в шаге 4.
//step 3
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
if(id==CHARTEVENT_OBJECT_CLICK)
{
if (sparam=="CSVButton")
{
if(CSVButton.State() == true)
{
ResetLastError();
int file_handle=FileOpen(InputDirectoryName+"//"+InputFileName,FILE_READ|FILE_WRITE|FILE_CSV);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for writing",InputFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//Call Step 4
WriteCSVObjects(file_handle);
//--- close the file
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InputFileName);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",InputFileName,GetLastError());
}
}
ChartRedraw();
}
}
}
Шаг 4: Изучите список объектов и запишите имя и описание в CSV.
Почти готово! Это последняя часть, чтобы решить ваш вопрос. Добавьте эту функцию в конец нашего примера кода.
//Step 4
void WriteCSVObjects(int file_hand)
{
int obj_total=ObjectsTotal();
string name;
string desc;
for(int i=obj_total;i>=0;i--)
{
name = ObjectName(i);
desc = ObjectDescription(name);
if(name == "")
{
name = "Empty Name";
}
if(desc == "")
{
desc = "Empty Desc";
}
FileWrite(file_hand, name + "," + desc);
}
}
Обратите внимание, что в приведенной выше функции мы зацикливаем объекты и выписываем имя и описание для каждого объекта. Порядок вывода и объектов может не соответствовать вашей цели, поэтому внесите соответствующие изменения.
На этом этапе, когда мы скомпилируем и нажмем кнопку CSV, он должен сгенерировать значения в файл CSV, сохраненный в Files//Data//iExposure.csv
,