Equilibrium/Indicators/Equilibrium.mq5

496 строки
54 КиБ
MQL5
Исходный Постоянная ссылка Обычный вид История

2025-05-30 14:53:03 +02:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| Equilibrium.mq5 |
//| Copyright 2019, Thomas Schwabhaeuser |
//| schwabhaeuser@icloud.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Thomas Schwabhaeuser"
#property link "schwabhaeuser@icloud.com"
#property description "Product of rates of added symbols:"
#property description "1. uses ask/bid prices for Equilibrium's ask/bid rates,"
#property description "2. uses ask/bid according to symbol's direction for Equilibrium's enter/leave rate, resp."
#property description "(intended for adding symbols whose product should equal one.)"
#property version "1.00"
//+------------------------------------------------------------------+
//| BACKLOG |
//| |
//| 1. Extract the functions |
//| bool parsePortfolioString(portfolio,directions,symbols[]) |
//| bool parseDirection(portfolio,string_index,array[]) |
//| bool parseSymbol(portfolio,string_index,array[]) |
//| int getNextIndex(portfolio,string_index) |
//| void PrintNextIndex(fn,pf,i,p,m,r) |
//| bool IsValidSymbolName(string symbol) |
//| string ToString(string &array[]) |
//| string ToString(ENUM_DIRECTION &array[]) |
//| to a new class CPortfolio encapsulating the 2 arrays |
//| string ExtSymbols[]; |
//| ENUM_DIRECTION ExtDirections[]; |
//| and providing the methods |
//| parse(string portfolio); |
//| int Total(void); |
//| string GetSymbol(int i); |
//| ENUM_DIRECTION GetDiretion(int i); |
//| string ToString(); |
//| |
//| 2. An expert should use the buffer MARGIN for risk management |
//| as ususal: |
//| LotSize = AccountInfoDouble(ACCOUNT_MARGIN_FREE)/MARGIN |
//| where MARGIN is computed by the indicator as follows: |
//| for(int i=0;i<#Symbols;i++): |
//| OrderCalcMargin(ExtDirections[i],ExtSymbols[i],1.0, |
//| EnterPrice,value) |
//| MARGIN += value; |
//| |
//| 3. Then the OnTick() handler of an expert is straightforward |
//| if(CheckClose()): |
//| for(int i=0;i<#Symbols;i++): |
//| Trade.Close(ExtSymbols[i]); |
//| else: |
//| if(CheckOpen()): |
//| for(int i=0;i<#Symbols;i++): |
//| Trade.Open(LotSize,ExtSymbols[i]); |
//| |
//+------------------------------------------------------------------+
//#property indicator_chart_window // K2>48BL 8=48:0B>@ 2 >:=> 3@0D8:0
#property indicator_separate_window
#property indicator_buffers 5 // >;8G5AB2> 1CD5@>2 4;O @0AGQB0 8=48:0B>@0
#property indicator_plots 4 // >;8G5AB2> 3@0D8G5A:8E A5@89
//--- &25B0 F25B>2KE 1CD5@>2
//#property indicator_color1 clrDodgerBlue,C'0,50,100'
//#property indicator_color2 clrMagenta,C'130,0,130'
//#property indicator_color3 clrGold,C'160,140,0'
//#property indicator_color4 clrAqua,C'0,140,140'
//#property indicator_color5 clrLimeGreen,C'20,80,20'
//---
#property indicator_label1 "Enter"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_label2 "Leave"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrGreen
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
#property indicator_label3 "Bid"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrBlue
#property indicator_style3 STYLE_SOLID
#property indicator_width4 1
#property indicator_label4 "Ask"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrMagenta
#property indicator_style4 STYLE_SOLID
#property indicator_width4 1
#property indicator_label4 "Margin"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrFireBrick
#property indicator_style4 STYLE_SOLID
#property indicator_width4 1
//---
#include "../Include/MultiSymbolIndicator.mqh"
//--- input parameters
input string InpPortfolio="EURUSD-EURGBP-GBPUSD"; // Buy/Sell (+/-) Symbols
//---- buffers
//--- TODO:
// enum ENUM_BUFFERS_EQL
// {
// BUFFER_ENTER = 0,
// BUFFER_LEAVE = 1,
// BUFFER_BID = 2,
// BUFFER_ASK = 3,
// BUFFER_MARGIN = 4,
// BUFFERS_TOTAL = 5
// };
// struct BufferType { double data[]; };
// BufferType ExtBuffersEql[BUFFERS_TOTAL];
//--- SetPropertiesIndicator():
// for(int b=0; b<BUFFERS_TOTAL; b++)
// SetIndexBuffer(b,ExtBuffersEql[b].data,INDICATOR_DATA);
//--- PrepareOnCalculate():
// for(int b=0; b<BUFFERS_TOTAL; b++)
// ArrayInitialize(ExtBuffersEql[b].data,EMPTY_VALUE);
double ExtEnterBuffer[];
double ExtLeaveBuffer[];
double ExtBidBuffer[];
double ExtAskBuffer[];
double ExtMarginBuffer[];
//--- gobal variables
CMultiSymbolIndicator ExtIndicator;
//--- Portfolio
// TODO: To be extracted to CPortfolio
string ExtSymbols[];
ENUM_DIRECTION ExtDirections[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- TODO: Move parsing of portfolio string to CMultiSymbolIndicator
//--- TODO: Extract parsing of portfolio string into a separate class
//--- DONE: parse portfolio initializing global variables
ArrayResize(ExtSymbols,0);
ArrayResize(ExtDirections,0);
parsePortfolioString(InpPortfolio,ExtDirections,ExtSymbols);
//--- DONE: add symbols with their direction to CMultiSymbolIndicator
if(ArraySize(ExtSymbols)!=ArraySize(ExtDirections))
return(INIT_FAILED);
string s="";
for(int i=0;i<-1+ArraySize(ExtSymbols);i++) s+=ExtSymbols[i]+", ";
s+="and "+ExtSymbols[-1+ArraySize(ExtSymbols)];
Print(__FUNCTION__+": Adding watchers for the "+ArraySize(ExtSymbols)+" symbols "+s);
for(int i=0;i<ArraySize(ExtSymbols);i++)
{
//Print(__FUNCTION__+": ExtIndicator.Add("+ExtSymbols[i]+","+
// EnumToString(ExtDirections[i])+")");
if(!ExtIndicator.AddWatcher(ExtSymbols[i],ExtDirections[i]))
return(INIT_FAILED);
}
ExtIndicator.OnInit();
//--- TODO:
// Try to map indicator buffers in the class CMultiSymbolIndicator
// For adding the buffers to ExtIndicator one by one we are going to use
// ExtIndicator.AddEnterBuffer(double &buffer[]);
// ExtIndicator.AddLeaveBuffer(double &buffer[]);
// ExtIndicator.AddBidBuffer(double &buffer[]);
// ExtIndicator.AddAskBuffer(double &buffer[]);
// ExtIndicator.AddMarginBuffer(double &buffer[]);
// which still needs to be implemented.
//--- indicator buffers mapping
SetIndexBuffer(0,ExtEnterBuffer,INDICATOR_DATA);
SetIndexBuffer(1,ExtLeaveBuffer,INDICATOR_DATA);
SetIndexBuffer(2,ExtBidBuffer,INDICATOR_DATA);
SetIndexBuffer(3,ExtAskBuffer,INDICATOR_DATA);
SetIndexBuffer(4,ExtMarginBuffer,INDICATOR_DATA);
//--- indicator digits
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+2);
//--- set draw begin is not necessary,
// we can start calculating at the first bar.
//--- indicator short name
IndicatorSetString(INDICATOR_SHORTNAME,"EQUILIBRIUM");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
Print(__FUNCTION__+
"("+rates_total+","+prev_calculated+",...): delegating to CMultiSymbolIndicator::OnCalculate()");
//---
int result=ExtIndicator.OnCalculate(rates_total,prev_calculated,time,open,high,low,close,
tick_volume,volume,spread);
//--- TODO:
// Find out how to fill the buffers
// double ExtEnterBuffer[];
// double ExtLeaveBuffer[];
// double ExtBidBuffer[];
// double ExtAskBuffer[];
// Of course, we would prefer ExtIndicator.OnCalculate() to invoke the FillBuffer functions.
// However, the buffers to be filled are in this indicator main program file while the data
// for filling is maintained in the indicator class. Therefore we need to pass the indicator
// buffers by reference to filling methods of the indicator object.
// Thus the indicator values must be written to the indicator buffers as follows:
ExtIndicator.FillEnterBuffer(rates_total,prev_calculated,ExtEnterBuffer);
ExtIndicator.FillLeaveBuffer(rates_total,prev_calculated,ExtLeaveBuffer);
ExtIndicator.FillBidBuffer(rates_total,prev_calculated,ExtBidBuffer);
ExtIndicator.FillAskBuffer(rates_total,prev_calculated,ExtAskBuffer);
ExtIndicator.FillMarginBuffer(rates_total,prev_calculated,ExtMarginBuffer);
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Timer function |
//+------------------------------------------------------------------+
void OnTimer()
{
//---
ExtIndicator.OnTimer();
}
//--- 2019.07.25
//
//DJ 0 18:49:50.619 Symbols EURUSD: symbol to be synchronized
//DL 0 18:49:50.620 Symbols EURUSD: symbol synchronized, 3544 bytes of symbol info received
//JN 0 18:49:50.880 History EURUSD: history synchronization started
//DG 0 18:49:51.097 History EURUSD: load 27 bytes of history data to synchronize in 0:00:00.002
//EL 0 18:49:51.097 History EURUSD: history synchronized from 2016.01.03 to 2019.03.25
//GE 0 18:49:51.097 Ticks EURUSD: ticks synchronization started
//QN 0 18:49:51.098 Ticks EURUSD: load 34 bytes of tick data to synchronize in 0:00:00.000
//HS 0 18:49:51.099 Ticks EURUSD: history ticks synchronized from 2018.12.20 to 2019.03.24
//DK 0 18:49:51.295 History EURUSD,M10: history cache allocated for 45737 bars and contains 37302 bars from 2018.01.01 23:00 to 2019.01.01 23:50
//JJ 0 18:49:51.295 History EURUSD,M10: history begins from 2018.01.01 23:00
//LN 0 18:49:51.556 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CSymbolWatcher::OnCalculate(37302,0): start =0, Symbol=EURUSD
//
//FR 0 18:49:51.556 Symbols EURGBP: symbol to be synchronized
//HK 0 18:49:51.557 Symbols EURGBP: symbol synchronized, 3544 bytes of symbol info received
//JP 0 18:49:51.772 History EURGBP: history synchronization started
//FI 0 18:49:51.908 History EURGBP: load 27 bytes of history data to synchronize in 0:00:00.001
//MF 0 18:49:51.908 History EURGBP: history synchronized from 2017.01.02 to 2019.03.25
//RM 0 18:49:51.909 Ticks EURGBP: ticks synchronization started
//IF 0 18:49:54.830 Ticks EURGBP: load 34 bytes of tick data to synchronize in 0:00:02.922
//NI 0 18:49:54.830 Ticks EURGBP: history ticks synchronized from 2018.12.20 to 2019.03.13
//GQ 0 18:49:54.851 History EURGBP,M10: history cache allocated for 8439 bars and contains 4 bars from 2019.01.01 23:00 to 2019.01.01 23:50
//MN 0 18:49:54.851 History EURGBP,M10: history begins from 2019.01.01 23:00
//LF 0 18:49:54.851 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CSymbolWatcher::OnCalculate(37302,0): start =0, Symbol=EURGBP
//
//CI 0 18:49:54.851 Symbols GBPUSD: symbol to be synchronized
//RP 0 18:49:54.851 Symbols GBPUSD: symbol synchronized, 3544 bytes of symbol info received
//LM 0 18:49:55.105 History GBPUSD: history synchronization started
//RE 0 18:49:55.234 History GBPUSD: load 27 bytes of history data to synchronize in 0:00:00.001
//QS 0 18:49:55.234 History GBPUSD: history synchronized from 2016.01.03 to 2019.03.25
//FR 0 18:49:55.235 Ticks GBPUSD: ticks synchronization started
//QI 0 18:49:58.432 Ticks GBPUSD: load 34 bytes of tick data to synchronize in 0:00:03.187
//PL 0 18:49:58.432 Ticks GBPUSD: history ticks synchronized from 2018.12.20 to 2019.03.13
//RS 0 18:49:58.651 History GBPUSD,M10: history cache allocated for 45729 bars and contains 37294 bars from 2018.01.01 23:00 to 2019.01.01 23:50
//DN 0 18:49:58.651 History GBPUSD,M10: history begins from 2018.01.01 23:00
//EF 0 18:49:58.653 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CSymbolWatcher::OnCalculate(37302,0): start =0, Symbol=GBPUSD
//
//EI 0 18:49:58.653 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CMultiSymbolIndicator::OnCalculate: watchers prepared with data from i=start=0 while i<5<37302. INCOMPLETE!
//
//ES 3 18:50:01.631 Ticks EURGBP : 2019.03.14 23:59 - real ticks absent for 1 minutes out of 1434 total minute bars within a day
//ES 3 18:50:01.632 Ticks EURGBP : 2019.03.15 23:59 - real ticks absent for 1 minutes out of 1320 total minute bars within a day
//CR 3 18:50:01.632 Ticks EURGBP : 2019.03.17 23:59 - real ticks absent for 1 minutes out of 110 total minute bars within a day
//KS 3 18:50:01.632 Ticks EURGBP : 2019.03.18 23:59 - real ticks absent for 1 minutes out of 1440 total minute bars within a day
//KS 3 18:50:01.633 Ticks EURGBP : 2019.03.19 23:59 - real ticks absent for 1 minutes out of 1440 total minute bars within a day
//OS 3 18:50:01.633 Ticks EURGBP : 2019.03.20 23:59 - real ticks absent for 1 minutes out of 1439 total minute bars within a day
//NS 3 18:50:01.634 Ticks EURGBP : 2019.03.21 23:59 - real ticks absent for 1 minutes out of 1438 total minute bars within a day
//IS 3 18:50:01.634 Ticks EURGBP : 2019.03.22 23:59 - real ticks absent for 1 minutes out of 1320 total minute bars within a day
//GR 3 18:50:01.634 Ticks EURGBP : 2019.03.24 23:59 - real ticks absent for 1 minutes out of 114 total minute bars within a day
//IR 0 18:50:01.634 Ticks EURGBP : real ticks begin from 2018.12.20 00:00:00
//EH 3 18:50:01.634 Ticks EURGBP : 2019.01.02 00:00 - 2019.03.25 00:00 real ticks absent for 9 minutes of 83317 total minute bars, every tick generation used
//EI 0 18:50:03.652 Ticks EURUSD : real ticks begin from 2018.12.20 00:00:00
//KP 3 18:50:06.776 Ticks GBPUSD : 2019.03.11 23:59 - real ticks absent for 834 minutes out of 1440 total minute bars within a day
//RG 3 18:50:06.788 Ticks GBPUSD : 2019.03.12 23:59 - no real ticks within a day
//IN 3 18:50:06.802 Ticks GBPUSD : 2019.03.14 23:59 - real ticks absent for 1 minutes out of 1435 total minute bars within a day
//HN 3 18:50:06.803 Ticks GBPUSD : 2019.03.15 23:59 - real ticks absent for 1 minutes out of 1320 total minute bars within a day
//NS 3 18:50:06.803 Ticks GBPUSD : 2019.03.17 23:59 - real ticks absent for 1 minutes out of 113 total minute bars within a day
//DM 3 18:50:06.804 Ticks GBPUSD : 2019.03.18 23:59 - real ticks absent for 1 minutes out of 1436 total minute bars within a day
//QM 3 18:50:06.804 Ticks GBPUSD : 2019.03.19 23:59 - real ticks absent for 1 minutes out of 1438 total minute bars within a day
//HM 3 18:50:06.805 Ticks GBPUSD : 2019.03.20 23:59 - real ticks absent for 1 minutes out of 1438 total minute bars within a day
//NM 3 18:50:06.805 Ticks GBPUSD : 2019.03.21 23:59 - real ticks absent for 1 minutes out of 1440 total minute bars within a day
//MM 3 18:50:06.806 Ticks GBPUSD : 2019.03.22 23:59 - real ticks absent for 1 minutes out of 1320 total minute bars within a day
//IP 3 18:50:06.806 Ticks GBPUSD : 2019.03.24 23:59 - real ticks absent for 1 minutes out of 115 total minute bars within a day
//FR 0 18:50:06.806 Ticks GBPUSD : real ticks begin from 2018.12.20 00:00:00
//CH 3 18:50:06.806 Ticks GBPUSD : 2019.01.02 00:00 - 2019.03.25 00:00 real ticks absent for 2281 minutes of 83395 total minute bars, every tick generation used
//NE 3 18:50:06.806 Ticks GBPUSD : 2019.01.02 00:00 - 2019.03.25 00:00 real ticks absent for 1 whole days
//IJ 0 18:50:06.808 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 OnCalculate(37303,37302,...): delegating to CMultiSymbolIndicator::OnCalculate()
//QI 0 18:50:06.808 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CMultiSymbolIndicator::OnCalculate(37303,37302,...): start =37301, updating 3 watchers...
//KN 0 18:50:06.808 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CSymbolWatcher::OnCalculate(37303,37302): start =37301, Symbol=EURUSD
//RN 0 18:50:06.808 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CSymbolWatcher::OnCalculate(37303,37302): start =37301, Symbol=EURGBP
//RQ 0 18:50:06.808 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CSymbolWatcher::OnCalculate(37303,37302): start =37301, Symbol=GBPUSD
//HO 0 18:50:06.808 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CMultiSymbolIndicator::OnCalculate: watchers prepared with data from i=start=37301 while i<37301<37303. INCOMPLETE!
//KH 0 18:50:06.823 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 OnCalculate(37303,37303,...): delegating to CMultiSymbolIndicator::OnCalculate()
//GJ 0 18:50:06.823 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CMultiSymbolIndicator::OnCalculate(37303,37303,...): start =37302, updating 3 watchers...
//EO 0 18:50:06.823 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CSymbolWatcher::OnCalculate(37303,37303): start =37302, Symbol=EURUSD
//HO 0 18:50:06.823 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CSymbolWatcher::OnCalculate(37303,37303): start =37302, Symbol=EURGBP
//HP 0 18:50:06.823 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CSymbolWatcher::OnCalculate(37303,37303): start =37302, Symbol=GBPUSD
//IO 0 18:50:06.823 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CMultiSymbolIndicator::OnCalculate: watchers prepared with data from i=start=37302 while i<37302<37303. INCOMPLETE!
//KG 0 18:50:06.838 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 OnCalculate(37303,37303,...): delegating to CMultiSymbolIndicator::OnCalculate()
//FJ 0 18:50:06.838 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CMultiSymbolIndicator::OnCalculate(37303,37303,...): start =37302, updating 3 watchers...
//HL 0 18:50:06.838 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CSymbolWatcher::OnCalculate(37303,37303): start =37302, Symbol=EURUSD
//EN 0 18:50:06.838 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CSymbolWatcher::OnCalculate(37303,37303): start =37302, Symbol=EURGBP
//EO 0 18:50:06.838 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CSymbolWatcher::OnCalculate(37303,37303): start =37302, Symbol=GBPUSD
//EN 0 18:50:06.838 Equilibrium (EURUSD,M10) 2019.01.02 00:00:00 CMultiSymbolIndicator::OnCalculate: watchers prepared with data from i=start=37302 while i<37302<37303. INCOMPLETE!
//FG 0 18:50:06.852 Equilibrium (EURUSD,M10) 2019.01.02 00:00:01 OnCalculate(37303,37303,...): delegating to CMultiSymbolIndicator::OnCalculate()
//GI 0 18:50:06.852 Equilibrium (EURUSD,M10) 2019.01.02 00:00:01 CMultiSymbolIndicator::OnCalculate(37303,37303,...): start =37302, updating 3 watchers...
//EL 0 18:50:06.852 Equilibrium (EURUSD,M10) 2019.01.02 00:00:01 CSymbolWatcher::OnCalculate(37303,37303): start =37302, Symbol=EURUSD
//HN 0 18:50:06.852 Equilibrium (EURUSD,M10) 2019.01.02 00:00:01 CSymbolWatcher::OnCalculate(37303,37303): start =37302, Symbol=EURGBP
//HO 0 18:50:06.852 Equilibrium (EURUSD,M10) 2019.01.02 00:00:01 CSymbolWatcher::OnCalculate(37303,37303): start =37302, Symbol=GBPUSD
//---
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool parsePortfolioString(string portfolio,ENUM_DIRECTION &directions[],string &symbols[])
{
//int array_index=0;
int string_index=0;
int length=StringLen(portfolio);
while(string_index<length)
{
Print(__FUNCTION__+
"(\""+portfolio+"\","+ToString(directions)+","+ToString(symbols)+"): "+
"string_index=="+string_index+", length=="+length);
if(!getDirection(portfolio,string_index,directions))
return(false);
if(!getSymbol(portfolio,string_index,symbols))
return(false);
}
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool getDirection(string portfolio,int &string_index,ENUM_DIRECTION &array[])
{
ushort character=StringGetCharacter(portfolio,string_index);
ENUM_DIRECTION direction=BUY;
if(character=='+')
string_index+=1; // discard matched character
if(character=='-')
{
direction=SELL;
string_index+=1; // discard matched character
}
// DONE: add direction to ExtDirections
// if(array_index!=ArraySize(array))
// {
// Print(__FUNCTION__+": array_index=="+array_index+"!="+ArraySize(array)+"==ArraySize(array)");
// return(false);
// }
int array_index=ArraySize(array);
int new_size=array_index+1;
ArrayResize(array,new_size);
array[array_index]=direction;
Print(__FUNCTION__+": added direction array["+array_index+"]=="+
EnumToString(array[array_index]));
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool getSymbol(string portfolio,int &string_index,string &array[])
{
int next_index=getNextIndex(portfolio,string_index);
int length;
if(next_index==-1)
length=StringLen(portfolio)-string_index;
else
length=next_index-string_index;
Print(__FUNCTION__+
"(\""+portfolio+"\","+string_index+",array): "+
"next_index=="+next_index+", length=="+length);
if(length<3)
return(false);
string symbol=StringSubstr(portfolio,string_index,length);
string_index+=length; // discard what should be a symbol name
if(!IsValidSymbolName(symbol))
return(false);
// DONE: add symbol to ExtSymbols
int array_index=ArraySize(array);
int new_size=array_index+1;
ArrayResize(array,new_size);
array[array_index]=symbol;
Print(__FUNCTION__+": added symbol array["+array_index+"]=="+array[array_index]);
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void PrintNextIndex(string fn,string pf,int i,int p,int m,int r)
{
Print(fn+"(\""+pf+"\","+i+") == "+r+" <= "+"plus_index=="+p+", "+"minus_index=="+m);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int getNextIndex(string portfolio,int string_index)
{
int plus_index=StringFind(portfolio,"+",string_index);
int minus_index=StringFind(portfolio,"-",string_index);
if(plus_index==-1 && minus_index==-1)
{
PrintNextIndex(__FUNCTION__,portfolio,string_index,plus_index,minus_index,-1);
return(-1);
}
if(plus_index==-1)
{
PrintNextIndex(__FUNCTION__,portfolio,string_index,plus_index,minus_index,minus_index);
return(minus_index);
}
if(minus_index==-1)
{
PrintNextIndex(__FUNCTION__,portfolio,string_index,plus_index,minus_index,plus_index);
return(plus_index);
}
if(plus_index<minus_index)
{
PrintNextIndex(__FUNCTION__,portfolio,string_index,plus_index,minus_index,plus_index);
return(plus_index);
}
else
{
PrintNextIndex(__FUNCTION__,portfolio,string_index,plus_index,minus_index,minus_index);
return(minus_index);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool IsValidSymbolName(string symbol)
{
// TODO: check if symbol is the valid name of a selectable symbol
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string ToString(string &array[])
{
string result="{";
for(int i=0;i<ArraySize(array);i++)
{
result+=array[i];
if(i<ArraySize(array)-1)
result+=",";
}
result+="}";
return(result);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string ToString(ENUM_DIRECTION &array[])
{
string result="{";
for(int i=0;i<ArraySize(array);i++)
{
result+=EnumToString(array[i]);
if(i<ArraySize(array)-1)
result+=",";
}
result+="}";
return(result);
}
//+------------------------------------------------------------------+