stevehopwoodforex.com
https://www.stevehopwoodforex.com/phpBB3/
Print view

Programmagically loading multiple sets of Settings
https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?t=4689
Page 1 of 1
Author:  oliverjp [ Wed Apr 20, 2016 4:26 pm ]
Post subject:  Programmagically loading multiple sets of Settings

Programmagically loading multiple sets of Settings – for multiple flexibility or multi-instances

Someone was asking in the HGBnG thread about programmatically inputting Settings and it reminded me that I had put together some code and infrastructure to do something useful on this front a while back, so I thought I would share the idea and the nascent code.

This all worked OK in the end but was the first and only EA that I used it in so far so I haven’t tidied it up any more… or indeed tweaked it for latest versions of Empty4, Excel and VB. Feel free to use the idea/code as you wish.

So, the problem is, how to easily manage piles of big Settings files in a live or test environment. The answer I came up with was to dynamically load the Settings as and when required, but to manage them externally using an Excel spreadsheet. That way, an end-user could use Excel to have this big matrix of easily-changeable different settings that could be called when the EA needed them. In my case, it was many different sets of Settings to trade different news releases, but the concept is easily translated to different uses. I used Excel as the front end because I wanted to add some maths later to calculate momentum of PriceAction as news was released and then dynamically adjust the settings, but Access or .Net/SQL would be fine too if you could be bothered with the extra work. In the case of something like HGBnG it could be a great way to record, control and use multiple settings in a forward test environment.

So, here’s how I did it:
Part 1: The Excel Frontend – the bit that makes it all worthwhile
NewsScoop1.jpg
NewsScoop2.jpg

Part 2: Behind the scenes in Excel the main pretty sheet gets copied to a plain sheet that is easier to output as a CSV file and there is a little VB macro to handle the output when you push the export button:

Code: Select all

Sub Button10_Click()
Dim MyPath As String
Dim MyPath2 As String
Dim MyMagic As String
Dim MyFileName As String
Application.DisplayAlerts = False
'The path and file names:
MyMagic = Range("i9").Value
MyPath = Range("i10").Value
MyPath2 = Range("i11").Value
MyFileName = "SettingsInput" & MyMagic & ".csv"
MyFileName2 = "NewsInput" & MyMagic & ".csv"
'Makes sure the path name ends with "\":
If Not Right(MyPath, 1) = "\" Then MyPath = MyPath & "\"
If Not Right(MyPath2, 1) = "\" Then MyPath2 = MyPath2 & "\"
'Copies the sheet to a new workbook:
Sheets("SettingsOutput").Copy
'The new workbook becomes Activeworkbook:
With ActiveWorkbook
'Saves the new workbook to given folder / filename:
    .SaveAs Filename:= _
        MyPath & MyFileName, _
        FileFormat:=xlCSV, _
        CreateBackup:=False
'Saves the new workbook to given folder / filename:
    .SaveAs Filename:= _
        MyPath2 & MyFileName, _
        FileFormat:=xlCSV, _
        CreateBackup:=False
'Closes the file
    .Close False
End With

Sheets("NewsOutput").Copy
'The new workbook becomes Activeworkbook:
With ActiveWorkbook
'Saves the new workbook to given folder / filename:
    .SaveAs Filename:= _
        MyPath & MyFileName2, _
        FileFormat:=xlCSV, _
        CreateBackup:=False
'Saves the new workbook to given folder / filename:
    .SaveAs Filename:= _
        MyPath2 & MyFileName2, _
        FileFormat:=xlCSV, _
        CreateBackup:=False
'Closes the file
    .Close False
End With

Application.DisplayAlerts = True
End Sub 


Part 3: Code in the EA to import settings matrix when required. For a small matrix I found it easier to import the whole lot once, but for a large matrix you would probably be better loading up just the column (set) you needed at the time.

Code: Select all

/+--------------------------------------------------------------------+
//| Load SettingsInput files to SettingsArray  |
//+--------------------------------------------------------------------+
   
   settingsfile1 = "SettingsInput" + magic + ".csv";
   handle1 = FileOpen(settingsfile1,FILE_CSV|FILE_READ,',');
   
   if(handle1 < 0)  
     {
     Print("ALERT!!! - OPTIMISE MODE: NO SettingsInput FILE TO OPEN: ",settingsfile,"  (error: ",GetLastError(),"}", "  PROCEEDING IN ORIGINAL Empty4 MODE TO ALLOW OPTIMISATION!!!");
     return(-1);
     }
     
  while (!FileIsEnding(handle1))  
     {
     while (!FileIsLineEnding(handle1))
       {
       SettingsArray[ii,jj] = FileReadString(handle1);
       ii++;
       }
     while (!FileIsEnding(handle1))
       {
       jj++;
       ii = 0;
       //Print("DEBUG: jj = ",jj);
       SettingsArray[ii,jj] = FileReadString(handle1);
       ii = 1;
       break;
       }    
     }
   FileClose(handle1);     
return(0);
}

Part 4: Finally, map the appropriate set of Settings (column in the SettingsInput Array) to overwrite any Settings you have already loaded in the EA via Extern, etc. (Tip: Useful to also have a default set of settings inside the EA so it will work OOTB for testing!)

Code: Select all

//+------------------------------------------------------------------+
//| ReadSpecificSettings                                             |
//+------------------------------------------------------------------+
int ReadSpecificSettings(int columnindex)
{

SettingsSet   				= StrToInteger(SettingsArray[columnindex, 0]);
SettingComments 			= SettingsArray[columnindex, 1];
SetupSecondsBefore			= StrToInteger(SettingsArray[columnindex, 2]);
RemoveSecondsAfter			= StrToInteger(SettingsArray[columnindex, 3]);
BarsLookBack				= StrToInteger(SettingsArray[columnindex, 4]);
BarTF						= StrToInteger(SettingsArray[columnindex, 5]);
GapPipsLong					= StrToInteger(SettingsArray[columnindex, 6]);
GapPipsShort				= StrToInteger(SettingsArray[columnindex, 7]);
OCO							= StrToInteger(SettingsArray[columnindex, 8]);
RiskPcnt					= StrToDouble(SettingsArray[columnindex, 9]);
EnableKSTFilter				= StrToInteger(SettingsArray[columnindex, 10]);
ModifyRiskWithTrend			= StrToDouble(SettingsArray[columnindex, 11]);	
ModifyRiskAgainstTrend		= StrToDouble(SettingsArray[columnindex, 12]);
ProfitPipsToStartTS			= StrToDouble(SettingsArray[columnindex, 13]);
EntryToTP1_StopLossPips		= StrToDouble(SettingsArray[columnindex, 14]);
EntryToTP1_TrailingStopPips	= StrToDouble(SettingsArray[columnindex, 15]);
TP1_TakeProfitPips			= StrToDouble(SettingsArray[columnindex, 16]);
TP1_ProportionToClose		= StrToDouble(SettingsArray[columnindex, 17]);
TP1ToTP2_StopLossPips		= StrToDouble(SettingsArray[columnindex, 18]);
TP1ToTP2_TrailingStopPips	= StrToDouble(SettingsArray[columnindex, 29]);
TP2_TakeProfitPips			= StrToDouble(SettingsArray[columnindex, 20]);
TP2_ProportionToClose		= StrToDouble(SettingsArray[columnindex, 21]);
TP2ToTP3_StopLossPips		= StrToDouble(SettingsArray[columnindex, 22]);
TP2ToTP3_TrailingStopPips	= StrToDouble(SettingsArray[columnindex, 23]);
TP3_TakeProfitPips			= StrToDouble(SettingsArray[columnindex, 24]);
TP3_ProportionToClose		= StrToDouble(SettingsArray[columnindex, 25]);
AfterTP3_StopLossPips		= StrToDouble(SettingsArray[columnindex, 26]);
AfterTP3_TrailingStopPips	= StrToDouble(SettingsArray[columnindex, 27]);
KillOrderSeconds_NoProfit	= StrToInteger(SettingsArray[columnindex, 28]);
KillOrderSeconds_Profit		= StrToInteger(SettingsArray[columnindex, 29]);
KillOrderSeconds_NoTP1		= StrToInteger(SettingsArray[columnindex, 30]);
KillOrderSeconds_NoTP2		= StrToInteger(SettingsArray[columnindex, 31]);
BarsToCount					= StrToInteger(SettingsArray[columnindex, 32]);
ATR_Period					= StrToInteger(SettingsArray[columnindex, 33]);
ATR_Multiplier				= StrToDouble(SettingsArray[columnindex,  34]);	
KST_TF						= StrToInteger(SettingsArray[columnindex, 35]);
NewsPeg1				    = (SettingsArray[columnindex, 36]);
NewsPeg2					= (SettingsArray[columnindex, 37]);
Risk_00_01					= StrToDouble(SettingsArray[columnindex, 38]);
Risk_01_02					= StrToDouble(SettingsArray[columnindex, 39]);
Risk_02_03					= StrToDouble(SettingsArray[columnindex, 40]);
Risk_03_04					= StrToDouble(SettingsArray[columnindex, 41]);
…
Another pile of 30 or so settings
…
MondayFirstEntryHour 		= StrToInteger(SettingsArray[columnindex, 69]);

TradeHighNews				= StrToInteger(SettingsArray[columnindex, 70]);
TradeMediumNews  			= StrToInteger(SettingsArray[columnindex, 71]);


strAccRisk = RiskToStr(RiskPcnt,0);
InitHours();
RefreshLabels();

return(1);
}


Have fun if you decide to play with it!

All the best

Jeff
Author:  cyberevil [ Wed Apr 20, 2016 6:53 pm ]
Post subject:  Programmagically loading multiple sets of Settings

Thanks Jeff, much appreciated! I'll give it a go over the weekend!
All times are UTC Page 1 of 1