This post is not about C# 4.0 programming itself but what have been done so far. Please keep in mind I'm IT guy who is learning C# 4.0 (I'm experienced in VB and VBscript ) and how trading world works in parallel.
There is one more form accessible which (from Main in menu bar or Trader 2012 item in 11) covers trader's portfolio (probably the most important part of trading ;-) ). Data are stored in Access database and managed by SQL. Also, on this form hidden frame(at the moment) can be invoked where trading transactions can be entered. So, this is only part of whole functionality but still enough to demonstrate C# 4.0 against Japanese candlesticks, trading volumes, three days flag and RSI. Development is in progress and new options will be added.
1. Table with history trading information which could be entered manually or pulled/filled from Internet. Also, if I click on certain date in the past, day analyze of that row date will happen. Candles will be redrawn and new findings will be placed in 3. It is useful to test trading strategies.
2. During trading day I can follow more shares which can be seen in 12. So, if I hit "timer Stopped" (it will change his label to "timer Started" and back color to red) button program will pull data (price) form Internet in a pace defined in field before "sec." label. Next field defines time of a day after which automatic update of trading information will stop.
3. Findings according to Japanese candlesticks and volumes for trading day. Back color is the same as for "Conclusion" field in 6.
4. Findings from previous trading day for easier trading decisions, since trading is field full of explosive devices which can blow out money.
5. During trading day field in green (it means present prices is bigger then previous) fills last row in table 1 in appropriate, in case I enter data manually. Two next fields are prices to Sell/Buy with commission. Two fields bellow represents Bid and Ask prices. These fields are filled/calculated if automatic pulling is chosen.
6. Actually this puts this program to an expert system. It consider three (at the moment) parameters and suggest action. At the moment, he says "Do not buy" ("Do not sell", "Buy", "Sell" or "Unknown" are other options) since price suggest buying action. Back color is yellow and could be white, green or red depending on suggested action.
7. These are live transactions with zero and one per cent profit. If selected (by application according to actual price) it means it could be sold with profit. Otherwise, no profit.
8. These are transaction from the past so I can follow what I did in past. These are very useful if kept up to date. Frame which maintains data of 7. and 8. can be invoked by Menu-> Ledger or button "Ledg/stats".
9. RSI as described in previous chapter. It is automatically recalculated by change of green field in 5. It can be used to test RSI limits with no influence to actual data.
10. This is Japanese candlestick chart with dates and volume bars.
11. It is list with active forms (indexes) at the moment and if item is selected I jump to corresponding form/share to see full details of that index/share. I'm not in CZ but in HR and shares as well (of course DAX is German index). This is mistake from Internet but no influence on nothing of importance.
12. This is summary status for all active shares. It is updated automatically when green field (Price) is changed on any listed/active form, active or in background.
13. This is reach text field for comments for specific share index.
14. This is list with different prices and indexes based on yesterday's average price. Selections are based on minimum and maximum prices for previous six days.
As mentioned, other functionality exists but since programming / learnig is in progress there will be time to present them.
C# 4.0 programming using Japanese candlesticks as an example. Calculation, drawing and trading decision management.
Monday, 1 October 2012
Sunday, 30 September 2012
30. Japanese candlestiscks and C# - Two dimensional array
How to calculate RSI (relative strength index)?
Now, application analyses Japanese candlesticks, volumes and RSI to advise trading action.
We'll use 2D array to calculate RSI value. If you are interested in theory of RSI please read this
http://en.wikipedia.org/wiki/Relative_strength_index
and related
http://en.wikipedia.org/wiki/Moving_average_(finance)#Simple_moving_average (SMA chapter)
Under RSI button is code which uses values of these Excel calculation example
http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:relative_strength_index_rsi
It is worth to have a look how it works in Excel, first.
So, now you can easier follow code. 2D table does not use all 8 columns but I did it so to be more easier to follow Excel example. Number of array rows is variable and type of data is double.
Under commented lines is code which is used for daily live trading analysis. Variable noDays is set to 14 as in Excel example. On your form you will need one button (any name) and text field rsItext. Of course, you can use string variable and change code to
string rsIstring== rsI.ToString(); // fill last value to string
and you'll need debugger to see result or you can use line such as this
MessageBox.Show("RSI value", rsIstring)
Also, if you are interested in RSI and how it changes with different number of days (traders use different values according to their trading goals for example 2,..9,14,20) then you can add text filed rsidayS to form and delete in bold line code( // also). With rsidayS filed change RSI will change, also.
noDays = 14; // noDays = Convert.ToInt16(rsidayS.Text);
Great example for debugger usage. :-)
And code:
private void rsI_Click(object sender, EventArgs e)
{ // how to calculate RSI - Relative strength index
int noRows = 44; // number or days to look back
double[,] rsiTable=new double[noRows,9]; // two dimensional array declaration with noRows rows
rsiTable[1, 1] = 43.13; // 1 means today - table filled with test data from
rsiTable[2, 1] = 42.66; // http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:relative_strength_index_rsi
rsiTable[3, 1] = 43.42;
rsiTable[4, 1] = 44.57;
rsiTable[5, 1] = 44.22;
rsiTable[6, 1] = 44.18;
rsiTable[7, 1] = 44.03;
rsiTable[8, 1] = 45.35;
rsiTable[9, 1] = 45.78;
rsiTable[10, 1] = 46.45;
rsiTable[11, 1] = 45.71;
rsiTable[12, 1] = 46.25;
rsiTable[13, 1] = 46.21;
rsiTable[14, 1] = 45.64;
rsiTable[15, 1] = 46.22;
rsiTable[16, 1] = 46.41;
rsiTable[17, 1] = 46.03;
rsiTable[18, 1] = 46.00;
rsiTable[19, 1] = 46.28;
rsiTable[20, 1] = 46.28;
rsiTable[21, 1] = 45.61;
rsiTable[22, 1] = 46.03;
rsiTable[23, 1] = 45.89;
rsiTable[24, 1] = 46.08;
rsiTable[25, 1] = 45.84;
rsiTable[26, 1] = 45.42;
rsiTable[27, 1] = 45.10;
rsiTable[28, 1] = 44.83;
rsiTable[29, 1] = 44.33;
rsiTable[30, 1] = 43.61;
rsiTable[31, 1] = 44.15;
rsiTable[32, 1] = 44.09;
rsiTable[33, 1] = 44.34;
/* for (int m = 0; m < noRows-1; m++) // load from live data table for number of days
{
rsiTable[m + 1, 1] = historyArrayL[m, 2];
} */
int noDays = 0;
int firstDayForAverage = 19;
int lastDayForAverage = 0;
double averageGainSum=0;
double averageLossSum=0;
double gainAverage=0;
double lossAverage=0;
double rS=0;
double rsI=0;
double deltA = 0;
noDays = 14; // noDays = Convert.ToInt16(rsidayS.Text);
if (noDays * 2 + 2 > noRows) { MessageBox.Show("Too many days", "Maximum is 20"); goto kraj; } // we have 44 days to examine
for (int k=gloB.rowSelected+1;k<noRows-1;k++) // calclulate loss
{
deltA=Math.Round(rsiTable[k,1]-rsiTable[k+1,1],2); // close yesterday - close today
if (deltA > 0) { rsiTable[k,3]=deltA; } // delta gain fill column 3
if (deltA < 0) { rsiTable[k, 4] = Math.Abs(deltA); } // delta loss fill column for as positive value
}
firstDayForAverage=firstDayForAverage+gloB.rowSelected; // calculate first average day index
lastDayForAverage=firstDayForAverage+noDays-1; // calculate last average day index
if (lastDayForAverage >= noRows) { MessageBox.Show("Too far in the past", "Maximum is 20"); goto kraj; } // if we are not in range
for (int k = firstDayForAverage; k <= lastDayForAverage; k++)
{
averageGainSum = averageGainSum + rsiTable[k, 3]; averageLossSum = averageLossSum + rsiTable[k, 4]; // for numebr of days
}
gainAverage = Math.Round(averageGainSum / noDays,3); //
lossAverage = Math.Round(averageLossSum / noDays,3); // average of 20th day is calculated
rsiTable[firstDayForAverage,5]=gainAverage; // average gain column 5
rsiTable[firstDayForAverage,6]=lossAverage; // average loss column 6
if (lossAverage > 0) { rS = gainAverage / lossAverage; } else { rS = 100; } // calc. loss avarege - value 100 is by definiton
rsiTable[firstDayForAverage, 7] = Math.Round(rS,2); // RS column 7
if (rsiTable[firstDayForAverage, 6] == 0) { rsiTable[firstDayForAverage, 8] = 100; } // calc. of first RSI value (column 8 of nth day)- value 100 is by definiton
else{rsiTable[firstDayForAverage, 8] = Math.Round(100-(100/(1+rsiTable[firstDayForAverage, 7])) ,2);} // RSI column 8
for (int k = firstDayForAverage -1; k > 0; k--) // calculte other RSI valuse
{
gainAverage = Math.Round((rsiTable[k + 1, 5] * (noDays - 1) + rsiTable[k, 3]) / noDays, 3); // previous and today day
lossAverage = Math.Round((rsiTable[k + 1, 6] * (noDays - 1) + rsiTable[k, 4]) / noDays,3);
rsiTable[k, 5] = gainAverage; // fill column 5
rsiTable[k, 6] = lossAverage;
rS = rsiTable[k, 5] / rsiTable[k, 6];
if (rsiTable[k, 6] == 0) { rsI = 100; } else { rsI = Math.Round(100 - 100 / (1 + rS), 2); rsiTable[k, 8] = rsI; } // calclulate RSI
}
rsItext.Text = rsI.ToString(); // fill last value to field rsIText
kraj: ;
}
Now, application analyses Japanese candlesticks, volumes and RSI to advise trading action.
We'll use 2D array to calculate RSI value. If you are interested in theory of RSI please read this
http://en.wikipedia.org/wiki/Relative_strength_index
and related
http://en.wikipedia.org/wiki/Moving_average_(finance)#Simple_moving_average (SMA chapter)
Under RSI button is code which uses values of these Excel calculation example
http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:relative_strength_index_rsi
It is worth to have a look how it works in Excel, first.
So, now you can easier follow code. 2D table does not use all 8 columns but I did it so to be more easier to follow Excel example. Number of array rows is variable and type of data is double.
Under commented lines is code which is used for daily live trading analysis. Variable noDays is set to 14 as in Excel example. On your form you will need one button (any name) and text field rsItext. Of course, you can use string variable and change code to
string rsIstring== rsI.ToString(); // fill last value to string
and you'll need debugger to see result or you can use line such as this
MessageBox.Show("RSI value", rsIstring)
Also, if you are interested in RSI and how it changes with different number of days (traders use different values according to their trading goals for example 2,..9,14,20) then you can add text filed rsidayS to form and delete in bold line code( // also). With rsidayS filed change RSI will change, also.
noDays = 14; // noDays = Convert.ToInt16(rsidayS.Text);
Great example for debugger usage. :-)
And code:
private void rsI_Click(object sender, EventArgs e)
{ // how to calculate RSI - Relative strength index
int noRows = 44; // number or days to look back
double[,] rsiTable=new double[noRows,9]; // two dimensional array declaration with noRows rows
rsiTable[1, 1] = 43.13; // 1 means today - table filled with test data from
rsiTable[2, 1] = 42.66; // http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:relative_strength_index_rsi
rsiTable[3, 1] = 43.42;
rsiTable[4, 1] = 44.57;
rsiTable[5, 1] = 44.22;
rsiTable[6, 1] = 44.18;
rsiTable[7, 1] = 44.03;
rsiTable[8, 1] = 45.35;
rsiTable[9, 1] = 45.78;
rsiTable[10, 1] = 46.45;
rsiTable[11, 1] = 45.71;
rsiTable[12, 1] = 46.25;
rsiTable[13, 1] = 46.21;
rsiTable[14, 1] = 45.64;
rsiTable[15, 1] = 46.22;
rsiTable[16, 1] = 46.41;
rsiTable[17, 1] = 46.03;
rsiTable[18, 1] = 46.00;
rsiTable[19, 1] = 46.28;
rsiTable[20, 1] = 46.28;
rsiTable[21, 1] = 45.61;
rsiTable[22, 1] = 46.03;
rsiTable[23, 1] = 45.89;
rsiTable[24, 1] = 46.08;
rsiTable[25, 1] = 45.84;
rsiTable[26, 1] = 45.42;
rsiTable[27, 1] = 45.10;
rsiTable[28, 1] = 44.83;
rsiTable[29, 1] = 44.33;
rsiTable[30, 1] = 43.61;
rsiTable[31, 1] = 44.15;
rsiTable[32, 1] = 44.09;
rsiTable[33, 1] = 44.34;
/* for (int m = 0; m < noRows-1; m++) // load from live data table for number of days
{
rsiTable[m + 1, 1] = historyArrayL[m, 2];
} */
int noDays = 0;
int firstDayForAverage = 19;
int lastDayForAverage = 0;
double averageGainSum=0;
double averageLossSum=0;
double gainAverage=0;
double lossAverage=0;
double rS=0;
double rsI=0;
double deltA = 0;
noDays = 14; // noDays = Convert.ToInt16(rsidayS.Text);
if (noDays * 2 + 2 > noRows) { MessageBox.Show("Too many days", "Maximum is 20"); goto kraj; } // we have 44 days to examine
for (int k=gloB.rowSelected+1;k<noRows-1;k++) // calclulate loss
{
deltA=Math.Round(rsiTable[k,1]-rsiTable[k+1,1],2); // close yesterday - close today
if (deltA > 0) { rsiTable[k,3]=deltA; } // delta gain fill column 3
if (deltA < 0) { rsiTable[k, 4] = Math.Abs(deltA); } // delta loss fill column for as positive value
}
firstDayForAverage=firstDayForAverage+gloB.rowSelected; // calculate first average day index
lastDayForAverage=firstDayForAverage+noDays-1; // calculate last average day index
if (lastDayForAverage >= noRows) { MessageBox.Show("Too far in the past", "Maximum is 20"); goto kraj; } // if we are not in range
for (int k = firstDayForAverage; k <= lastDayForAverage; k++)
{
averageGainSum = averageGainSum + rsiTable[k, 3]; averageLossSum = averageLossSum + rsiTable[k, 4]; // for numebr of days
}
gainAverage = Math.Round(averageGainSum / noDays,3); //
lossAverage = Math.Round(averageLossSum / noDays,3); // average of 20th day is calculated
rsiTable[firstDayForAverage,5]=gainAverage; // average gain column 5
rsiTable[firstDayForAverage,6]=lossAverage; // average loss column 6
if (lossAverage > 0) { rS = gainAverage / lossAverage; } else { rS = 100; } // calc. loss avarege - value 100 is by definiton
rsiTable[firstDayForAverage, 7] = Math.Round(rS,2); // RS column 7
if (rsiTable[firstDayForAverage, 6] == 0) { rsiTable[firstDayForAverage, 8] = 100; } // calc. of first RSI value (column 8 of nth day)- value 100 is by definiton
else{rsiTable[firstDayForAverage, 8] = Math.Round(100-(100/(1+rsiTable[firstDayForAverage, 7])) ,2);} // RSI column 8
for (int k = firstDayForAverage -1; k > 0; k--) // calculte other RSI valuse
{
gainAverage = Math.Round((rsiTable[k + 1, 5] * (noDays - 1) + rsiTable[k, 3]) / noDays, 3); // previous and today day
lossAverage = Math.Round((rsiTable[k + 1, 6] * (noDays - 1) + rsiTable[k, 4]) / noDays,3);
rsiTable[k, 5] = gainAverage; // fill column 5
rsiTable[k, 6] = lossAverage;
rS = rsiTable[k, 5] / rsiTable[k, 6];
if (rsiTable[k, 6] == 0) { rsI = 100; } else { rsI = Math.Round(100 - 100 / (1 + rS), 2); rsiTable[k, 8] = rsI; } // calclulate RSI
}
rsItext.Text = rsI.ToString(); // fill last value to field rsIText
kraj: ;
}
Thursday, 20 September 2012
29. Japanese candlestiscks and C# - RichTextBox
How to have comments and use RichTextBox control? I can enter free text in commenT (control name) RichTextBox and save it for later. It means when form is loaded or activated commneT is filled with text saved in disk.
So, how to save data from RichTextBox to file. Under menu item Comments are Save and Load code.
This code is used to save content:
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
if (activeIndice.Text == "") { MessageBox.Show("No indice name", "Saving error - Select indice"); goto end1; } // to save file name I need index name
makeSaveFileName msfN = new makeSaveFileName(gloB.workingPath, activeIndice.Text, true); // fix and make file name and path
string fileNameFull = msfN.indexPathName;
string fileName = msfN.indexName;
fileNameFull = fileNameFull.Replace(fileName, fileName + "Comment"); // full file name is finished
File.WriteAllText(fileNameFull, commenT.Text); // save stream to file
end1: ;
}
This is code which fills RichTextBox from text file:
private void loadToolStripMenuItem_Click(object sender, EventArgs e)
{
if (activeIndice.Text == "") { MessageBox.Show("No indice name", "Loading error - Select indice"); goto end1; } // to read file name I need index name
makeSaveFileName msfN = new makeSaveFileName(gloB.workingPath, activeIndice.Text, true); // fix and make file name and path
string fileNameFull = msfN.indexPathName;
string fileName = msfN.indexName;
fileNameFull = fileNameFull.Replace(fileName, fileName + "Comment"); // full name is finished
if (File.Exists(fileNameFull))
{ commenT.Text = File.ReadAllText(fileNameFull); } // load file to form field
end1: ;
}
These codes could be under buttons, no difference.
Code for class MakeFileSaveName which fixes file name and generates filename and path. from indices's name. You can use absolute string definitions for fileNameFull and FileName and comment class:
internal class makeSaveFileName // construct file name from global path and selected index
{
public makeSaveFileName(string patH, string indeX, Boolean daNe)
{
indeX = indeX.Replace(":", "-");
if (daNe== true) indeX = indeX.Replace("CZ", "HR");
indexPathName = patH + indeX + ".txt"; // make full path,file name and add .txt extension as it is text file
indexName=indeX;
}
public string indexPathName { get; private set; }
public string indexName { get; private set;}
}
And small trick if we want to automate saving process. If we put code under event LostFocus of commenT control text we'll be saved as soon as we leave commenT field. We call the procedure under menu control (in bold).
private void commenT_LostFocus(object sender, EventArgs e)
{ saveToolStripMenuItem.PerformClick(); }
This code is used to save content:
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
if (activeIndice.Text == "") { MessageBox.Show("No indice name", "Saving error - Select indice"); goto end1; } // to save file name I need index name
makeSaveFileName msfN = new makeSaveFileName(gloB.workingPath, activeIndice.Text, true); // fix and make file name and path
string fileNameFull = msfN.indexPathName;
string fileName = msfN.indexName;
fileNameFull = fileNameFull.Replace(fileName, fileName + "Comment"); // full file name is finished
File.WriteAllText(fileNameFull, commenT.Text); // save stream to file
end1: ;
}
This is code which fills RichTextBox from text file:
private void loadToolStripMenuItem_Click(object sender, EventArgs e)
{
if (activeIndice.Text == "") { MessageBox.Show("No indice name", "Loading error - Select indice"); goto end1; } // to read file name I need index name
makeSaveFileName msfN = new makeSaveFileName(gloB.workingPath, activeIndice.Text, true); // fix and make file name and path
string fileNameFull = msfN.indexPathName;
string fileName = msfN.indexName;
fileNameFull = fileNameFull.Replace(fileName, fileName + "Comment"); // full name is finished
if (File.Exists(fileNameFull))
{ commenT.Text = File.ReadAllText(fileNameFull); } // load file to form field
end1: ;
}
These codes could be under buttons, no difference.
Code for class MakeFileSaveName which fixes file name and generates filename and path. from indices's name. You can use absolute string definitions for fileNameFull and FileName and comment class:
internal class makeSaveFileName // construct file name from global path and selected index
{
public makeSaveFileName(string patH, string indeX, Boolean daNe)
{
indeX = indeX.Replace(":", "-");
if (daNe== true) indeX = indeX.Replace("CZ", "HR");
indexPathName = patH + indeX + ".txt"; // make full path,file name and add .txt extension as it is text file
indexName=indeX;
}
public string indexPathName { get; private set; }
public string indexName { get; private set;}
}
And small trick if we want to automate saving process. If we put code under event LostFocus of commenT control text we'll be saved as soon as we leave commenT field. We call the procedure under menu control (in bold).
private void commenT_LostFocus(object sender, EventArgs e)
{ saveToolStripMenuItem.PerformClick(); }
Thursday, 26 July 2012
28. Trader - 26.7. during trading day analyse for Google stock - GOOG:US
As we can see bellow price grow is in progress (as predicted in chapter 27) and confirmed but for tomorrow is pattern set to fall. So, conclusion is not to buy. In left list box we can see what was analyse for today and in the upper right what is at the moment. Still, trading is in progress and conclusion could be changed.
Disclaimer | The
candlestick patterns explained herein are intended
to inform. They come with no warranty of any kind. If you
should choose
this information for your investment decisions, you do so at
your
own risk. Investing can be a very dangerous venture and it
is you
who must assume the entire cost and risk involved in all of
your investment
decisions, should you choose to follow this system or use
this information.
The information contained on the this site is drawn
from sources believed to be factual and reliable, but in no
way does this site represent or guarantee the accuracy or completeness
thereof, nor in providing it, does this site assume any
liability. The information found on the this web site is protected by the copyright laws of the Croatia and may not be copied, or reproduced in any way without the expressed, written consent of the editors. |
27. Trader - Before 26.7. trading analyse for Google stock - GOOG:US
27. Trader - Before 26.7. trading analyse for Google stock - GOOG:US
There are information for other stocks on other forms which can be accessed with their name in list box.
There are information for other stocks on other forms which can be accessed with their name in list box.
Disclaimer | The
candlestick patterns explained herein are intended
to inform. They come with no warranty of any kind. If you
should choose
this information for your investment decisions, you do so at
your
own risk. Investing can be a very dangerous venture and it
is you
who must assume the entire cost and risk involved in all of
your investment
decisions, should you choose to follow this system or use
this information.
The information contained on the this site is drawn
from sources believed to be factual and reliable, but in no
way does this site represent or guarantee the accuracy or completeness
thereof, nor in providing it, does this site assume any
liability. The information found on the this web site is protected by the copyright laws of the Croatia and may not be copied, or reproduced in any way without the expressed, written consent of the editors. |
Friday, 20 July 2012
26. Trader can read/save data to Acess database
I have Access database from previous version so C# will use these Access database data using OleDbConnection.
There are elements needed and code under button "BuySell" (partially hidden behind two lists). Two lists are used to present information in a better way.
private void BuySell_Click(object sender, EventArgs e)
{
string con = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=P:\\Private\\Analizator\\Analizator.mdb"; // define connection
using (OleDbConnection c = new OleDbConnection(con)) // create connection
{
c.Open(); // Open connection
string indNow = activeIndice.Text.Replace("RA:CZ", "-R-A");
string selekt = "select * from zatrgovinu where dionica=" + "'" + indNow + "'" + " and Status='Otvoren' " + " order by redbrzt"; // construct sql string
string listRow = "";
string auX = "";
string buYselL = "";
double suMb = 0;
double suMs = 0;
double dou1;
double dou2;
string str1;
Int16 int1;
int sumShS = 0;
int sumShB = 0;
double statusB = 0;
double statusS = 0;
double proD;
double PricE = Convert.ToDouble(pricE.Text);
double deltA = 0;
using (OleDbDataAdapter a = new OleDbDataAdapter(selekt, c)) // Create new DataAdapter
{
DataTable dt = new DataTable(); // Use DataAdapter to fill DataTable
a.Fill(dt);
listBuy.Items.Clear();
listSell.Items.Clear();
sumShB = 0;
sumShS = 0;
int j = -1;
int m = -1;
for (int i = 0; i < dt.Rows.Count; i++)
{
auX = Convert.ToString(dt.Rows[i][3]);
if (auX == "Prodaja")
{
m++;
buYselL = "Buy < @ ";
dou1 = Convert.ToDouble(dt.Rows[i][9]);
dou2 = Math.Round(dou1 * 0.99, 2);
str1 = Convert.ToString(dt.Rows[i][4]);
int1 = Convert.ToInt16(str1);
listRow = buYselL + dou1.ToString("##0.00") + " Kn x " + str1.PadLeft(3)
+ " shares -1% " + dou2.ToString("##0.00");
proD = dou1 * int1;
suMb = suMb + proD;
sumShB = sumShB+ int1;
listRow = listRow + " = " + proD.ToString("##,##0.00") + " Kn";
deltA = Math.Round(dou1 - PricE, 2);
listRow = listRow + " " + deltA.ToString("##0.00");
deltA = Math.Round(deltA * int1, 2);
listRow = listRow + " " + deltA.ToString("#,##0.00");
if (deltA > 0) { listRow = listRow + "++"; } else { listRow = listRow + "--"; }
listBuy.Items.Add(listRow);
if (deltA > 0) { listBuy.SetSelected(m, true); }
toBuyTotal.Text = suMb.ToString("##,##0.00");
buyShares.Text = Convert.ToString(sumShB);
statusB = PricE * sumShB;
buyStatus.Text = Convert.ToString(Math.Round(suMb - statusB, 2));
toBuyAve.Text=Convert.ToString(Math.Round((suMb/sumShB)*1,2)); // minimal selling price
}
else
{
j++;
buYselL = "Sell > @ ";
dou1 = Convert.ToDouble(dt.Rows[i][9]);
dou2 = Math.Round(dou1 * 1.01, 2);
str1 = Convert.ToString(dt.Rows[i][4]);
int1 = Convert.ToInt16(str1);
listRow = buYselL + dou1.ToString("##0.00") + " Kn x " + str1.PadLeft(3)
+ " shares +1% " + dou2.ToString("##0.00");
proD = dou1 * int1;
suMs = suMs + proD;
sumShS = sumShS + int1;
listRow = listRow + " = " + proD.ToString("##,##0.00") + " Kn";
deltA =Math.Round( PricE - dou1,2);
listRow=listRow+" " + deltA.ToString("##0.00");
deltA = Math.Round(deltA*int1, 2);
listRow=listRow + " " + deltA.ToString("#,##0.00");
if (deltA > 0) { listRow = listRow + "++"; } else { listRow = listRow + "--"; }
listSell.Items.Add(listRow );
if (deltA > 0) { listSell.SetSelected(j,true);}
toSellTotal.Text = suMs.ToString("##,##0.00");
sellShares.Text = Convert.ToString(sumShS);
statusS = PricE * sumShS;
sellStatus.Text = Convert.ToString(Math.Round( statusS-suMs, 2));
toSellAve.Text = Convert.ToString(Math.Round((suMs / sumShS) * 1, 2)); // minimal selling price
}
}
dataSelect.DataSource = dt; // // Render data onto the screen
dataSelect.AutoResizeColumns();
}
}
}
There are elements needed and code under button "BuySell" (partially hidden behind two lists). Two lists are used to present information in a better way.
private void BuySell_Click(object sender, EventArgs e)
{
string con = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=P:\\Private\\Analizator\\Analizator.mdb"; // define connection
using (OleDbConnection c = new OleDbConnection(con)) // create connection
{
c.Open(); // Open connection
string indNow = activeIndice.Text.Replace("RA:CZ", "-R-A");
string selekt = "select * from zatrgovinu where dionica=" + "'" + indNow + "'" + " and Status='Otvoren' " + " order by redbrzt"; // construct sql string
string listRow = "";
string auX = "";
string buYselL = "";
double suMb = 0;
double suMs = 0;
double dou1;
double dou2;
string str1;
Int16 int1;
int sumShS = 0;
int sumShB = 0;
double statusB = 0;
double statusS = 0;
double proD;
double PricE = Convert.ToDouble(pricE.Text);
double deltA = 0;
using (OleDbDataAdapter a = new OleDbDataAdapter(selekt, c)) // Create new DataAdapter
{
DataTable dt = new DataTable(); // Use DataAdapter to fill DataTable
a.Fill(dt);
listBuy.Items.Clear();
listSell.Items.Clear();
sumShB = 0;
sumShS = 0;
int j = -1;
int m = -1;
for (int i = 0; i < dt.Rows.Count; i++)
{
auX = Convert.ToString(dt.Rows[i][3]);
if (auX == "Prodaja")
{
m++;
buYselL = "Buy < @ ";
dou1 = Convert.ToDouble(dt.Rows[i][9]);
dou2 = Math.Round(dou1 * 0.99, 2);
str1 = Convert.ToString(dt.Rows[i][4]);
int1 = Convert.ToInt16(str1);
listRow = buYselL + dou1.ToString("##0.00") + " Kn x " + str1.PadLeft(3)
+ " shares -1% " + dou2.ToString("##0.00");
proD = dou1 * int1;
suMb = suMb + proD;
sumShB = sumShB+ int1;
listRow = listRow + " = " + proD.ToString("##,##0.00") + " Kn";
deltA = Math.Round(dou1 - PricE, 2);
listRow = listRow + " " + deltA.ToString("##0.00");
deltA = Math.Round(deltA * int1, 2);
listRow = listRow + " " + deltA.ToString("#,##0.00");
if (deltA > 0) { listRow = listRow + "++"; } else { listRow = listRow + "--"; }
listBuy.Items.Add(listRow);
if (deltA > 0) { listBuy.SetSelected(m, true); }
toBuyTotal.Text = suMb.ToString("##,##0.00");
buyShares.Text = Convert.ToString(sumShB);
statusB = PricE * sumShB;
buyStatus.Text = Convert.ToString(Math.Round(suMb - statusB, 2));
toBuyAve.Text=Convert.ToString(Math.Round((suMb/sumShB)*1,2)); // minimal selling price
}
else
{
j++;
buYselL = "Sell > @ ";
dou1 = Convert.ToDouble(dt.Rows[i][9]);
dou2 = Math.Round(dou1 * 1.01, 2);
str1 = Convert.ToString(dt.Rows[i][4]);
int1 = Convert.ToInt16(str1);
listRow = buYselL + dou1.ToString("##0.00") + " Kn x " + str1.PadLeft(3)
+ " shares +1% " + dou2.ToString("##0.00");
proD = dou1 * int1;
suMs = suMs + proD;
sumShS = sumShS + int1;
listRow = listRow + " = " + proD.ToString("##,##0.00") + " Kn";
deltA =Math.Round( PricE - dou1,2);
listRow=listRow+" " + deltA.ToString("##0.00");
deltA = Math.Round(deltA*int1, 2);
listRow=listRow + " " + deltA.ToString("#,##0.00");
if (deltA > 0) { listRow = listRow + "++"; } else { listRow = listRow + "--"; }
listSell.Items.Add(listRow );
if (deltA > 0) { listSell.SetSelected(j,true);}
toSellTotal.Text = suMs.ToString("##,##0.00");
sellShares.Text = Convert.ToString(sumShS);
statusS = PricE * sumShS;
sellStatus.Text = Convert.ToString(Math.Round( statusS-suMs, 2));
toSellAve.Text = Convert.ToString(Math.Round((suMs / sumShS) * 1, 2)); // minimal selling price
}
}
dataSelect.DataSource = dt; // // Render data onto the screen
dataSelect.AutoResizeColumns();
}
}
}
25. Trader can fetch data periodically - C# timer
Trader can fetch data from Internet periodically with period defined in seconds. Button with text "timer Stoped" starts remote data fetching. Period is defined in second in field timinG. After button is clicked text is changed to "timer Started". Button Get live is run every 120 seconds (default value). Also, you'll need Timer control from Toolbox.
There is code:
private void timeR_Click(object sender, EventArgs e)
{
if (tGetLive.Enabled == false)
{
tGetLive.Interval = Convert.ToInt32(timinG.Text)*1000; //60000; - 60 sec
tGetLive.Start();
timeR.Text = "Timer started";
}
else
{
tGetLive.Stop();
timeR.Text = "Timer stopped";
}
}
private void tGetLive_Tick(object sender, EventArgs e)
{
getLive.PerformClick();
}
There is code:
private void timeR_Click(object sender, EventArgs e)
{
if (tGetLive.Enabled == false)
{
tGetLive.Interval = Convert.ToInt32(timinG.Text)*1000; //60000; - 60 sec
tGetLive.Start();
timeR.Text = "Timer started";
}
else
{
tGetLive.Stop();
timeR.Text = "Timer stopped";
}
}
private void tGetLive_Tick(object sender, EventArgs e)
{
getLive.PerformClick();
}
Tuesday, 19 June 2012
24. Trader - Drawing was finished
Now, candle drawing is finished and some pattern recognition.
Two signals are in place. Long white day suggests grow, but long tails bring some concerns. Confirmation on new trading day is needed.
And some code:
internal class lLongDay
{
public lLongDay(double[] arr2,double[] arr1,double[] arr0)
{
string mE = " 320-L-Long day "; // name of the pattern
aboutDay aD0 = new aboutDay(arr0);
whatIsTrend wis=new whatIsTrend(arr2,arr1);
if (aD0.dayLong != Globals.yeS) { idenT = Globals.nO; goto kraj; }
if (aD0.dayColor == Globals.whitE && wis.trendIs == Globals.growtH)
{
mE = Globals.nextDay + aD0.dayDate + mE + " " + Globals.whitE + " " + Globals.growtH + " Continues ";
Globals.messageS.Add(mE);
}
if (aD0.dayColor == Globals.whitE && wis.trendIs == Globals.falL)
{
mE = Globals.nextDay + aD0.dayDate + mE + " " + Globals.whitE + " " + Globals.falL + " Reverse ";
Globals.messageS.Add(mE);
}
if (aD0.dayColor == Globals.blacK && wis.trendIs == Globals.falL)
{
mE = Globals.nextDay + aD0.dayDate + mE + " " + Globals.blacK + " " + Globals.falL + " Continues ";
Globals.messageS.Add(mE);
}
if (aD0.dayColor == Globals.blacK && wis.trendIs == Globals.growtH)
{
mE = Globals.nextDay + aD0.dayDate + mE + " " + Globals.blacK + " " + Globals.growtH + " Reverse ";
Globals.messageS.Add(mE);
}
if (aD0.dayColor == Globals.blacK && wis.trendDesc == Globals.almostTheSameS)
{
mE = Globals.nextDay + aD0.dayDate + mE + " " + Globals.blacK + " " + Globals.falL + " Continues ";
Globals.messageS.Add(mE);
mE = mE + " " + Globals.blacK + " " + Globals.falL + Globals.weakDay + " D2.close ~ D1.close";
Globals.messageS.Add(mE);
}
kraj: ;
}
public string idenT { get; private set; }
}
Candle drawing routines:
private void bDrawCandles_Click(object sender, EventArgs e)
{
int fH = shLabels.Height + shLabels.Top; // shLabels is upper limit for graphics
int maxCdH = fH - upperLimit.Top - 2 * MainMenuStrip.Height; // max drawing area height
int maxTop = upperLimit.Top + MainMenuStrip.Height; // top point of drawing area - upper right corner is 0,0
areaHeightMax = maxCdH - MainMenuStrip.Height; // height of drawing area
//areaTopPointMin = maxTop;
tradingLimits tL = new tradingLimits(Globals.rowSelected, Globals.daysToAnalyse, areaHeightMax, Globals.historyArrayGloDou);
double pricePerPix = tL.pricePerPix;
double priceMax = tL.priceMx;
for (int i = 0; Globals.daysToAnalyse - i >= 0; i++)
{
drawCandle dc5 = new drawCandle(Globals.rowSelected, Globals.daysToAnalyse - i, pricePerPix, priceMax, maxTop);
if (Globals.daysToAnalyse - i == Globals.daysToAnalyse)
{
body5.Top = dc5.body5Top;
body5.Height = dc5.body5Height;
tail5.Top = dc5.tail5Top;
tail5.Height = dc5.tail5Height;
cLabel5.Top = shLabels.Top - shLabels.Height;
cLabel5.Text = dc5.cLabel5Text;
if (dc5.body5BackColor == Globals.whitE) { body5.BackColor = Color.White; };
if (dc5.body5BackColor == Globals.blacK) { body5.BackColor = Color.Black; };
}
if (Globals.daysToAnalyse - i == Globals.daysToAnalyse - 1)
{
body4.Top = dc5.body4Top;
body4.Height = dc5.body4Height;
tail4.Top = dc5.tail4Top;
tail4.Height = dc5.tail4Height;
cLabel4.Top = shLabels.Top - shLabels.Height;
cLabel4.Text = dc5.cLabel4Text;
if (dc5.body4BackColor == Globals.whitE) { body4.BackColor = Color.White; };
if (dc5.body4BackColor == Globals.blacK) { body4.BackColor = Color.Black; };
}
if (Globals.daysToAnalyse - i == Globals.daysToAnalyse - 2)
{
body3.Top = dc5.body3Top;
body3.Height = dc5.body3Height;
tail3.Top = dc5.tail3Top;
tail3.Height = dc5.tail3Height;
cLabel3.Top = shLabels.Top - shLabels.Height;
cLabel3.Text = dc5.cLabel3Text;
if (dc5.body3BackColor == Globals.whitE) { body3.BackColor = Color.White; };
if (dc5.body3BackColor == Globals.blacK) { body3.BackColor = Color.Black; };
}
if (Globals.daysToAnalyse - i == Globals.daysToAnalyse - 3)
{
body2.Top = dc5.body2Top;
body2.Height = dc5.body2Height;
tail2.Top = dc5.tail2Top;
tail2.Height = dc5.tail2Height;
cLabel2.Top = shLabels.Top - shLabels.Height;
cLabel2.Text = dc5.cLabel2Text;
if (dc5.body2BackColor == Globals.whitE) { body2.BackColor = Color.White; };
if (dc5.body2BackColor == Globals.blacK) { body2.BackColor = Color.Black; };
}
if (Globals.daysToAnalyse - i == Globals.daysToAnalyse - 4) // yesterday
{
body1.Top = dc5.body1Top;
body1.Height = dc5.body1Height;
tail1.Top = dc5.tail1Top;
tail1.Height = dc5.tail1Height;
cLabel1.Top = shLabels.Top - shLabels.Height;
cLabel1.Text = dc5.cLabel1Text;
if (dc5.body1BackColor == Globals.whitE) { body1.BackColor = Color.White; };
if (dc5.body1BackColor == Globals.blacK) { body1.BackColor = Color.Black; };
cLabel1B.Top = dc5.cLabel1BTop;
cLabel1B.Text = dc5.cLabel1BText;
cLabel1S.Top = dc5.cLabel1STop;
cLabel1S.Text = dc5.cLabel1SText;
}
if (Globals.daysToAnalyse - i == Globals.daysToAnalyse - 5) // today
{
body0.Top = dc5.body0Top;
body0.Height = dc5.body0Height;
tail0.Top = dc5.tail0Top;
tail0.Height = dc5.tail0Height;
cLabel0.Top = shLabels.Top - shLabels.Height;
cLabel0.Text = dc5.cLabel0Text;
if (dc5.body0BackColor == Globals.whitE) { body0.BackColor = Color.White; };
if (dc5.body0BackColor == Globals.blacK) { body0.BackColor = Color.Black; };
cLabel0B.Top = dc5.cLabel0BTop;
cLabel0B.Text = dc5.cLabel0BText;
cLabel0S.Top = dc5.cLabel0STop;
cLabel0S.Text = dc5.cLabel0SText;
}
}
}
private void bInitCandleDrawing_Click(object sender, EventArgs e)
{
// candele no 5
int leftLimit = upperLimit.Left; // left margin for candles
tail5.Width = Globals.tailWidhtDef; //oldest
tail5.Height = Globals.tailHeightDef;
body5.Width = Globals.bodyWidthDef;
body5.Height = Globals.bodyHeightDef;
tail5.Left = body5.Left + (body5.Width / 2 - tail5.Width / 2);
cLabel5.Width = Globals.tailWidhtDef;
cLabel5.Left = body5.Left; // leftLimit + Globals.bodyGap * 0;
// candele no 4
tail4.Width = Globals.tailWidhtDef; //oldest
tail4.Height = Globals.tailHeightDef;
body4.Width = Globals.bodyWidthDef;
body4.Height = Globals.bodyHeightDef;
tail4.Left = body4.Left + (body4.Width / 2 - tail4.Width / 2);
cLabel4.Width = Globals.tailWidhtDef;
cLabel4.Left = body4.Left;// leftLimit + Globals.bodyGap * 1;
// candele no 3
tail3.Width = Globals.tailWidhtDef; //oldest
tail3.Height = Globals.tailHeightDef;
body3.Width = Globals.bodyWidthDef;
body3.Height = Globals.bodyHeightDef;
tail3.Left = body3.Left + (body3.Width / 2 - tail3.Width / 2);
cLabel3.Width = Globals.tailWidhtDef;
cLabel3.Left = body3.Left;// leftLimit + Globals.bodyGap * 1;
// candele no 2
tail2.Width = Globals.tailWidhtDef; //oldest
tail2.Height = Globals.tailHeightDef;
body2.Width = Globals.bodyWidthDef;
body2.Height = Globals.bodyHeightDef;
tail2.Left = body2.Left + (body2.Width / 2 - tail2.Width / 2);
cLabel2.Width = Globals.tailWidhtDef;
cLabel2.Left = body2.Left;// leftLimit + Globals.bodyGap * 1;
// candele no 1
tail1.Width = Globals.tailWidhtDef; //oldest
tail1.Height = Globals.tailHeightDef;
body1.Width = Globals.bodyWidthDef;
body1.Height = Globals.bodyHeightDef;
tail1.Left = body1.Left + (body1.Width / 2 - tail1.Width / 2);
cLabel1.Width = Globals.tailWidhtDef;
cLabel1.Left = body1.Left;
// candele no 0
tail0.Width = Globals.tailWidhtDef; // last
tail0.Height = Globals.tailHeightDef;
body0.Width = Globals.bodyWidthDef;
body0.Height = Globals.bodyHeightDef;
tail0.Left = body0.Left + (body0.Width / 2 - tail0.Width / 2);
cLabel0.Width = Globals.tailWidhtDef;
cLabel0.Left = body0.Left;
}
}
After click on Gridview analyse and drawing are performed:
private void historyGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
Globals.rowSelected = e.RowIndex; // get a row index // row number for form2
bFillAndAnalyze.PerformClick(); // make descriptive analyze
bDrawCandles.PerformClick(); // draw candles
}
Two signals are in place. Long white day suggests grow, but long tails bring some concerns. Confirmation on new trading day is needed.
And some code:
internal class lLongDay
{
public lLongDay(double[] arr2,double[] arr1,double[] arr0)
{
string mE = " 320-L-Long day "; // name of the pattern
aboutDay aD0 = new aboutDay(arr0);
whatIsTrend wis=new whatIsTrend(arr2,arr1);
if (aD0.dayLong != Globals.yeS) { idenT = Globals.nO; goto kraj; }
if (aD0.dayColor == Globals.whitE && wis.trendIs == Globals.growtH)
{
mE = Globals.nextDay + aD0.dayDate + mE + " " + Globals.whitE + " " + Globals.growtH + " Continues ";
Globals.messageS.Add(mE);
}
if (aD0.dayColor == Globals.whitE && wis.trendIs == Globals.falL)
{
mE = Globals.nextDay + aD0.dayDate + mE + " " + Globals.whitE + " " + Globals.falL + " Reverse ";
Globals.messageS.Add(mE);
}
if (aD0.dayColor == Globals.blacK && wis.trendIs == Globals.falL)
{
mE = Globals.nextDay + aD0.dayDate + mE + " " + Globals.blacK + " " + Globals.falL + " Continues ";
Globals.messageS.Add(mE);
}
if (aD0.dayColor == Globals.blacK && wis.trendIs == Globals.growtH)
{
mE = Globals.nextDay + aD0.dayDate + mE + " " + Globals.blacK + " " + Globals.growtH + " Reverse ";
Globals.messageS.Add(mE);
}
if (aD0.dayColor == Globals.blacK && wis.trendDesc == Globals.almostTheSameS)
{
mE = Globals.nextDay + aD0.dayDate + mE + " " + Globals.blacK + " " + Globals.falL + " Continues ";
Globals.messageS.Add(mE);
mE = mE + " " + Globals.blacK + " " + Globals.falL + Globals.weakDay + " D2.close ~ D1.close";
Globals.messageS.Add(mE);
}
kraj: ;
}
public string idenT { get; private set; }
}
Candle drawing routines:
private void bDrawCandles_Click(object sender, EventArgs e)
{
int fH = shLabels.Height + shLabels.Top; // shLabels is upper limit for graphics
int maxCdH = fH - upperLimit.Top - 2 * MainMenuStrip.Height; // max drawing area height
int maxTop = upperLimit.Top + MainMenuStrip.Height; // top point of drawing area - upper right corner is 0,0
areaHeightMax = maxCdH - MainMenuStrip.Height; // height of drawing area
//areaTopPointMin = maxTop;
tradingLimits tL = new tradingLimits(Globals.rowSelected, Globals.daysToAnalyse, areaHeightMax, Globals.historyArrayGloDou);
double pricePerPix = tL.pricePerPix;
double priceMax = tL.priceMx;
for (int i = 0; Globals.daysToAnalyse - i >= 0; i++)
{
drawCandle dc5 = new drawCandle(Globals.rowSelected, Globals.daysToAnalyse - i, pricePerPix, priceMax, maxTop);
if (Globals.daysToAnalyse - i == Globals.daysToAnalyse)
{
body5.Top = dc5.body5Top;
body5.Height = dc5.body5Height;
tail5.Top = dc5.tail5Top;
tail5.Height = dc5.tail5Height;
cLabel5.Top = shLabels.Top - shLabels.Height;
cLabel5.Text = dc5.cLabel5Text;
if (dc5.body5BackColor == Globals.whitE) { body5.BackColor = Color.White; };
if (dc5.body5BackColor == Globals.blacK) { body5.BackColor = Color.Black; };
}
if (Globals.daysToAnalyse - i == Globals.daysToAnalyse - 1)
{
body4.Top = dc5.body4Top;
body4.Height = dc5.body4Height;
tail4.Top = dc5.tail4Top;
tail4.Height = dc5.tail4Height;
cLabel4.Top = shLabels.Top - shLabels.Height;
cLabel4.Text = dc5.cLabel4Text;
if (dc5.body4BackColor == Globals.whitE) { body4.BackColor = Color.White; };
if (dc5.body4BackColor == Globals.blacK) { body4.BackColor = Color.Black; };
}
if (Globals.daysToAnalyse - i == Globals.daysToAnalyse - 2)
{
body3.Top = dc5.body3Top;
body3.Height = dc5.body3Height;
tail3.Top = dc5.tail3Top;
tail3.Height = dc5.tail3Height;
cLabel3.Top = shLabels.Top - shLabels.Height;
cLabel3.Text = dc5.cLabel3Text;
if (dc5.body3BackColor == Globals.whitE) { body3.BackColor = Color.White; };
if (dc5.body3BackColor == Globals.blacK) { body3.BackColor = Color.Black; };
}
if (Globals.daysToAnalyse - i == Globals.daysToAnalyse - 3)
{
body2.Top = dc5.body2Top;
body2.Height = dc5.body2Height;
tail2.Top = dc5.tail2Top;
tail2.Height = dc5.tail2Height;
cLabel2.Top = shLabels.Top - shLabels.Height;
cLabel2.Text = dc5.cLabel2Text;
if (dc5.body2BackColor == Globals.whitE) { body2.BackColor = Color.White; };
if (dc5.body2BackColor == Globals.blacK) { body2.BackColor = Color.Black; };
}
if (Globals.daysToAnalyse - i == Globals.daysToAnalyse - 4) // yesterday
{
body1.Top = dc5.body1Top;
body1.Height = dc5.body1Height;
tail1.Top = dc5.tail1Top;
tail1.Height = dc5.tail1Height;
cLabel1.Top = shLabels.Top - shLabels.Height;
cLabel1.Text = dc5.cLabel1Text;
if (dc5.body1BackColor == Globals.whitE) { body1.BackColor = Color.White; };
if (dc5.body1BackColor == Globals.blacK) { body1.BackColor = Color.Black; };
cLabel1B.Top = dc5.cLabel1BTop;
cLabel1B.Text = dc5.cLabel1BText;
cLabel1S.Top = dc5.cLabel1STop;
cLabel1S.Text = dc5.cLabel1SText;
}
if (Globals.daysToAnalyse - i == Globals.daysToAnalyse - 5) // today
{
body0.Top = dc5.body0Top;
body0.Height = dc5.body0Height;
tail0.Top = dc5.tail0Top;
tail0.Height = dc5.tail0Height;
cLabel0.Top = shLabels.Top - shLabels.Height;
cLabel0.Text = dc5.cLabel0Text;
if (dc5.body0BackColor == Globals.whitE) { body0.BackColor = Color.White; };
if (dc5.body0BackColor == Globals.blacK) { body0.BackColor = Color.Black; };
cLabel0B.Top = dc5.cLabel0BTop;
cLabel0B.Text = dc5.cLabel0BText;
cLabel0S.Top = dc5.cLabel0STop;
cLabel0S.Text = dc5.cLabel0SText;
}
}
}
private void bInitCandleDrawing_Click(object sender, EventArgs e)
{
// candele no 5
int leftLimit = upperLimit.Left; // left margin for candles
tail5.Width = Globals.tailWidhtDef; //oldest
tail5.Height = Globals.tailHeightDef;
body5.Width = Globals.bodyWidthDef;
body5.Height = Globals.bodyHeightDef;
tail5.Left = body5.Left + (body5.Width / 2 - tail5.Width / 2);
cLabel5.Width = Globals.tailWidhtDef;
cLabel5.Left = body5.Left; // leftLimit + Globals.bodyGap * 0;
// candele no 4
tail4.Width = Globals.tailWidhtDef; //oldest
tail4.Height = Globals.tailHeightDef;
body4.Width = Globals.bodyWidthDef;
body4.Height = Globals.bodyHeightDef;
tail4.Left = body4.Left + (body4.Width / 2 - tail4.Width / 2);
cLabel4.Width = Globals.tailWidhtDef;
cLabel4.Left = body4.Left;// leftLimit + Globals.bodyGap * 1;
// candele no 3
tail3.Width = Globals.tailWidhtDef; //oldest
tail3.Height = Globals.tailHeightDef;
body3.Width = Globals.bodyWidthDef;
body3.Height = Globals.bodyHeightDef;
tail3.Left = body3.Left + (body3.Width / 2 - tail3.Width / 2);
cLabel3.Width = Globals.tailWidhtDef;
cLabel3.Left = body3.Left;// leftLimit + Globals.bodyGap * 1;
// candele no 2
tail2.Width = Globals.tailWidhtDef; //oldest
tail2.Height = Globals.tailHeightDef;
body2.Width = Globals.bodyWidthDef;
body2.Height = Globals.bodyHeightDef;
tail2.Left = body2.Left + (body2.Width / 2 - tail2.Width / 2);
cLabel2.Width = Globals.tailWidhtDef;
cLabel2.Left = body2.Left;// leftLimit + Globals.bodyGap * 1;
// candele no 1
tail1.Width = Globals.tailWidhtDef; //oldest
tail1.Height = Globals.tailHeightDef;
body1.Width = Globals.bodyWidthDef;
body1.Height = Globals.bodyHeightDef;
tail1.Left = body1.Left + (body1.Width / 2 - tail1.Width / 2);
cLabel1.Width = Globals.tailWidhtDef;
cLabel1.Left = body1.Left;
// candele no 0
tail0.Width = Globals.tailWidhtDef; // last
tail0.Height = Globals.tailHeightDef;
body0.Width = Globals.bodyWidthDef;
body0.Height = Globals.bodyHeightDef;
tail0.Left = body0.Left + (body0.Width / 2 - tail0.Width / 2);
cLabel0.Width = Globals.tailWidhtDef;
cLabel0.Left = body0.Left;
}
}
After click on Gridview analyse and drawing are performed:
private void historyGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
Globals.rowSelected = e.RowIndex; // get a row index // row number for form2
bFillAndAnalyze.PerformClick(); // make descriptive analyze
bDrawCandles.PerformClick(); // draw candles
}
Wednesday, 30 May 2012
23. Trader - Full project code attached
Lot of code, so far. Here is whole project including item 22.
Sorry, Google does not allow file upload. :-(
Sorry, Google does not allow file upload. :-(
22. Trader - First drawing
Application can draw candles. Six days can be analysed. Gray one is for today and it is be drawn with current trading data. More details will come to graph but this is basic start.
Code needed:
// let's find trading limits
double priceMax=0;
double priceMin=1000000;
int j = 5; // number of days to draw
for (int i = 1; i <= j; i++)
{
if (historyArray[i, 3] > priceMax) priceMax = historyArray[i, 3]; // find max price for j last days
if (historyArray[i, 4] < priceMin) priceMin = historyArray[i, 4]; // find min price for j last days
}
double priceRange = priceMax - priceMin;
double pricePerPix = areaHeightMax / priceRange;
drawCandle(5, pricePerPix, priceMax);
drawCandle(4, pricePerPix, priceMax);
drawCandle(3, pricePerPix, priceMax);
drawCandle(2, pricePerPix, priceMax);
drawCandle(1, pricePerPix, priceMax);
then:
private void drawCandle(int noDay, double vPricePerPix, double vPriceMax)
{
double[] aR=new double[8];
for (int i = 0; i < 8; i++) { aR[i]=historyArray[noDay,i];}
aboutDay ad = new aboutDay(aR); // day 5*********************************
double candleHeiPix = ad.dayBodyLengthNum * vPricePerPix; // candle length in pix
double candleTaiPix = ad.dayTailLengthNum * vPricePerPix; // candle tail in pix
if (noDay == 5)
{
body5.Height = Convert.ToInt16(candleHeiPix);
body5.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBodyBigger) * vPricePerPix);
tail5.Height = Convert.ToInt16(candleTaiPix);
tail5.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBiggest) * vPricePerPix);
tail5.Height = Convert.ToInt16(ad.dayTailLengthNum * vPricePerPix);
if (ad.dayColor == Globals.whitE) body5.BackColor = Color.White;
if (ad.dayColor == Globals.blacK) body5.BackColor = Color.Black;
cLabel5.Text = Convert.ToString( aR[0]).Substring(6,2);
cLabel5.Top = body5.Top + body5.Height / 2;
}
if (noDay == 4)
{
body4.Height = Convert.ToInt16(candleHeiPix);
body4.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBodyBigger) * vPricePerPix);
tail4.Height = Convert.ToInt16(candleTaiPix);
tail4.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBiggest) * vPricePerPix);
tail4.Height = Convert.ToInt16(ad.dayTailLengthNum * vPricePerPix);
if (ad.dayColor == Globals.whitE) body4.BackColor = Color.White;
if (ad.dayColor == Globals.blacK) body4.BackColor = Color.Black;
} if (noDay == 3)
{
body3.Height = Convert.ToInt16(candleHeiPix);
body3.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBodyBigger) * vPricePerPix);
tail3.Height = Convert.ToInt16(candleTaiPix);
tail3.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBiggest) * vPricePerPix);
tail3.Height = Convert.ToInt16(ad.dayTailLengthNum * vPricePerPix);
if (ad.dayColor == Globals.whitE) body3.BackColor = Color.White;
if (ad.dayColor == Globals.blacK) body3.BackColor = Color.Black;
}
if (noDay == 2)
{
body2.Height = Convert.ToInt16(candleHeiPix);
body2.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBodyBigger) * vPricePerPix);
tail2.Height = Convert.ToInt16(candleTaiPix);
tail2.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBiggest) * vPricePerPix);
tail2.Height = Convert.ToInt16(ad.dayTailLengthNum * vPricePerPix);
if (ad.dayColor == Globals.whitE) body2.BackColor = Color.White;
if (ad.dayColor == Globals.blacK) body2.BackColor = Color.Black;
}
if (noDay == 1)
{
body1.Height = Convert.ToInt16(candleHeiPix);
body1.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBodyBigger) * vPricePerPix);
tail1.Height = Convert.ToInt16(candleTaiPix);
tail1.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBiggest) * vPricePerPix);
tail1.Height = Convert.ToInt16(ad.dayTailLengthNum * vPricePerPix);
if (ad.dayColor == Globals.whitE) body1.BackColor = Color.White;
if (ad.dayColor == Globals.blacK) body1.BackColor = Color.Black;
}
if (noDay == 0)
{
body0.Height = Convert.ToInt16(candleHeiPix);
body0.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBodyBigger) * vPricePerPix);
tail0.Height = Convert.ToInt16(candleTaiPix);
tail0.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBiggest) * vPricePerPix);
tail0.Height = Convert.ToInt16(ad.dayTailLengthNum * vPricePerPix);
if (ad.dayColor == Globals.whitE) body0.BackColor = Color.White;
if (ad.dayColor == Globals.blacK) body0.BackColor = Color.Black;
}
}
Code needed:
// let's find trading limits
double priceMax=0;
double priceMin=1000000;
int j = 5; // number of days to draw
for (int i = 1; i <= j; i++)
{
if (historyArray[i, 3] > priceMax) priceMax = historyArray[i, 3]; // find max price for j last days
if (historyArray[i, 4] < priceMin) priceMin = historyArray[i, 4]; // find min price for j last days
}
double priceRange = priceMax - priceMin;
double pricePerPix = areaHeightMax / priceRange;
drawCandle(5, pricePerPix, priceMax);
drawCandle(4, pricePerPix, priceMax);
drawCandle(3, pricePerPix, priceMax);
drawCandle(2, pricePerPix, priceMax);
drawCandle(1, pricePerPix, priceMax);
then:
private void drawCandle(int noDay, double vPricePerPix, double vPriceMax)
{
double[] aR=new double[8];
for (int i = 0; i < 8; i++) { aR[i]=historyArray[noDay,i];}
aboutDay ad = new aboutDay(aR); // day 5*********************************
double candleHeiPix = ad.dayBodyLengthNum * vPricePerPix; // candle length in pix
double candleTaiPix = ad.dayTailLengthNum * vPricePerPix; // candle tail in pix
if (noDay == 5)
{
body5.Height = Convert.ToInt16(candleHeiPix);
body5.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBodyBigger) * vPricePerPix);
tail5.Height = Convert.ToInt16(candleTaiPix);
tail5.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBiggest) * vPricePerPix);
tail5.Height = Convert.ToInt16(ad.dayTailLengthNum * vPricePerPix);
if (ad.dayColor == Globals.whitE) body5.BackColor = Color.White;
if (ad.dayColor == Globals.blacK) body5.BackColor = Color.Black;
cLabel5.Text = Convert.ToString( aR[0]).Substring(6,2);
cLabel5.Top = body5.Top + body5.Height / 2;
}
if (noDay == 4)
{
body4.Height = Convert.ToInt16(candleHeiPix);
body4.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBodyBigger) * vPricePerPix);
tail4.Height = Convert.ToInt16(candleTaiPix);
tail4.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBiggest) * vPricePerPix);
tail4.Height = Convert.ToInt16(ad.dayTailLengthNum * vPricePerPix);
if (ad.dayColor == Globals.whitE) body4.BackColor = Color.White;
if (ad.dayColor == Globals.blacK) body4.BackColor = Color.Black;
} if (noDay == 3)
{
body3.Height = Convert.ToInt16(candleHeiPix);
body3.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBodyBigger) * vPricePerPix);
tail3.Height = Convert.ToInt16(candleTaiPix);
tail3.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBiggest) * vPricePerPix);
tail3.Height = Convert.ToInt16(ad.dayTailLengthNum * vPricePerPix);
if (ad.dayColor == Globals.whitE) body3.BackColor = Color.White;
if (ad.dayColor == Globals.blacK) body3.BackColor = Color.Black;
}
if (noDay == 2)
{
body2.Height = Convert.ToInt16(candleHeiPix);
body2.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBodyBigger) * vPricePerPix);
tail2.Height = Convert.ToInt16(candleTaiPix);
tail2.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBiggest) * vPricePerPix);
tail2.Height = Convert.ToInt16(ad.dayTailLengthNum * vPricePerPix);
if (ad.dayColor == Globals.whitE) body2.BackColor = Color.White;
if (ad.dayColor == Globals.blacK) body2.BackColor = Color.Black;
}
if (noDay == 1)
{
body1.Height = Convert.ToInt16(candleHeiPix);
body1.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBodyBigger) * vPricePerPix);
tail1.Height = Convert.ToInt16(candleTaiPix);
tail1.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBiggest) * vPricePerPix);
tail1.Height = Convert.ToInt16(ad.dayTailLengthNum * vPricePerPix);
if (ad.dayColor == Globals.whitE) body1.BackColor = Color.White;
if (ad.dayColor == Globals.blacK) body1.BackColor = Color.Black;
}
if (noDay == 0)
{
body0.Height = Convert.ToInt16(candleHeiPix);
body0.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBodyBigger) * vPricePerPix);
tail0.Height = Convert.ToInt16(candleTaiPix);
tail0.Top = Convert.ToInt16(areaTopPointMin + (vPriceMax - ad.dayBiggest) * vPricePerPix);
tail0.Height = Convert.ToInt16(ad.dayTailLengthNum * vPricePerPix);
if (ad.dayColor == Globals.whitE) body0.BackColor = Color.White;
if (ad.dayColor == Globals.blacK) body0.BackColor = Color.Black;
}
}
Tuesday, 29 May 2012
21. Trader - New navigation among forms
There is new navigation in place. Now, once activated forms, stayed alive in background and can be invoked by click in Active form list (it is listBox ListActiveForms). Active form can be hidden and still be activated. List item is added with form name after new indice is chosen and form was created. There is checking of only one form per indice can be created.
Code is changed under Menu item "Patterns":
private void patternsToolStripMenuItem_Click(object sender, EventArgs e)
{
FormCollection fC = Application.OpenForms;
string ait = activeIndice.Text;
if (ait == "") { goto kraj; }
int i = Application.OpenForms.Count;
if (i == 1)
{
fPatterns ff = new fPatterns();
ff.Text = ait;
ff.Name = ait;
ff.Show();
goto kraj;
}
foreach (Form f in fC)
{
if (f.Text == ait) {
goto kraj; }
}
{
fPatterns ff = new fPatterns();
ff.Text = ait;
ff.Name = ait;
ff.Show();
}
kraj: ;
listActiveForms.Items.Clear();
foreach (Form f in fC) { listActiveForms.Items.Add(f.Name); }
}
This code is activated on click (selection) on ListBox labeled "Active form list":
private void listActiveForms_SelectedIndexChanged(object sender, EventArgs e)
{
if (listActiveForms.SelectedItem.ToString() == "") { goto kraj; }
string fS = listActiveForms.SelectedItem.ToString(); // Value.ToString(); // form selected
Form form = Application.OpenForms[fS];
form.Visible = true;
form.Activate();
kraj: ;
}
Code under menu item Hide is:
private void hideToolStripMenuItem_Click(object sender, EventArgs e)
{
fPatterns.ActiveForm.Visible=false;
}
Code is changed under Menu item "Patterns":
private void patternsToolStripMenuItem_Click(object sender, EventArgs e)
{
FormCollection fC = Application.OpenForms;
string ait = activeIndice.Text;
if (ait == "") { goto kraj; }
int i = Application.OpenForms.Count;
if (i == 1)
{
fPatterns ff = new fPatterns();
ff.Text = ait;
ff.Name = ait;
ff.Show();
goto kraj;
}
foreach (Form f in fC)
{
if (f.Text == ait) {
goto kraj; }
}
{
fPatterns ff = new fPatterns();
ff.Text = ait;
ff.Name = ait;
ff.Show();
}
kraj: ;
listActiveForms.Items.Clear();
foreach (Form f in fC) { listActiveForms.Items.Add(f.Name); }
}
This code is activated on click (selection) on ListBox labeled "Active form list":
private void listActiveForms_SelectedIndexChanged(object sender, EventArgs e)
{
if (listActiveForms.SelectedItem.ToString() == "") { goto kraj; }
string fS = listActiveForms.SelectedItem.ToString(); // Value.ToString(); // form selected
Form form = Application.OpenForms[fS];
form.Visible = true;
form.Activate();
kraj: ;
}
Code under menu item Hide is:
private void hideToolStripMenuItem_Click(object sender, EventArgs e)
{
fPatterns.ActiveForm.Visible=false;
}
Monday, 28 May 2012
20. Trader - Candles for patterns drawing
As said, we'll use five days to analyze from dataGridView i.e. historyGrid.
So, we need five candles and we'll use new form Patterns for candle drawing. This is default screen before actual drawing. I used Panel control to represent candles and their tails.
Code for Form1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
namespace Stocker
{
// "Copyright © Mladen Zupancic 2012")
public partial class Form1 : Form
{
// DataTable historyTable = new DataTable(); // histroyTable declaration
public Form1()
{
InitializeComponent();
}
public string workingPath = @"P:\Private\Analizator\"; // constant is working directory on disk P
public string[] arrDay0 = new string[8]; // working array - today
public string[] arrDay1 = new string[8]; // working array - yesterday
public string[] arrDay2 = new string[8]; // working array - day before yesterday
public string[] arrDay3 = new string[8]; // working array - 3 days before
public string[] arrDay4 = new string[8]; // working array - 4 days before
public double[] arrDay0d = new double[8]; // working array - today
public double[] arrDay1d = new double[8]; // working array - yesterday
public double[] arrDay2d = new double[8]; // working array - day before yesterday
public double[] arrDay3d = new double[8]; // working array - 3 days before
public double[] arrDay4d = new double[8]; // working array - 4 days before
public double sum2; // auxiliary variable
public double sum1; // auxiliary variable
private void Form1_DoubleClick(object sender, EventArgs e)
{
Environment.Exit(0); // double click on form to end application- just for quick exit when testing
}
private void Form1_Load(object sender, EventArgs e)
{
this.Text = "Stocker2012"; // put title on form bar
this.Width = 1000; // set form width
this.Height = 500; // set form height
this.Top = 0; // set position of form
this.Left = 0;
activeOnly.Checked = true; // by default we would like to work only with active indicies
DataTable historyTable = new DataTable(); // histroyTable declaration
historyTable.Columns.Add(new DataColumn("Date", typeof(string)));
historyTable.Columns.Add(new DataColumn("Open", typeof(string)));
historyTable.Columns.Add(new DataColumn("Close", typeof(string)));
historyTable.Columns.Add(new DataColumn("High", typeof(string)));
historyTable.Columns.Add(new DataColumn("Low", typeof(string)));
historyTable.Columns.Add(new DataColumn("Volume", typeof(string)));
historyTable.Columns.Add(new DataColumn("Avg.Vol.", typeof(string))); // avgDays days Volume
historyTable.Columns.Add(new DataColumn("Avg.Len.", typeof(string))); // avgDays days Length
historyGrid.DataSource = historyTable;
historyGrid.AutoResizeColumns(); // justify columns acording to header
if (Globals.ghistoryArray[0, 0] == null)
{ }
else
{
for (int i = 0; i <= Convert.ToInt16(Globals.ghtDays); i++)
{
historyTable.Rows.Add(Globals.ghistoryArray[i, 0], Globals.ghistoryArray[i, 1], Globals.ghistoryArray[i, 2], Globals.ghistoryArray[i, 3], Globals.ghistoryArray[i, 4],
Globals.ghistoryArray[i, 5], Globals.ghistoryArray[i, 6], Globals.ghistoryArray[i, 7]);
}
historyGrid.DataSource = historyTable;
historyGrid.AutoResizeColumns();
// historyGrid.CurrentCell = historyGrid[0, 1];
}
}
public void getIndicesL()
{
string aPath; // working string to make path
if (activeOnly.Checked == true) // upon a checkbox state
aPath = workingPath + "ActiveIndices.txt"; // if checked - this file
else aPath = workingPath + "NonActiveIndices.txt"; // if not - other file
listIndices.Items.Clear(); // clear listbox before filling
FileStream fs = File.OpenRead(aPath); // prepare filestream
TextReader reader = new StreamReader(fs); // use textreader
while (reader.Peek() > -1) // read while end of file is reached
listIndices.Items.Add(reader.ReadLine()); // add line to listbox
listIndices.Sorted = true;
}
private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Environment.Exit(0); // quit application
}
private void getIndicies_Click(object sender, EventArgs e)
{
getIndicesL();
}
private void listIndices_SelectedIndexChanged(object sender, EventArgs e)
{
if (listIndices.SelectedItem.ToString() == "") { goto kra; }
string part1bloom = "http://www.internet.com/apps/data?pid=webpxta&Securities="; // first part of Internet
string part2bloom = "&TimePeriod=5Y&Outfields=HDATE,PR006-H,PR007-H,PR008-H,PR005-H,PR013-H,&rnd=421"; // second part of internet url histroy string
urlHistory.Text = part1bloom + listIndices.SelectedItem.ToString()+ part2bloom; // construct whole url string
Int16 j = Convert.ToInt16( fillHistoryTableDays.Text); // convert textbox text to int16
fillHistoryT(j); // getting data from local disk // invoke table filling
fillWorkingArrays(0,8); // fill daily working arrays
zeroDay.Text = historyGrid[0, 0].Value.ToString(); // show zero day to analyze
urlHistory.BackColor = Color.White; // restore back color
kra: ;
}
private void getHistory_Click(object sender, EventArgs e)
{
if (urlHistory.Text=="") // is url entered?
{MessageBox.Show("URL field is empty.", "No infomation"); // url is not enetred
goto end1;} // no action. goto end
WebRequest req = WebRequest.Create(urlHistory.Text); // to use WebRequest we need to add "using System.Net;" row
req.Proxy = null; // i do not use proxy
string selectedIndices = listIndices.SelectedItem.ToString(); // get selected indice
selectedIndices=selectedIndices.Replace(":", "-"); // file name can not contain ":"
selectedIndices = workingPath + selectedIndices + ".txt"; // make full path,file name and add .txt extension as it is text file
WebResponse res = req.GetResponse(); // get response from internet
Stream s = res.GetResponseStream(); // make a stream
StreamReader sr = new StreamReader(s);
File.WriteAllText(selectedIndices, sr.ReadToEnd()); // save stream to file
urlHistory.BackColor = Color.LightGreen; // if file was created make BackColor LightGreen
// System.Diagnostics.Process.Start(selectedIndices); // remove comment and result can be seen in text editor
end1: ;
}
private void fillHistoryT(int j)
{
if (listIndices.SelectedItem == null) //formal control if any indice is selected
{
MessageBox.Show("Indice is not selected.", "No infomation"); // no
goto end1; // no action
}
string selectedIndices = listIndices.SelectedItem.ToString(); // get selected indice
selectedIndices = selectedIndices.Replace(":", "-"); // file name can not contain ":"
selectedIndices = workingPath + selectedIndices + ".txt"; // make full path,file name and add .txt extension as it is text file
if (File.Exists(selectedIndices))
{
List<string> fileLines = File.ReadAllLines(selectedIndices).ToList(); // read file to list filelines
int fL = fileLines.Count - 2; // newest date is two rows before end of file
DataTable historyTable = new DataTable(); // histroyTable declaration
historyTable.Columns.Add(new DataColumn("Date", typeof(string)));
historyTable.Columns.Add(new DataColumn("Open", typeof(string)));
historyTable.Columns.Add(new DataColumn("Close", typeof(string)));
historyTable.Columns.Add(new DataColumn("High", typeof(string)));
historyTable.Columns.Add(new DataColumn("Low", typeof(string)));
historyTable.Columns.Add(new DataColumn("Volume", typeof(string)));
historyTable.Columns.Add(new DataColumn("Avg.Vol.", typeof(string))); // avgDays days Volume
historyTable.Columns.Add(new DataColumn("Avg.Len.", typeof(string))); // avgDays days Length
historyGrid.DataSource = historyTable;
historyGrid.AutoResizeColumns(); // justify columns acording to header
for (int i=0; i<=j; i++) // be in loop for number of days asked (j)
{
string row = fileLines[fL-i]; // decrement file line number
string[] words = row.Split('"'); // words are splitted by " delimiter
historyTable.Rows.Add(words[0], words[1].ToString(), words[4].ToString(), words[2].ToString(),
words[3].ToString(), words[5].ToString()); // fill table accordingly to header line
Globals.ghistoryArray[i+1, 0] = words[0];
Globals.ghistoryArray[i + 1, 1] = words[1];
Globals.ghistoryArray[i + 1, 2] = words[2];
Globals.ghistoryArray[i + 1, 3] = words[3];
Globals.ghistoryArray[i + 1, 4] = words[4];
Globals.ghistoryArray[i + 1, 5] = words[5]; // volumen
Globals.ghtDays = Convert.ToString( i);
}
computeAverage(); // compute some auxiliary values
historyTable.Clear(); // prepare to refill with avarage data
historyTable.Rows.Add("0", "0", "0", "0", "0", "0", "0", "0"); // empty row in data table
for (int i = 0; i < 8; i++) { Globals.ghistoryArray[0, i] = "0"; } // zero row in global array
for (int i = 1; i <= Convert.ToInt16(Globals.ghtDays); i++)
{
historyTable.Rows.Add(Globals.ghistoryArray[i, 0], Globals.ghistoryArray[i, 1], Globals.ghistoryArray[i, 2], Globals.ghistoryArray[i, 3], Globals.ghistoryArray[i, 4],
Globals.ghistoryArray[i, 5], Globals.ghistoryArray[i, 6], Globals.ghistoryArray[i, 7]);
}
historyGrid.DataSource = historyTable; // refresh grid content
historyGrid.AutoResizeColumns(); // adjust column width
}
else MessageBox.Show(selectedIndices + " file does not exist","Download needed");
end1: ;
}
private void fillHistoryTable_Click(object sender, EventArgs e)
{
fillHistoryT(Convert.ToInt16(fillHistoryTableDays.Text));
}
private void activeOnly_CheckedChanged(object sender, EventArgs e)
{
if (activeOnly.Checked == true) // make take appropriate to state
activeOnly.Text = "activeOnly"; // if checked
else activeOnly.Text = "all"; // in not checked
getIndicesL();
}
private void fillWorkingArrays(int k, int kC)
{
for (int m = 0; m <kC ; m++) // copy data of kC columns to array
{
if (historyGrid.RowCount <= k + kC-1) { // we need five more rows from selected
MessageBox.Show("No rows","Selection failed" );
goto end1; // cause to exit for loop
}
arrDay0[m] = historyGrid[m, k].Value.ToString(); // copy days in their arrays
arrDay1[m] = historyGrid[m, k+1].Value.ToString();
arrDay2[m] = historyGrid[m, k + 2].Value.ToString();
arrDay3[m] = historyGrid[m, k+3].Value.ToString();
arrDay4[m] = historyGrid[m, k+4].Value.ToString();
calC cc0 = new calC("1", Globals.ghistoryArray[k, m]); // convert string value to double i.e. arrays are declared as dobule
arrDay0d[m] = cc0.producT;
calC cc1 = new calC("1", Globals.ghistoryArray[k + 1, m]);
arrDay1d[m] = cc1.producT;
calC cc2 = new calC("1", Globals.ghistoryArray[k + 2, m]);
arrDay2d[m] = cc2.producT;
calC cc3 = new calC("1", Globals.ghistoryArray[k + 3, m]);
arrDay3d[m] = cc3.producT;
calC cc4 = new calC("1", Globals.ghistoryArray[k + 4, m]);
arrDay4d[m] = cc4.producT;
}
end1: ;
}
private void historyGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
int r = e.RowIndex; // get a row index
zeroDay.Text = historyGrid[0, r].Value.ToString()+ " " + e.RowIndex.ToString() + "."; // put date in zeroDay field
fillWorkingArrays(r,8); // selected raw index will be 0 day -> "today". this is for lates market analyse.
analyseResults.Items.Clear(); // clear listbox
}
private string dayColor( string[] aR)
{
string mE = "Day color : "; // name of routine
string coloR = "Color is not calculated - ERROR" ; // color of the day, by defalt ERROR message which should be changed later
calC cC = new calC(aR[1], aR[2]); // class calC computes two strings and returns result as double
if (cC.diffFmS > 0) { coloR = Globals.blacK; } // if difference first minus second is bigger then zero then it is white day
if (cC.diffFmS < 0) { coloR = Globals.whitE; }
if (cC.diffFmS == 0) { coloR = Globals.nO; }
if (showDetails.Checked) { analyseResults.Items.Add(mE +aR[0] + " -> " + coloR); } // show result if checked
return coloR;
}
private void analyseDay_Click(object sender, EventArgs e)
{ // routine for testing all patterns
mBullishEngulfing(); // bullish pattern
}
private void computeAverage() // compute average volume, day length
{
int i; // auxiliary variable
int j1; // auxiliary variable
string aux; // auxiliary variable
string aux1; // auxiliary variable
int j = historyGrid.RowCount - Globals.avgDays; // last row to calculate
for (int k = 0; k < j; k++) // =<
{
j1 = k; // j1 is working row
sum2 = 0; // make sum zero
sum1 = 0; // make sum zero
for (i = 1; i <= Globals.avgDays && j1 <= j; i++) // make loop avgDays times
{
aux = historyGrid[Globals.volumeColumn, j1 + 1].Value.ToString(); // extract volume
calC cC = new calC(aux,"1"); // class calC computes two strings and returns result as double
sum2 = sum2 + cC.producT; // convert to double
aux = historyGrid[1, j1+1].Value.ToString(); // extract open price
aux1 = historyGrid[2, j1+1].Value.ToString(); // extract close price
calC cC1 = new calC(aux, aux1); // class calC computes two strings and returns result as double
sum1 = sum1 + cC1.abS; // sum
j1++; // increment
}
if ( k +1 < j) // after last loop no need to calculate
{
sum2 = Math.Round((sum2 / Globals.avgDays), 0); // compute averige based on avgDays (3)
sum1 = Math.Round((sum1 / Globals.avgDays), 2); // compute averige based on avgDays (3)
// historyTable.Rows[k][Globals.avgVolumeColumn] = sum2.ToString(); // add to history table
// historyTable.Rows[k][Globals.avgDayLengthColumn] = sum1.ToString(); // add to history table
Globals.ghistoryArray[k + 1, Globals.avgVolumeColumn] = sum2.ToString();
Globals.ghistoryArray[k + 1, Globals.avgDayLengthColumn] = sum1.ToString();
}
}
}
private void mBullishEngulfing() // bullish pattern Medium strong
{
string mE = " 111-M-Bullish Engulfing "; // name of the pattern
string directioN = Globals.growtH; // expected direction
mE = mE + directioN; // make whole name and direction
int sumA = 0; // init score
if (dayColor(arrDay0) == Globals.whitE) { sumA++; } // today is white day
if (dayColor(arrDay1) == Globals.blacK) { sumA++; } // yesterday is black day
biggeRsmaller bgR = new biggeRsmaller(arrDay1[2].ToString(), arrDay0[1].ToString());
if (bgR.bseN == Globals.fBts) { sumA++; } // close yesterday should be lower then open today
biggeRsmaller bgR1 = new biggeRsmaller(arrDay0[2].ToString(), arrDay1[1].ToString());
if (bgR1.bseN == Globals.fBts) { sumA++; } // close yesterday should be lower then open today
int critNo = 4; // number of criteria to meet
if (critNo==sumA) // if met
{ analyseResults.Items.Add(arrDay0[0] + mE); } // fill listbox
}
public void switchTo() {
new fPatterns().Show(); // prepare showing of form named fPatterns
}
private void patternsToolStripMenuItem_Click(object sender, EventArgs e)
{
switchTo(); // to switch to form named fPatterns
this.Hide(); // hide source form
}
private void button1_Click(object sender, EventArgs e)
{
// listIndices.SetSelected(2,true);
aboutDay aD = new aboutDay(arrDay0d);
if (aD.dayColor == Globals.whitE) { }
}
}
}
Code for form Patterns:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Stocker
{
public partial class fPatterns : Form
{
public int maxAreaTopPoint; // working array - today
public int maxAreaHeight;
DataTable historyTable = new DataTable(); // histroyTable declaration
public const int tailHeightDef = 90;
public const int tailWidhtDef = 2;
public const int bodyWidthDef = 20;
public const int bodyHeightDef = 50;
public const int bodyGap = 50;
public fPatterns()
{
InitializeComponent();
}
private void fPatterns_Load(object sender, EventArgs e)
{
this.BackColor = Color.LightGray; //FromName( "red");
historyTable.Columns.Add(new DataColumn("Date", typeof(string)));
historyTable.Columns.Add(new DataColumn("Open", typeof(string)));
historyTable.Columns.Add(new DataColumn("Close", typeof(string)));
historyTable.Columns.Add(new DataColumn("High", typeof(string)));
historyTable.Columns.Add(new DataColumn("Low", typeof(string)));
historyTable.Columns.Add(new DataColumn("Volume", typeof(string)));
historyTable.Columns.Add(new DataColumn("Avg.Vol.", typeof(string))); // avgDays days Volume
historyTable.Columns.Add(new DataColumn("Avg.Len.", typeof(string))); // avgDays days Length
historyTable.Rows.Add("0", "0", "0", "0", "0", "0", "0", "0"); // empty row in data table
for (int i = 0; i < 8; i++) { Globals.ghistoryArray[0, i] = "0"; } // zero row in global array
for (int i = 1; i <= Convert.ToInt16(Globals.ghtDays); i++) // copy data from global array to local historyTable
{
historyTable.Rows.Add(Globals.ghistoryArray[i, 0], Globals.ghistoryArray[i, 1], Globals.ghistoryArray[i, 2],
Globals.ghistoryArray[i, 3], Globals.ghistoryArray[i, 4],
Globals.ghistoryArray[i, 5], Globals.ghistoryArray[i, 6], Globals.ghistoryArray[i, 7]);
}
historyGrid.DataSource = historyTable;
historyGrid.AutoResizeColumns();
// calculate drawing area below historyGrid
int fW = Screen.PrimaryScreen.WorkingArea.Width; // screen max width
int fH = Screen.PrimaryScreen.WorkingArea.Height; // screen max height
int dgH = historyGrid.Height + historyGrid.Top; // historyGrid is above graphics
int maxCdH = fH - dgH - 2 * MainMenuStrip.Height; // max drawing area height
int maxTop = dgH; // top point of drawing area - upper right corner is 0,0
maxAreaHeight = maxCdH;
maxAreaTopPoint = maxTop;
// candeles
tail4.Width = tailWidhtDef; //oldest
tail4.Height = tailHeightDef;
body4.Width = bodyWidthDef;
body4.Height = bodyHeightDef;
body4.Left = historyGrid.Left;
tail4.Left = body4.Left + (body4.Width / 2 - tail4.Width / 2);
tail3.Width = tailWidhtDef;
tail3.Height = tailHeightDef;
body3.Width = bodyWidthDef;
body3.Height = bodyHeightDef;
body3.Left = historyGrid.Left + bodyGap * 1;
tail3.Left = body3.Left + (body3.Width / 2 - tail3.Width / 2);
tail2.Width = tailWidhtDef;
tail2.Height = tailHeightDef;
body2.Width = bodyWidthDef;
body2.Height = bodyHeightDef;
body2.Left = historyGrid.Left + bodyGap * 2;
tail2.Left = body2.Left + (body2.Width / 2 - tail2.Width / 2);
tail1.Width = tailWidhtDef;
tail1.Height = tailHeightDef;
body1.Width = bodyWidthDef;
body1.Height = bodyHeightDef;
body1.Left = historyGrid.Left + bodyGap * 3;
tail1.Left = body1.Left + (body1.Width / 2 - tail1.Width / 2);
tail0.Width = tailWidhtDef; // candle for today
tail0.Height = tailHeightDef;
body0.Width = bodyWidthDef;
body0.Height = bodyHeightDef;
body0.Left = historyGrid.Left+bodyGap*4;
tail0.Left = body0.Left + (body0.Width / 2 - tail0.Width / 2);
}
public void switchTo() { new Form1().Show(); }
private void mainToolStripMenuItem_Click(object sender, EventArgs e)
{
switchTo();
this.Hide();
}
private void button2_Click(object sender, EventArgs e)
{
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Environment.Exit(0); // quit application
}
private void button3_Click_1(object sender, EventArgs e)
{
int a = mainToolStripMenuItem.Height;
body0.BackColor = Color.Black;
body0.Width = Globals.candleW;
body0.Top = 0 + a;
body0.Left = Convert.ToInt16(candleWidth.Text);
}
private void button4_Click(object sender, EventArgs e)
{
}
private void body0_Paint(object sender, PaintEventArgs e)
{
}
}
}
and Globals.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Stocker
{
public static class Globals
{
public const string blacK = "Black"; // black constant
public const string whitE = "White"; // white constant
public const string yeS = "Yes"; // yes constant
public const string nO = "No"; // no constant
public const string fiRst = "First"; // First constant
public const string seCond = "Second"; // Second constant
public const string eqUal = "Equal"; // Equel constant
public const string neaR = "Near"; // NearEquel constant
public const int avgDays = 3; // number of days to count average values
public const int avgVolumeColumn = 6; // average volume column in history table
public const int avgDayLengthColumn = 7; // average day column in history table
public const int volumeColumn = 5; // volume column index
public const int candleW = 20;
public const double almostTheSame = 0.001; // if ratio is less then this, we consider them the same
public const string fEts = "fEts"; // first equal to second
public const string fBts = "fBts"; // first bigger then second
public const string fSts = "fSts"; // first smaller then second
public const string fNts = "fNts"; // first near to second
public const string falL = "FALL"; // fall constant
public const string growtH = "GROW"; // grow constant
public const string commaCountry=yeS; // if your country uses decimal comma change yeS to nO below
static string _strTest1;
public static string strTest1 // global variable
{ get { return _strTest1; } set { _strTest1 = value; } } // access routine for global variable static string _strTest1; static string _strTest1;
static string _ghtDays; // number of days in history table
public static string ghtDays // global variable
{ get { return _ghtDays; } set { _ghtDays = value; } } //access routine for global variable static string _ghtDays;
static string[,] _ghistoryArray=new string[90,8]; // global variable
public static string[,] ghistoryArray
{
get { return _ghistoryArray; } set { _ghistoryArray = value; } } // access routine for global variable
}
class makeHeader
{
public makeHeader()
{
this.succesS=Globals.yeS;
}
public string succesS {get;private set;}
}
class aboutDay
{
public aboutDay(double[] arra)
{
this.dayColor = ""; // Globals.whitE;
this.dayLengthDesc = "";
this.dayLengthNum = 0;
compareTwoNumbers ctn = new compareTwoNumbers(arra[1], arra[2]);
if (ctn.biggeRs==Globals.seCond) this.dayColor = Globals.whitE;
if (ctn.smalleRs==Globals.fiRst) this.dayColor = Globals.blacK;
if (ctn.equalS==Globals.yeS | ctn.equalFNearS==Globals.yeS) this.dayColor = Globals.nO;
}
public string dayColor { get; private set; }
public string dayLengthDesc { get; private set; }
public double dayLengthNum { get; private set; }
}
class stringToDouble
{
public stringToDouble(string valuE) // coverts string to double having in mind decimal sign
{
double mla; // init variable
mla = Convert.ToDouble(valuE); // convert with default function
if (valuE.Contains(".")) // check for decimal point
{
if (Globals.commaCountry == Globals.yeS) // check if we use decimal comma
{ mla = Convert.ToDouble(valuE.Replace(".", ",")); } // but if you use decimal comma we need fix
}
else
{ mla = Convert.ToDouble(valuE); } // convert string to double
this.doublE = mla; // return values
}
public double doublE { get; private set; }
}
class calC
{
public calC(string firsT, string seconD) // calC class - input are two numbers as string - string to double for countries
{ // using decimal comma
double mlaF; // auxiliary number for the first day
double mlaS; // auxiliary number for the second day
if (firsT == null | seconD == null) goto kraj;
if (firsT.Contains(".")) // if string contains point
{
if (Globals.commaCountry == Globals.yeS) // if country uses decimal comma
{ mlaF = Convert.ToDouble(firsT.Replace(".", ",")); } // and if you use decimal comma we need fix
}
else
{ mlaF = Convert.ToDouble(firsT); } // convert string to doubleif (firsT.Contains("."))
if (seconD.Contains(".")) // the same as above for first number
{
if (Globals.commaCountry == Globals.yeS)
{ mlaS = Convert.ToDouble(seconD.Replace(".", ",")); } // but if you use decimal comma we need fix
}
else
{ mlaS = Convert.ToDouble(seconD); } // convert string to doubleif (firsT.Contains("."))
double mlaPro = Math.Round( mlaF * mlaS,2); // product rounded to two decimal places
double mlaDiffFirstMinSecond = Math.Round(mlaF - mlaS,2); // difference first minus second rounded to two decimal places
double mlaSum = Math.Round(mlaF + mlaS,2); // first plus second rounded to two decimal places
double mlaabS = Math.Round (Math.Abs(mlaF - mlaS),2) ; // difference first minus second rounded to two decimal places
biggeRsmaller bgR = new biggeRsmaller(firsT, seconD);
double c = Math.Abs((mlaF - mlaS) / bgR.biggeR);
this.producT = mlaPro; // define properties
this.diffFmS = mlaDiffFirstMinSecond;
this.sumFS = mlaSum;
this.abS = mlaabS;
kraj: ;
}
public double producT { get; private set; }
public double diffFmS { get; private set; }
public double sumFS { get; private set; }
public double abS { get; private set; }
}
class biggeRsmaller // compares two numbers as string
{
public biggeRsmaller(string f, string s) // (f)irst and (s)econd
{
stringToDouble ca = new stringToDouble(f); // convert string to number having in mind decimal comma
double a = ca.doublE; // a is first result
stringToDouble cb = new stringToDouble(s);
double b = cb.doublE; // b is second result
double sM = 0; // init variable
if (a < b) { sM = b; this.biggeR = b; this.biggeRs = s; this.smalleR = a; this.smalleRs = f; this.bseN = Globals.fSts; }
if (a > b) { sM = a; this.smalleR = b; this.smalleRs = s; this.biggeR = a; this.biggeRs = f; this.bseN = Globals.fBts; }
if (this.biggeR == 0) { this.biggeR = a; }
double c = Math.Abs((a - b) / this.biggeR);
if (c <= Globals.almostTheSame) { this.equalNearS = Globals.yeS; } // first near to second i.e. almost the same
if (a == b) { sM = b; this.equalS = Globals.yeS; }
}
public double biggeR { get; private set; }
public double smalleR { get; private set; }
public string biggeRs { get; private set; }
public string smalleRs { get; private set; }
public string equalS { get; private set; }
public string equalNearS { get; private set; }
public string bseN { get; private set; }
}
class compareTwoNumbers // compares two numbers as string
{
public compareTwoNumbers(double f, double s) // (f)irst and (s)econd
{
double a = f;
double b = s;
if (a < b) { this.biggeR = b; this.biggeRs = Globals.seCond; this.smalleR = a; this.smalleRs = Globals.fiRst; this.equalFNearS = Globals.nO; this.equalS = Globals.nO; }
if (a > b) { this.smalleR = b; this.smalleRs = Globals.seCond; this.biggeR = a; this.biggeRs = Globals.fiRst; this.equalFNearS = Globals.nO; this.equalS = Globals.nO; }
// if (this.biggeR == 0) { this.biggeR = a; }
double c = Math.Abs((a - b) / this.biggeR);
if (c <= Globals.almostTheSame) { this.equalFNearS = Globals.yeS; this.equalS = Globals.nO; } // first near to second i.e. almost the same
if (a == b) { this.equalS = Globals.nO; this.equalFNearS = Globals.yeS; this.biggeRs = Globals.nO; this.smalleRs = Globals.nO; }
}
public double biggeR { get; private set; }
public double smalleR { get; private set; }
public string biggeRs { get; private set; }
public string smalleRs { get; private set; }
public string equalS { get; private set; }
public string equalFNearS { get; private set; }
}
}
So, we need five candles and we'll use new form Patterns for candle drawing. This is default screen before actual drawing. I used Panel control to represent candles and their tails.
Code for Form1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
namespace Stocker
{
// "Copyright © Mladen Zupancic 2012")
public partial class Form1 : Form
{
// DataTable historyTable = new DataTable(); // histroyTable declaration
public Form1()
{
InitializeComponent();
}
public string workingPath = @"P:\Private\Analizator\"; // constant is working directory on disk P
public string[] arrDay0 = new string[8]; // working array - today
public string[] arrDay1 = new string[8]; // working array - yesterday
public string[] arrDay2 = new string[8]; // working array - day before yesterday
public string[] arrDay3 = new string[8]; // working array - 3 days before
public string[] arrDay4 = new string[8]; // working array - 4 days before
public double[] arrDay0d = new double[8]; // working array - today
public double[] arrDay1d = new double[8]; // working array - yesterday
public double[] arrDay2d = new double[8]; // working array - day before yesterday
public double[] arrDay3d = new double[8]; // working array - 3 days before
public double[] arrDay4d = new double[8]; // working array - 4 days before
public double sum2; // auxiliary variable
public double sum1; // auxiliary variable
private void Form1_DoubleClick(object sender, EventArgs e)
{
Environment.Exit(0); // double click on form to end application- just for quick exit when testing
}
private void Form1_Load(object sender, EventArgs e)
{
this.Text = "Stocker2012"; // put title on form bar
this.Width = 1000; // set form width
this.Height = 500; // set form height
this.Top = 0; // set position of form
this.Left = 0;
activeOnly.Checked = true; // by default we would like to work only with active indicies
DataTable historyTable = new DataTable(); // histroyTable declaration
historyTable.Columns.Add(new DataColumn("Date", typeof(string)));
historyTable.Columns.Add(new DataColumn("Open", typeof(string)));
historyTable.Columns.Add(new DataColumn("Close", typeof(string)));
historyTable.Columns.Add(new DataColumn("High", typeof(string)));
historyTable.Columns.Add(new DataColumn("Low", typeof(string)));
historyTable.Columns.Add(new DataColumn("Volume", typeof(string)));
historyTable.Columns.Add(new DataColumn("Avg.Vol.", typeof(string))); // avgDays days Volume
historyTable.Columns.Add(new DataColumn("Avg.Len.", typeof(string))); // avgDays days Length
historyGrid.DataSource = historyTable;
historyGrid.AutoResizeColumns(); // justify columns acording to header
if (Globals.ghistoryArray[0, 0] == null)
{ }
else
{
for (int i = 0; i <= Convert.ToInt16(Globals.ghtDays); i++)
{
historyTable.Rows.Add(Globals.ghistoryArray[i, 0], Globals.ghistoryArray[i, 1], Globals.ghistoryArray[i, 2], Globals.ghistoryArray[i, 3], Globals.ghistoryArray[i, 4],
Globals.ghistoryArray[i, 5], Globals.ghistoryArray[i, 6], Globals.ghistoryArray[i, 7]);
}
historyGrid.DataSource = historyTable;
historyGrid.AutoResizeColumns();
// historyGrid.CurrentCell = historyGrid[0, 1];
}
}
public void getIndicesL()
{
string aPath; // working string to make path
if (activeOnly.Checked == true) // upon a checkbox state
aPath = workingPath + "ActiveIndices.txt"; // if checked - this file
else aPath = workingPath + "NonActiveIndices.txt"; // if not - other file
listIndices.Items.Clear(); // clear listbox before filling
FileStream fs = File.OpenRead(aPath); // prepare filestream
TextReader reader = new StreamReader(fs); // use textreader
while (reader.Peek() > -1) // read while end of file is reached
listIndices.Items.Add(reader.ReadLine()); // add line to listbox
listIndices.Sorted = true;
}
private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Environment.Exit(0); // quit application
}
private void getIndicies_Click(object sender, EventArgs e)
{
getIndicesL();
}
private void listIndices_SelectedIndexChanged(object sender, EventArgs e)
{
if (listIndices.SelectedItem.ToString() == "") { goto kra; }
string part1bloom = "http://www.internet.com/apps/data?pid=webpxta&Securities="; // first part of Internet
string part2bloom = "&TimePeriod=5Y&Outfields=HDATE,PR006-H,PR007-H,PR008-H,PR005-H,PR013-H,&rnd=421"; // second part of internet url histroy string
urlHistory.Text = part1bloom + listIndices.SelectedItem.ToString()+ part2bloom; // construct whole url string
Int16 j = Convert.ToInt16( fillHistoryTableDays.Text); // convert textbox text to int16
fillHistoryT(j); // getting data from local disk // invoke table filling
fillWorkingArrays(0,8); // fill daily working arrays
zeroDay.Text = historyGrid[0, 0].Value.ToString(); // show zero day to analyze
urlHistory.BackColor = Color.White; // restore back color
kra: ;
}
private void getHistory_Click(object sender, EventArgs e)
{
if (urlHistory.Text=="") // is url entered?
{MessageBox.Show("URL field is empty.", "No infomation"); // url is not enetred
goto end1;} // no action. goto end
WebRequest req = WebRequest.Create(urlHistory.Text); // to use WebRequest we need to add "using System.Net;" row
req.Proxy = null; // i do not use proxy
string selectedIndices = listIndices.SelectedItem.ToString(); // get selected indice
selectedIndices=selectedIndices.Replace(":", "-"); // file name can not contain ":"
selectedIndices = workingPath + selectedIndices + ".txt"; // make full path,file name and add .txt extension as it is text file
WebResponse res = req.GetResponse(); // get response from internet
Stream s = res.GetResponseStream(); // make a stream
StreamReader sr = new StreamReader(s);
File.WriteAllText(selectedIndices, sr.ReadToEnd()); // save stream to file
urlHistory.BackColor = Color.LightGreen; // if file was created make BackColor LightGreen
// System.Diagnostics.Process.Start(selectedIndices); // remove comment and result can be seen in text editor
end1: ;
}
private void fillHistoryT(int j)
{
if (listIndices.SelectedItem == null) //formal control if any indice is selected
{
MessageBox.Show("Indice is not selected.", "No infomation"); // no
goto end1; // no action
}
string selectedIndices = listIndices.SelectedItem.ToString(); // get selected indice
selectedIndices = selectedIndices.Replace(":", "-"); // file name can not contain ":"
selectedIndices = workingPath + selectedIndices + ".txt"; // make full path,file name and add .txt extension as it is text file
if (File.Exists(selectedIndices))
{
List<string> fileLines = File.ReadAllLines(selectedIndices).ToList(); // read file to list filelines
int fL = fileLines.Count - 2; // newest date is two rows before end of file
DataTable historyTable = new DataTable(); // histroyTable declaration
historyTable.Columns.Add(new DataColumn("Date", typeof(string)));
historyTable.Columns.Add(new DataColumn("Open", typeof(string)));
historyTable.Columns.Add(new DataColumn("Close", typeof(string)));
historyTable.Columns.Add(new DataColumn("High", typeof(string)));
historyTable.Columns.Add(new DataColumn("Low", typeof(string)));
historyTable.Columns.Add(new DataColumn("Volume", typeof(string)));
historyTable.Columns.Add(new DataColumn("Avg.Vol.", typeof(string))); // avgDays days Volume
historyTable.Columns.Add(new DataColumn("Avg.Len.", typeof(string))); // avgDays days Length
historyGrid.DataSource = historyTable;
historyGrid.AutoResizeColumns(); // justify columns acording to header
for (int i=0; i<=j; i++) // be in loop for number of days asked (j)
{
string row = fileLines[fL-i]; // decrement file line number
string[] words = row.Split('"'); // words are splitted by " delimiter
historyTable.Rows.Add(words[0], words[1].ToString(), words[4].ToString(), words[2].ToString(),
words[3].ToString(), words[5].ToString()); // fill table accordingly to header line
Globals.ghistoryArray[i+1, 0] = words[0];
Globals.ghistoryArray[i + 1, 1] = words[1];
Globals.ghistoryArray[i + 1, 2] = words[2];
Globals.ghistoryArray[i + 1, 3] = words[3];
Globals.ghistoryArray[i + 1, 4] = words[4];
Globals.ghistoryArray[i + 1, 5] = words[5]; // volumen
Globals.ghtDays = Convert.ToString( i);
}
computeAverage(); // compute some auxiliary values
historyTable.Clear(); // prepare to refill with avarage data
historyTable.Rows.Add("0", "0", "0", "0", "0", "0", "0", "0"); // empty row in data table
for (int i = 0; i < 8; i++) { Globals.ghistoryArray[0, i] = "0"; } // zero row in global array
for (int i = 1; i <= Convert.ToInt16(Globals.ghtDays); i++)
{
historyTable.Rows.Add(Globals.ghistoryArray[i, 0], Globals.ghistoryArray[i, 1], Globals.ghistoryArray[i, 2], Globals.ghistoryArray[i, 3], Globals.ghistoryArray[i, 4],
Globals.ghistoryArray[i, 5], Globals.ghistoryArray[i, 6], Globals.ghistoryArray[i, 7]);
}
historyGrid.DataSource = historyTable; // refresh grid content
historyGrid.AutoResizeColumns(); // adjust column width
}
else MessageBox.Show(selectedIndices + " file does not exist","Download needed");
end1: ;
}
private void fillHistoryTable_Click(object sender, EventArgs e)
{
fillHistoryT(Convert.ToInt16(fillHistoryTableDays.Text));
}
private void activeOnly_CheckedChanged(object sender, EventArgs e)
{
if (activeOnly.Checked == true) // make take appropriate to state
activeOnly.Text = "activeOnly"; // if checked
else activeOnly.Text = "all"; // in not checked
getIndicesL();
}
private void fillWorkingArrays(int k, int kC)
{
for (int m = 0; m <kC ; m++) // copy data of kC columns to array
{
if (historyGrid.RowCount <= k + kC-1) { // we need five more rows from selected
MessageBox.Show("No rows","Selection failed" );
goto end1; // cause to exit for loop
}
arrDay0[m] = historyGrid[m, k].Value.ToString(); // copy days in their arrays
arrDay1[m] = historyGrid[m, k+1].Value.ToString();
arrDay2[m] = historyGrid[m, k + 2].Value.ToString();
arrDay3[m] = historyGrid[m, k+3].Value.ToString();
arrDay4[m] = historyGrid[m, k+4].Value.ToString();
calC cc0 = new calC("1", Globals.ghistoryArray[k, m]); // convert string value to double i.e. arrays are declared as dobule
arrDay0d[m] = cc0.producT;
calC cc1 = new calC("1", Globals.ghistoryArray[k + 1, m]);
arrDay1d[m] = cc1.producT;
calC cc2 = new calC("1", Globals.ghistoryArray[k + 2, m]);
arrDay2d[m] = cc2.producT;
calC cc3 = new calC("1", Globals.ghistoryArray[k + 3, m]);
arrDay3d[m] = cc3.producT;
calC cc4 = new calC("1", Globals.ghistoryArray[k + 4, m]);
arrDay4d[m] = cc4.producT;
}
end1: ;
}
private void historyGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
int r = e.RowIndex; // get a row index
zeroDay.Text = historyGrid[0, r].Value.ToString()+ " " + e.RowIndex.ToString() + "."; // put date in zeroDay field
fillWorkingArrays(r,8); // selected raw index will be 0 day -> "today". this is for lates market analyse.
analyseResults.Items.Clear(); // clear listbox
}
private string dayColor( string[] aR)
{
string mE = "Day color : "; // name of routine
string coloR = "Color is not calculated - ERROR" ; // color of the day, by defalt ERROR message which should be changed later
calC cC = new calC(aR[1], aR[2]); // class calC computes two strings and returns result as double
if (cC.diffFmS > 0) { coloR = Globals.blacK; } // if difference first minus second is bigger then zero then it is white day
if (cC.diffFmS < 0) { coloR = Globals.whitE; }
if (cC.diffFmS == 0) { coloR = Globals.nO; }
if (showDetails.Checked) { analyseResults.Items.Add(mE +aR[0] + " -> " + coloR); } // show result if checked
return coloR;
}
private void analyseDay_Click(object sender, EventArgs e)
{ // routine for testing all patterns
mBullishEngulfing(); // bullish pattern
}
private void computeAverage() // compute average volume, day length
{
int i; // auxiliary variable
int j1; // auxiliary variable
string aux; // auxiliary variable
string aux1; // auxiliary variable
int j = historyGrid.RowCount - Globals.avgDays; // last row to calculate
for (int k = 0; k < j; k++) // =<
{
j1 = k; // j1 is working row
sum2 = 0; // make sum zero
sum1 = 0; // make sum zero
for (i = 1; i <= Globals.avgDays && j1 <= j; i++) // make loop avgDays times
{
aux = historyGrid[Globals.volumeColumn, j1 + 1].Value.ToString(); // extract volume
calC cC = new calC(aux,"1"); // class calC computes two strings and returns result as double
sum2 = sum2 + cC.producT; // convert to double
aux = historyGrid[1, j1+1].Value.ToString(); // extract open price
aux1 = historyGrid[2, j1+1].Value.ToString(); // extract close price
calC cC1 = new calC(aux, aux1); // class calC computes two strings and returns result as double
sum1 = sum1 + cC1.abS; // sum
j1++; // increment
}
if ( k +1 < j) // after last loop no need to calculate
{
sum2 = Math.Round((sum2 / Globals.avgDays), 0); // compute averige based on avgDays (3)
sum1 = Math.Round((sum1 / Globals.avgDays), 2); // compute averige based on avgDays (3)
// historyTable.Rows[k][Globals.avgVolumeColumn] = sum2.ToString(); // add to history table
// historyTable.Rows[k][Globals.avgDayLengthColumn] = sum1.ToString(); // add to history table
Globals.ghistoryArray[k + 1, Globals.avgVolumeColumn] = sum2.ToString();
Globals.ghistoryArray[k + 1, Globals.avgDayLengthColumn] = sum1.ToString();
}
}
}
private void mBullishEngulfing() // bullish pattern Medium strong
{
string mE = " 111-M-Bullish Engulfing "; // name of the pattern
string directioN = Globals.growtH; // expected direction
mE = mE + directioN; // make whole name and direction
int sumA = 0; // init score
if (dayColor(arrDay0) == Globals.whitE) { sumA++; } // today is white day
if (dayColor(arrDay1) == Globals.blacK) { sumA++; } // yesterday is black day
biggeRsmaller bgR = new biggeRsmaller(arrDay1[2].ToString(), arrDay0[1].ToString());
if (bgR.bseN == Globals.fBts) { sumA++; } // close yesterday should be lower then open today
biggeRsmaller bgR1 = new biggeRsmaller(arrDay0[2].ToString(), arrDay1[1].ToString());
if (bgR1.bseN == Globals.fBts) { sumA++; } // close yesterday should be lower then open today
int critNo = 4; // number of criteria to meet
if (critNo==sumA) // if met
{ analyseResults.Items.Add(arrDay0[0] + mE); } // fill listbox
}
public void switchTo() {
new fPatterns().Show(); // prepare showing of form named fPatterns
}
private void patternsToolStripMenuItem_Click(object sender, EventArgs e)
{
switchTo(); // to switch to form named fPatterns
this.Hide(); // hide source form
}
private void button1_Click(object sender, EventArgs e)
{
// listIndices.SetSelected(2,true);
aboutDay aD = new aboutDay(arrDay0d);
if (aD.dayColor == Globals.whitE) { }
}
}
}
Code for form Patterns:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Stocker
{
public partial class fPatterns : Form
{
public int maxAreaTopPoint; // working array - today
public int maxAreaHeight;
DataTable historyTable = new DataTable(); // histroyTable declaration
public const int tailHeightDef = 90;
public const int tailWidhtDef = 2;
public const int bodyWidthDef = 20;
public const int bodyHeightDef = 50;
public const int bodyGap = 50;
public fPatterns()
{
InitializeComponent();
}
private void fPatterns_Load(object sender, EventArgs e)
{
this.BackColor = Color.LightGray; //FromName( "red");
historyTable.Columns.Add(new DataColumn("Date", typeof(string)));
historyTable.Columns.Add(new DataColumn("Open", typeof(string)));
historyTable.Columns.Add(new DataColumn("Close", typeof(string)));
historyTable.Columns.Add(new DataColumn("High", typeof(string)));
historyTable.Columns.Add(new DataColumn("Low", typeof(string)));
historyTable.Columns.Add(new DataColumn("Volume", typeof(string)));
historyTable.Columns.Add(new DataColumn("Avg.Vol.", typeof(string))); // avgDays days Volume
historyTable.Columns.Add(new DataColumn("Avg.Len.", typeof(string))); // avgDays days Length
historyTable.Rows.Add("0", "0", "0", "0", "0", "0", "0", "0"); // empty row in data table
for (int i = 0; i < 8; i++) { Globals.ghistoryArray[0, i] = "0"; } // zero row in global array
for (int i = 1; i <= Convert.ToInt16(Globals.ghtDays); i++) // copy data from global array to local historyTable
{
historyTable.Rows.Add(Globals.ghistoryArray[i, 0], Globals.ghistoryArray[i, 1], Globals.ghistoryArray[i, 2],
Globals.ghistoryArray[i, 3], Globals.ghistoryArray[i, 4],
Globals.ghistoryArray[i, 5], Globals.ghistoryArray[i, 6], Globals.ghistoryArray[i, 7]);
}
historyGrid.DataSource = historyTable;
historyGrid.AutoResizeColumns();
// calculate drawing area below historyGrid
int fW = Screen.PrimaryScreen.WorkingArea.Width; // screen max width
int fH = Screen.PrimaryScreen.WorkingArea.Height; // screen max height
int dgH = historyGrid.Height + historyGrid.Top; // historyGrid is above graphics
int maxCdH = fH - dgH - 2 * MainMenuStrip.Height; // max drawing area height
int maxTop = dgH; // top point of drawing area - upper right corner is 0,0
maxAreaHeight = maxCdH;
maxAreaTopPoint = maxTop;
// candeles
tail4.Width = tailWidhtDef; //oldest
tail4.Height = tailHeightDef;
body4.Width = bodyWidthDef;
body4.Height = bodyHeightDef;
body4.Left = historyGrid.Left;
tail4.Left = body4.Left + (body4.Width / 2 - tail4.Width / 2);
tail3.Width = tailWidhtDef;
tail3.Height = tailHeightDef;
body3.Width = bodyWidthDef;
body3.Height = bodyHeightDef;
body3.Left = historyGrid.Left + bodyGap * 1;
tail3.Left = body3.Left + (body3.Width / 2 - tail3.Width / 2);
tail2.Width = tailWidhtDef;
tail2.Height = tailHeightDef;
body2.Width = bodyWidthDef;
body2.Height = bodyHeightDef;
body2.Left = historyGrid.Left + bodyGap * 2;
tail2.Left = body2.Left + (body2.Width / 2 - tail2.Width / 2);
tail1.Width = tailWidhtDef;
tail1.Height = tailHeightDef;
body1.Width = bodyWidthDef;
body1.Height = bodyHeightDef;
body1.Left = historyGrid.Left + bodyGap * 3;
tail1.Left = body1.Left + (body1.Width / 2 - tail1.Width / 2);
tail0.Width = tailWidhtDef; // candle for today
tail0.Height = tailHeightDef;
body0.Width = bodyWidthDef;
body0.Height = bodyHeightDef;
body0.Left = historyGrid.Left+bodyGap*4;
tail0.Left = body0.Left + (body0.Width / 2 - tail0.Width / 2);
}
public void switchTo() { new Form1().Show(); }
private void mainToolStripMenuItem_Click(object sender, EventArgs e)
{
switchTo();
this.Hide();
}
private void button2_Click(object sender, EventArgs e)
{
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Environment.Exit(0); // quit application
}
private void button3_Click_1(object sender, EventArgs e)
{
int a = mainToolStripMenuItem.Height;
body0.BackColor = Color.Black;
body0.Width = Globals.candleW;
body0.Top = 0 + a;
body0.Left = Convert.ToInt16(candleWidth.Text);
}
private void button4_Click(object sender, EventArgs e)
{
}
private void body0_Paint(object sender, PaintEventArgs e)
{
}
}
}
and Globals.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Stocker
{
public static class Globals
{
public const string blacK = "Black"; // black constant
public const string whitE = "White"; // white constant
public const string yeS = "Yes"; // yes constant
public const string nO = "No"; // no constant
public const string fiRst = "First"; // First constant
public const string seCond = "Second"; // Second constant
public const string eqUal = "Equal"; // Equel constant
public const string neaR = "Near"; // NearEquel constant
public const int avgDays = 3; // number of days to count average values
public const int avgVolumeColumn = 6; // average volume column in history table
public const int avgDayLengthColumn = 7; // average day column in history table
public const int volumeColumn = 5; // volume column index
public const int candleW = 20;
public const double almostTheSame = 0.001; // if ratio is less then this, we consider them the same
public const string fEts = "fEts"; // first equal to second
public const string fBts = "fBts"; // first bigger then second
public const string fSts = "fSts"; // first smaller then second
public const string fNts = "fNts"; // first near to second
public const string falL = "FALL"; // fall constant
public const string growtH = "GROW"; // grow constant
public const string commaCountry=yeS; // if your country uses decimal comma change yeS to nO below
static string _strTest1;
public static string strTest1 // global variable
{ get { return _strTest1; } set { _strTest1 = value; } } // access routine for global variable static string _strTest1; static string _strTest1;
static string _ghtDays; // number of days in history table
public static string ghtDays // global variable
{ get { return _ghtDays; } set { _ghtDays = value; } } //access routine for global variable static string _ghtDays;
static string[,] _ghistoryArray=new string[90,8]; // global variable
public static string[,] ghistoryArray
{
get { return _ghistoryArray; } set { _ghistoryArray = value; } } // access routine for global variable
}
class makeHeader
{
public makeHeader()
{
this.succesS=Globals.yeS;
}
public string succesS {get;private set;}
}
class aboutDay
{
public aboutDay(double[] arra)
{
this.dayColor = ""; // Globals.whitE;
this.dayLengthDesc = "";
this.dayLengthNum = 0;
compareTwoNumbers ctn = new compareTwoNumbers(arra[1], arra[2]);
if (ctn.biggeRs==Globals.seCond) this.dayColor = Globals.whitE;
if (ctn.smalleRs==Globals.fiRst) this.dayColor = Globals.blacK;
if (ctn.equalS==Globals.yeS | ctn.equalFNearS==Globals.yeS) this.dayColor = Globals.nO;
}
public string dayColor { get; private set; }
public string dayLengthDesc { get; private set; }
public double dayLengthNum { get; private set; }
}
class stringToDouble
{
public stringToDouble(string valuE) // coverts string to double having in mind decimal sign
{
double mla; // init variable
mla = Convert.ToDouble(valuE); // convert with default function
if (valuE.Contains(".")) // check for decimal point
{
if (Globals.commaCountry == Globals.yeS) // check if we use decimal comma
{ mla = Convert.ToDouble(valuE.Replace(".", ",")); } // but if you use decimal comma we need fix
}
else
{ mla = Convert.ToDouble(valuE); } // convert string to double
this.doublE = mla; // return values
}
public double doublE { get; private set; }
}
class calC
{
public calC(string firsT, string seconD) // calC class - input are two numbers as string - string to double for countries
{ // using decimal comma
double mlaF; // auxiliary number for the first day
double mlaS; // auxiliary number for the second day
if (firsT == null | seconD == null) goto kraj;
if (firsT.Contains(".")) // if string contains point
{
if (Globals.commaCountry == Globals.yeS) // if country uses decimal comma
{ mlaF = Convert.ToDouble(firsT.Replace(".", ",")); } // and if you use decimal comma we need fix
}
else
{ mlaF = Convert.ToDouble(firsT); } // convert string to doubleif (firsT.Contains("."))
if (seconD.Contains(".")) // the same as above for first number
{
if (Globals.commaCountry == Globals.yeS)
{ mlaS = Convert.ToDouble(seconD.Replace(".", ",")); } // but if you use decimal comma we need fix
}
else
{ mlaS = Convert.ToDouble(seconD); } // convert string to doubleif (firsT.Contains("."))
double mlaPro = Math.Round( mlaF * mlaS,2); // product rounded to two decimal places
double mlaDiffFirstMinSecond = Math.Round(mlaF - mlaS,2); // difference first minus second rounded to two decimal places
double mlaSum = Math.Round(mlaF + mlaS,2); // first plus second rounded to two decimal places
double mlaabS = Math.Round (Math.Abs(mlaF - mlaS),2) ; // difference first minus second rounded to two decimal places
biggeRsmaller bgR = new biggeRsmaller(firsT, seconD);
double c = Math.Abs((mlaF - mlaS) / bgR.biggeR);
this.producT = mlaPro; // define properties
this.diffFmS = mlaDiffFirstMinSecond;
this.sumFS = mlaSum;
this.abS = mlaabS;
kraj: ;
}
public double producT { get; private set; }
public double diffFmS { get; private set; }
public double sumFS { get; private set; }
public double abS { get; private set; }
}
class biggeRsmaller // compares two numbers as string
{
public biggeRsmaller(string f, string s) // (f)irst and (s)econd
{
stringToDouble ca = new stringToDouble(f); // convert string to number having in mind decimal comma
double a = ca.doublE; // a is first result
stringToDouble cb = new stringToDouble(s);
double b = cb.doublE; // b is second result
double sM = 0; // init variable
if (a < b) { sM = b; this.biggeR = b; this.biggeRs = s; this.smalleR = a; this.smalleRs = f; this.bseN = Globals.fSts; }
if (a > b) { sM = a; this.smalleR = b; this.smalleRs = s; this.biggeR = a; this.biggeRs = f; this.bseN = Globals.fBts; }
if (this.biggeR == 0) { this.biggeR = a; }
double c = Math.Abs((a - b) / this.biggeR);
if (c <= Globals.almostTheSame) { this.equalNearS = Globals.yeS; } // first near to second i.e. almost the same
if (a == b) { sM = b; this.equalS = Globals.yeS; }
}
public double biggeR { get; private set; }
public double smalleR { get; private set; }
public string biggeRs { get; private set; }
public string smalleRs { get; private set; }
public string equalS { get; private set; }
public string equalNearS { get; private set; }
public string bseN { get; private set; }
}
class compareTwoNumbers // compares two numbers as string
{
public compareTwoNumbers(double f, double s) // (f)irst and (s)econd
{
double a = f;
double b = s;
if (a < b) { this.biggeR = b; this.biggeRs = Globals.seCond; this.smalleR = a; this.smalleRs = Globals.fiRst; this.equalFNearS = Globals.nO; this.equalS = Globals.nO; }
if (a > b) { this.smalleR = b; this.smalleRs = Globals.seCond; this.biggeR = a; this.biggeRs = Globals.fiRst; this.equalFNearS = Globals.nO; this.equalS = Globals.nO; }
// if (this.biggeR == 0) { this.biggeR = a; }
double c = Math.Abs((a - b) / this.biggeR);
if (c <= Globals.almostTheSame) { this.equalFNearS = Globals.yeS; this.equalS = Globals.nO; } // first near to second i.e. almost the same
if (a == b) { this.equalS = Globals.nO; this.equalFNearS = Globals.yeS; this.biggeRs = Globals.nO; this.smalleRs = Globals.nO; }
}
public double biggeR { get; private set; }
public double smalleR { get; private set; }
public string biggeRs { get; private set; }
public string smalleRs { get; private set; }
public string equalS { get; private set; }
public string equalFNearS { get; private set; }
}
}
Subscribe to:
Posts (Atom)