For the amateur trader, the biggest issue in using Metastock is how to convert data for it. I originally used end-of-day services such as those provided by Paritech, however, I found this somewhat restrictive as I wanted to control what data I converted e.g. FTSE100 or FTSE250 only. Unfortunately, Metastock does not appear keen to open up the workings of its data format and as such I have never found a pure open-source method of converting data for it. At the heart of my conversion code I use a dll called 'Metalib' (http://trading-tools.com)- my version of the dll is very old now (2007) but still does the job - it is proprietary so you will need to buy it.
Points to note in the ConverterEngine method are:
- The EPIC codes and Prices are pulled in from SQL using a Linq query.
- All existing Metastock data files are deleted to start with.
- There are two parts to the method: OpenSecurityBySymbol and AppendDataRec - the first creates the security file whilst the second adds subsequent price data to it.
- The Sort method just sorts the files by name - the filenames are meaningless gibberish so the Sort method arranges them for when you open them in Metastock.
private readonly MLReader _metaReader;
private readonly MLWriter _metaWriter;
private readonly MLRegistration _mReg;
private MetastockDataContext _db;
private IQueryable _hemsList;
public void ConverterEngine()
{
_db = new MetastockDataContext();
_db.Connection.ConnectionString = Database.ConnectionString;
_hemsList = from epic in _db.StatsLists
where epic.FTSE_Index.Replace("\"", "") == "FTSE100"
|| epic.FTSE_Index.Replace("\"", "") == "FTSE250"
orderby epic.EPIC
select epic;
Console.WriteLine("[][][][][][][][]Doing METASTOCK conversion[][][][][][][][]");
_mReg.SetRegistrationInfo(PUT_YOUR_REG_HERE, KEY_HERE);
if (!Directory.Exists("C:/Metastock/Securities"))
{
Directory.CreateDirectory("C:/Metastock/Securities");
}
foreach (string sFile in Directory.GetFiles("C:/Metastock/Securities"))
{
File.Delete(sFile);
}
foreach (StatsList epicItem in _hemsList)
{
string epic = epicItem.EPIC.Replace("\"", "");
IQueryable<Price> prices = from p in _db.Prices
where p.Epic == epic
orderby p.Date ascending
select p;
if (prices.Any())
{
Console.WriteLine("Processing " + epicItem.Share_Name.Replace("\"", ""));
foreach (Price price in prices)
{
DateTime priceDate = price.Date;
string yahooDate = priceDate.Year + priceDate.Month.ToString("00") +
priceDate.Day.ToString("00");
_metaWriter.OpenDirectory("C:/Metastock/Securities");
if (_metaWriter.bSymbolExists[price.Epic])
{
_metaWriter.OpenSecurityBySymbol(price.Epic);
_metaWriter.AppendDataRec(Convert.ToInt32(yahooDate), 0,
Convert.ToSingle(price.Open),
Convert.ToSingle(price.High),
Convert.ToSingle(price.Low),
Convert.ToSingle(price.Close),
Convert.ToSingle(price.Volume),
0f);
}
else
{
_metaWriter.AppendSecurity(price.Epic, epicItem.Share_Name.Replace("\"", ""),
PERIODICITY.Daily);
_metaWriter.AppendDataRec(Convert.ToInt32(yahooDate), 0,
Convert.ToSingle(price.Open),
Convert.ToSingle(price.High),
Convert.ToSingle(price.Low),
Convert.ToSingle(price.Close),
Convert.ToSingle(price.Volume),
0f);
_metaWriter.CloseSecurity();
}
}
}
}
_metaWriter.CloseDirectory();
Sort();
}
// Private Methods (1)
private void Sort()
{
_metaWriter.OpenDirectory(@"C:\MetaStock\Securities");
_metaWriter.Sort();
_metaWriter.CloseDirectory();
}
No comments:
Post a Comment