Present code became too "massive" and I wonder myself could be easier if I could organise them in different way. My experience with VB6 learnt me that variables and functions can be in separate files. After Internet search for global variables and constants in C# I found solution. By the way, I found how to switch two forms in C#. :-) This solution is here, also. So, first how to declare C# global variables to be on disposal to more then one form. We should create new class via menu Project -> Add class. Choose class and rename it in right pane as you like
I called it Globals. "cs" is default.
So, I moved constants from Form1 to Globals.cs (cut->paste) and add "public" declarationa. Below is how it looks in 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 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 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
}
}
Those variables are removed from Form1.cs code. Also, to keep functionality, I needed to add Form1 code reference to new class. Please note Globals prefix added to previous declaration.
if (c <= Globals.almostTheSame) { reS = Globals.fNts; } // first near to second
if (stringToDouble(firsT) > stringToDouble(seconD)) { reS = Globals.fBts; } // first bigger then second
if (stringToDouble(firsT) < stringToDouble(seconD)) { reS = Globals.fSts; } // first smaller then second
if (stringToDouble(firsT) == stringToDouble(seconD)) { reS = Globals.fEts; } // first equal to second
Also, it means we could have constants with the same name within Form1.cs without any collision having their own values. Adding Globals.ccccc should be done for all constants moved to new class. I'd like to move "private void mBullishEngulfing() // bullish pattern Medium strong" because it is function which is actually "static". It means no further changes. I do not know how to that at the moment.
During my search for this solution I found way how to switch between two forms. At the moment, it is not needed but in near future, it will be.
So, Form2 was added. To switch between these two forms, Form1 and Form2), code in Form1 is needed under menu item "Patterns". How to add menu strip, please ask me.
private void patternsToolStripMenuItem_Click(object sender, EventArgs e)
{
switchTo();
this.Hide();
}
To make this work we need to define function switchTo:
public void switchTo() {
new fPatterns().Show();
}
Those commands will hide Form1 and show Form2. Please note that Form2 has name fPatterns. To come back we need some code in Form2. Under item Main is code to come back to main Form1.
public void switchTo() { new Form1().Show(); }
private void mainToolStripMenuItem_Click(object sender, EventArgs e)
{
switchTo();
this.Hide();
}
Almost the same on Form1 but fPatterns changed to Form1.
To track easier these two changes Form1 code is here:
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[7]; // working array - today
public string[] arrDay1 = new string[7]; // working array - yesterday
public string[] arrDay2 = new string[7]; // working array - day before yesterday
public string[] arrDay3 = new string[7]; // working array - 3 days before
public string[] arrDay4 = new string[7]; // working array - 4 days before
public string commaCountry; // if your country uses decimal comma change yeS to nO below
// const string whitE = "White"; // white constant
// const int avgDays = 3; // number of days to count average values
// const int avgVolumeColumn = 6; // average volume column in history table
// const int avgDayLengthColumn = 7; // average day column in history table
// const int volumeColumn = 5; // volume column index
// const double almostTheSame = 0.001; // if ratio is less then this, we consider them the same
public double sum; // auxiliary variable
public double sum1; // auxiliary variable
// const string fEts="fEts"; // first equal to second
// const string fBts="fBts"; // first bigger then second
// const string fSts="fSts"; // first smaller then second
// const string fNts = "fNts"; // first near to second
// const string falL = "FALL"; // fall constant
// const string growtH = "GROW"; // grow constant
private void Form1_DoubleClick(object sender, EventArgs e)
{
Environment.Exit(0); // double click on form to end application- just for quick exit when testing
}
public DataTable makeHistoryHeader() {
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
return historyTable;
}
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
makeHistoryHeader(); // header init of historyTable
commaCountry = Globals.yeS; // change yeS to nO if you do not use decimal comma
}
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)
{
string part1bloom = "http://www.internet.com/apps/data?pid=webpxta&Securities="; // first part of internet url histroy string
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
historyTable.Clear();
Int16 j = Convert.ToInt16( fillHistoryTableDays.Text); // convert textbox text to int16
fillHistoryT(j); // getting data from local disk // invoke table filling
fillWorkingArrays(0,6); // fill daily working arrays
zeroDay.Text = historyGrid[0, 0].Value.ToString(); // show zero day to analyze
urlHistory.BackColor = Color.White; // restore back color
}
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
historyTable.Clear(); // clear list before filling
int fL = fileLines.Count - 2; // newest date is two rows before end of file
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
}
computeAverage(); // compute some auxiliary values
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();
//historyTable.Rows.CopyTo(arrDay0,1)
}
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,6); // selected raw index will be 0 day -> "today". this is for lates market analyse.
analyseResults.Items.Clear(); // clear listbox
}
private double stringToDouble(string valuE)
{
double mla;
mla = Convert.ToDouble(valuE);
if (valuE.Contains("."))
{
if (commaCountry == Globals.yeS)
{ mla = Convert.ToDouble(valuE.Replace(".", ",")); } // but if you use decimal comma we need fix
else
{ mla = Convert.ToDouble(valuE); } // convert string to double - open price
} return mla;
}
private string dayColor( string[] aR)
{
string mE = "Day color : "; // name of routine
string coloR; // color of the day
double openP; // opening price
double closeR; // closing price
openP = stringToDouble(aR[1]); // covert string to double
closeR=stringToDouble(aR[2]);
double closeMinusOpen = closeR - openP; // covert string to double
if (closeMinusOpen > 0) // is close price bigger then oper
{ coloR = Globals.whitE; } // yes, white day
else if (closeMinusOpen < 0) { coloR = Globals.blacK; } // no, black day
else { coloR = Globals.nO; } // both prices are the same -> no color
if (showDetails.Checked) { analyseResults.Items.Add(mE +aR[0] + " -> " + coloR); }
return coloR;
}
private void analyseDay_Click(object sender, EventArgs e)
{
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
sum = 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
sum = sum + stringToDouble(aux); // convert to double
aux = historyGrid[1, j1+1].Value.ToString(); // extract open price
aux1 = historyGrid[2, j1+1].Value.ToString(); // extract close price
sum1 = sum1 + Math.Abs(stringToDouble(aux) - stringToDouble(aux1)); // length of day
j1++; // increment
}
if ( k +1 < j) // after last loop no need to calculate
{
sum = Math.Round((sum / 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] = sum.ToString(); // add to histry table
historyTable.Rows[k][Globals.avgDayLengthColumn] = sum1.ToString();
} // add to histry table
}
}
private string comparE(string firsT, string seconD) // compare to values
{ string reS;
reS = "";
double a = stringToDouble(firsT);
double b = stringToDouble(seconD);
double c=Math.Abs((a-b)/stringToDouble(biggeR(firsT,seconD)));
if (c <= Globals.almostTheSame) { reS = Globals.fNts; } // first near to second
if (stringToDouble(firsT) > stringToDouble(seconD)) { reS = Globals.fBts; } // first bigger then second
if (stringToDouble(firsT) < stringToDouble(seconD)) { reS = Globals.fSts; } // first smaller then second
if (stringToDouble(firsT) == stringToDouble(seconD)) { reS = Globals.fEts; } // first equal to second
return reS;
}
private string smalleR(string a, string b) // which one is smaller
{
string sM = "";
if (stringToDouble(a) < stringToDouble(b)) { sM = a; }
if (stringToDouble(a) > stringToDouble(b)) { sM = b; }
if (stringToDouble(a) == stringToDouble(b)) { sM = b; }
return sM;
}
private string biggeR(string a, string b) // which one is smaller
{
string sM = "";
if (stringToDouble(a) < stringToDouble(b)) { sM = b; }
if (stringToDouble(a) > stringToDouble(b)) { sM = a; }
if (stringToDouble(a) == stringToDouble(b)) { sM = b; }
return sM;
}
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
if (comparE(arrDay1[2].ToString(), arrDay0[1].ToString()) == Globals.fBts) { sumA++; } // close yesterday should be lower then open today
if (comparE(arrDay0[2].ToString(), arrDay1[1].ToString()) == Globals.fBts) { sumA++; } //close today shoul be higher then open yesterday
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
}
}}
and Form2 code named fPatterns.
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 fPatterns()
{
InitializeComponent();
}
private void fPatterns_Load(object sender, EventArgs e)
{
}
private void chart1_Click(object sender, EventArgs e)
{
}
public void switchTo() { new Form1().Show(); }
private void mainToolStripMenuItem_Click(object sender, EventArgs e)
{
switchTo();
this.Hide();
}
}
}
No comments:
Post a Comment