public DetailViewModel getDetailViewModel(long id) { FullPatientData dataModel = cache.loadPatientDataModel(id); DetailViewModel model = new DetailViewModel(); if (dataModel != null) { model.observations = dataModel.observations; model.patient = dataModel.patient; model.patientID = dataModel.patientID; model.QRs = dataModel.QRs; model.questionnaireMap = dataModel.questionnaireMap; } //load selected charts ChartSelection charts = chartSelectionRepo.getChartsByTherapistId(0); //0 is therapistID, replace with ID when authentication is impl if (charts != null && charts.chartMap.Keys.Contains(id.ToString())) //saved settings exist { model.selectedCharts = charts.chartMap[id.ToString()]; } else { model.selectedCharts = new Dictionary <string, string>(); } return(model); }
private void FrmSelectChartFormClosing(object sender, FormClosingEventArgs e) { if (DialogResult != DialogResult.OK) { _mSelection = new ChartSelection(); } }
private string FormRequestString(ChartSelection selection) { //Specs, //https,//www.cryptocompare.com/api/#-api-data-histoday- //Set correct endpoint var ep = ""; switch (selection.Periodicity) { case EPeriodicity.Hourly: ep = @"histohour"; break; case EPeriodicity.Minutely: ep = @"histominute"; break; case EPeriodicity.Daily: ep = @"histoday"; break; default: MessageBox.Show("CryptoCompare supports only days, hours and minutes"); return(""); } var requestUrl = Settings.Default.APIUrl + "data/" + ep + "?fsym=" + selection.Symbol + "&tsym=" + BaseSymbol + "&limit=" + selection.Bars + "&aggregate=" + (int)selection.Interval + "&e=" + Exchange; //"&toTs=" + unix; FireConnectionStatus("Get: " + requestUrl); return(requestUrl); }
public ChartSelection(ChartSelection other) { chartPath = other.chartPath; directory = other.directory; chartType = other.chartType; difficulty = other.difficulty; instrument = other.instrument; }
public ChartControl() { Selection = new ChartSelection(); Selection.BeforeClear += Selection_BeforeClear; Selection.AfterClear += Selection_AfterClear; MultiSelect = true; }
public ChartControl() { Selection = new ChartSelection(); Selection.BeforeClear += new EventHandler(Selection_BeforeClear); Selection.AfterClear += new EventHandler(Selection_AfterClear); MultiSelect = true; }
//Get the user inputed selection information private ChartSelection GetSelection(string Symbol) { ChartSelection selection = new ChartSelection { Periodicity = (M4Core.Entities.Periodicity)Periodicity, Interval = Interval, Bars = Bars, Symbol = Symbol }; return(selection); }
private void BtnGraphicsClick(object sender, EventArgs e) { ChartSelection selection = (new FrmSelectChart()).GetChartSelection(); if (selection == null) { return; } MFrmMain.CreateNewCtlPainel(selection); //MFrmMain.CreateNewChart(selection); }
public void GetHistory(ChartSelection selection, IHistorySubscriber subscriber) { var request = new HistoryRequest { ChartSelection = selection, HistorySubscriber = subscriber }; request.ChartSelection.Symbol = request.ChartSelection.Symbol.ToUpper(); if (!ValidateRequest(request)) { SendNoHistory(request); return; } ThreadPool.QueueUserWorkItem(state => ProcessRequest(request)); }
public void upsertSingleEntry(long therapistID, string patientID, string chartName, string chartType) { //find if exists var filter = Builders <ChartSelection> .Filter.Eq(x => x.therapistID, therapistID); var charts = collection.Find(filter).FirstOrDefault(); if (chartName.Contains(".")) { chartName = chartName.Replace(".", "*"); //can't have dots } //insert if (charts != null && charts.chartMap != null) { Dictionary <string, Dictionary <string, string> > map = charts.chartMap; if (map.Keys.Contains(patientID)) //has settings for patient { if (!map[patientID].Keys.Contains(chartName)) { map[patientID][chartName] = chartType; } } else { map[patientID] = new Dictionary <string, string>(); map[patientID][chartName] = chartType; } collection.UpdateOne(filter, Builders <ChartSelection> .Update.Set("chartMap", map) ); } else { ChartSelection entry = new ChartSelection(); entry.therapistID = therapistID; entry.chartMap = new Dictionary <string, Dictionary <string, string> >(); entry.chartMap[patientID] = new Dictionary <string, string>(); entry.chartMap[patientID][chartName] = chartType; collection.InsertOne(entry); } }
private void ViewChart(string symbol) { if (_parentControl.MFrmMain.MActiveChart != null) { _parentControl.MFrmMain.MActiveChart.StockChartX1.LoadUserStudyLine(-1); } if (_parentControl.MFrmMain.m_DockManager.DocumentManager.ActiveDocument != null) { if (_parentControl.MFrmMain.m_DockManager.DocumentManager.ActiveDocument.Client.Name == "CtlPainelChart") { _parentControl.MFrmMain.MActiveChart.StockChartX1.SaveGeneralTemplate(ListTemplates._path + "TempTemplate" + ".sct"); _parentControl.MFrmMain.MActiveChart.MSymbol = symbol; _parentControl.MFrmMain.MActiveChart._source = _parentControl.MFrmMain.MActiveChart._mListSymbols.Where(r => r.Code.Equals(symbol)).Single().Source; _parentControl.MFrmMain.MActiveChart.LoadChart(_parentControl.MFrmMain.MActiveChart.MSymbol); _parentControl.MFrmMain.MActiveChart.InitRTChartAsync(b => _parentControl.MFrmMain.MActiveChart._asyncOp.Post(() => { if (b) { _parentControl.MFrmMain.MActiveChart.BindContextMenuEvents(); return; } return; })); _parentControl.MFrmMain.m_DockManager.DocumentManager.ActiveDocument.Text = _parentControl.MFrmMain.MActiveChart.GetChartTitle(); _parentControl.MFrmMain.MActiveChart.StockChartX1.Focus(); _parentControl.MFrmMain.MActiveChart.StockChartX1.Update(); return; } } ChartSelection selection = (new FrmSelectChart { CodeStock = symbol }).GetChartSelection(symbol); if (selection == null) { return; } _parentControl.MFrmMain.CreateNewCtlPainel(selection); }
private void NewChart(object sender, EventArgs e) { if (radGridView1.CurrentCell == null) { return; } ChartSelection selection = (new FrmSelectChart { CodeStock = radGridView1.CurrentCell.RowInfo.Cells[0].Value.ToString() }).GetChartSelection(); if (selection == null) { return; } _parentControl.MFrmMain.CreateNewCtlPainel(selection); _parentControl.MFrmMain2.CreateNewCtlPainel(selection); }
//...generate WebAPI GET request format string private string FormRequestString(ChartSelection selection) { //API Endpoint, e.g. //https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_EUR/latest?period_id=1DAY&limit=200 //Set correct endpoint var ep = ""; switch (selection.Periodicity) { case EPeriodicity.Hourly: ep = $"{(int) selection.Interval}HRS"; break; case EPeriodicity.Minutely: ep = $"{(int) selection.Interval}MIN"; break; case EPeriodicity.Daily: ep = $"{(int) selection.Interval}DAY"; break; default: MessageBox.Show("CoinApi supports only days, hours and minutes"); return(""); } var requestUrl = $"{Settings.Default.APIUrl}v1/ohlcv/{selection.Symbol}/latest?period_id={ep}&limit={selection.Bars}"; //... Alternative request with start- and end-dates //var requestUrl = string.Format("/v1/ohlcv/{0}/history?period_id={1}&time_start={2}&time_end={3}", symbolId, periodId, start.ToString(dateFormat), end.ToString(dateFormat)); //string requestUrl = Properties.Settings.Default.APIUrl + // "v1/ohlcv/" + selection.Symbol+ "/latest?" + "period_id=" + ep + "&limit=" + selection.Bars; //debug only //FireConnectionStatus("Get: " + requestUrl); return(requestUrl); }
/// <summary> /// Creates a notechart from the specified midi path and the actual charttype /// (i.e. ExpertSingle from notes.mid). Due to the overhead necessary to /// parse a midi file. I am going to cram all midi->chart operations into /// one function call. /// This function uses the Toub midi parser which is much faster than Sanford, /// but will throw an exception on certian midi files. /// </summary> /// <param name="chartSelection"> /// The information on which particular notechart to use. /// </param> /// <param name="chartInfo">The metadata on the chart.</param> /// <param name="BPMChanges">The list of BPM changes for this chart.</param> /// <returns> /// A filled out Notechart containing the needed information from the *.mid file. /// </returns> public static Notes ParseMidiInformationToub(ChartSelection chartSelection, Info chartInfo, List <BPMChange> BPMChanges) { Notes notechartToReturn = new Notes(); notechartToReturn.instrument = chartSelection.instrument; notechartToReturn.difficulty = chartSelection.difficulty; // The following two switch's are used to get the proper midi terminology for // the selected track and difficulty. string instrumentPart = null; string greenKey = null; string redKey = null; string yellowKey = null; string blueKey = null; string orangeKey = null; switch (chartSelection.instrument) { case "Single": instrumentPart = "PART GUITAR"; break; case "DoubleGuitar": instrumentPart = "PART GUITAR COOP"; break; case "DoubleBass": instrumentPart = "PART BASS"; break; case "Drums": instrumentPart = "PART DRUMS"; break; default: instrumentPart = "PART GUITAR"; break; } switch (chartSelection.difficulty) { case "Expert": greenKey = "C8"; redKey = "C#8"; yellowKey = "D8"; blueKey = "D#8"; orangeKey = "E8"; break; case "Hard": greenKey = "C7"; redKey = "C#7"; yellowKey = "D7"; blueKey = "D#7"; orangeKey = "E7"; break; case "Medium": greenKey = "C6"; redKey = "C#6"; yellowKey = "D6"; blueKey = "D#6"; orangeKey = "E6"; break; case "Easy": greenKey = "C5"; redKey = "C#5"; yellowKey = "D5"; blueKey = "D#5"; orangeKey = "E5"; break; default: greenKey = "C8"; redKey = "C#8"; yellowKey = "D8"; blueKey = "D#8"; orangeKey = "E8"; break; } MidiSequence mySequence = MidiSequence.Import(chartSelection.directory + "\\notes.mid"); MidiTrack[] myTracks = mySequence.GetTracks(); chartInfo.resolution = mySequence.Division; MidiTrack trackToUse = new MidiTrack(); uint totalTickValue = 0; // Go through each event in the first track (which contains the BPM changes) // and parse the resulting string. for (int i = 0; i < myTracks[0].Events.Count; i++) { Toub.Sound.Midi.MidiEvent currEvent = myTracks[0].Events[i]; string eventString = currEvent.ToString(); string[] splitEventString = eventString.Split('\t'); // Since ticks are stored relative to each other (e.g. 300 ticks // until next note), we must maintain the total tick amout. totalTickValue += Convert.ToUInt32(splitEventString[1]); if (splitEventString[0] == "Tempo") { // In midi files, bpm chages are stored as "microseconds per quarter note" // and must be converted to BPM, and then into the non decimal format the game // uses. double currBPMDouble = 60000000 / Convert.ToDouble(splitEventString[3]); uint BPMToAdd = (uint)(currBPMDouble * 1000); BPMChanges.Add(new BPMChange(totalTickValue, BPMToAdd)); } } trackToUse = new MidiTrack(); // Find the specified instrument's track foreach (MidiTrack currTrack in myTracks) { string trackHeader = currTrack.Events[0].ToString(); string[] splitHeader = trackHeader.Split('\t'); // -If we come across a "T1 GEMS" track, we're in GH1 territory. // -GH2/FoF has both PART BASS and PART RHYTHM (one or the other depending // on the chart). if (((splitHeader[3] == instrumentPart) || (splitHeader[3] == "T1 GEMS")) || ((splitHeader[3] == "PART RHYTHM") && (instrumentPart == "PART BASS"))) { trackToUse = currTrack; } } totalTickValue = 0; uint currTickValue = 0; Note currNote = new Note(); bool blankNote = true; // Scan through and record every note specific to the selected difficulty for (int i = 0; i < trackToUse.Events.Count; i++) { string currEvent = trackToUse.Events[i].ToString(); string[] splitEvent = currEvent.Split('\t'); currTickValue = Convert.ToUInt32(splitEvent[1]); totalTickValue += currTickValue; // We need to specify wether a note is blank or not so we don't add // blank notes from other difficulties into the chart, but if we have // a filled out note, any nonzero tick value means we are moving to a // new note, so we must cut our ties and add this note to the chart. if ((currTickValue != 0) && !blankNote) { notechartToReturn.notes.Add(currNote); currNote = new Note(); blankNote = true; } // The "0x64" I think means "not was hit." There is another // set of notes that use "0x00" that all appear slightly after // the "0x64" notes. if ((splitEvent[0] == "NoteOn") && (splitEvent[4] != "0x00")) { // Only consider notes within the octave our difficulty is in. if ((splitEvent[3] == greenKey) || (splitEvent[3] == redKey) || (splitEvent[3] == yellowKey) || (splitEvent[3] == blueKey) || (splitEvent[3] == orangeKey)) { // If it's a new note, we need to setup the tick value of it. if (blankNote) { currNote.tickValue = totalTickValue; blankNote = false; } if (splitEvent[3] == greenKey) { currNote.addNote(0); } else if (splitEvent[3] == redKey) { currNote.addNote(1); } else if (splitEvent[3] == yellowKey) { currNote.addNote(2); } else if (splitEvent[3] == blueKey) { currNote.addNote(3); } else if (splitEvent[3] == orangeKey) { currNote.addNote(4); } } } } return(notechartToReturn); }
/// <summary> /// Creates a notechart from the specified file and the actual charttype /// (i.e. ExpertSingle from Freebird.chart) /// </summary> /// <param name="chartSelection"> /// The information on which particular notechart to use. /// </param> /// <returns> /// A filled out Notechart containing the needed information from the *.chart file /// </returns> public static Notes GenerateNotechartFromChart(ChartSelection chartSelection) { string chartname = chartSelection.difficulty + chartSelection.instrument; StreamReader inputStream = new StreamReader(chartSelection.chartPath); string inputString = inputStream.ReadToEnd(); // Single out the specified section via regular expressions string pattern = Regex.Escape("[") + chartname + "]\\s*" + Regex.Escape("{") + "[^}]*"; Match matched_section = Regex.Match(inputString, pattern); // Create the stream from the singled out section of the input string StringReader pattern_stream = new StringReader(matched_section.ToString()); string current_line = ""; string[] parsed_line; // Create the resulting notechart and prep for input Notes notechartToReturn = new Notes(chartSelection.difficulty, chartSelection.instrument); //If specific notechart is not found, return a generic one if (!(matched_section.Success)) { notechartToReturn.notes.Add(new Note()); } // Else, read in all the chart information else { int i = 0; while ((current_line = pattern_stream.ReadLine()) != null) { // Trim and split the line to retrieve information current_line = current_line.Trim(); parsed_line = current_line.Split(' '); // If a valid note is found, add it to the list if (parsed_line.Length == 5) { if (parsed_line[2] == "N") { if ((notechartToReturn.notes.Count > 0) && (Convert.ToUInt32(parsed_line[0]) == notechartToReturn.notes[notechartToReturn.notes.Count - 1].tickValue)) { switch (Convert.ToInt32(parsed_line[3])) { case 0: notechartToReturn.notes[notechartToReturn.notes.Count - 1].addNote(0); break; case 1: notechartToReturn.notes[notechartToReturn.notes.Count - 1].addNote(1); break; case 2: notechartToReturn.notes[notechartToReturn.notes.Count - 1].addNote(2); break; case 3: notechartToReturn.notes[notechartToReturn.notes.Count - 1].addNote(3); break; case 4: notechartToReturn.notes[notechartToReturn.notes.Count - 1].addNote(4); break; default: Console.WriteLine("ERROR: Invalid Note Detcted. Skipping..."); break; } } else { // Find out which note the current line is, and add it to the respective list switch (Convert.ToInt32(parsed_line[3])) { case 0: notechartToReturn.notes.Add(new Note(Convert.ToUInt32(parsed_line[0]), Convert.ToInt32(parsed_line[4]), 0)); break; case 1: notechartToReturn.notes.Add(new Note(Convert.ToUInt32(parsed_line[0]), Convert.ToInt32(parsed_line[4]), 1)); break; case 2: notechartToReturn.notes.Add(new Note(Convert.ToUInt32(parsed_line[0]), Convert.ToInt32(parsed_line[4]), 2)); break; case 3: notechartToReturn.notes.Add(new Note(Convert.ToUInt32(parsed_line[0]), Convert.ToInt32(parsed_line[4]), 3)); break; case 4: notechartToReturn.notes.Add(new Note(Convert.ToUInt32(parsed_line[0]), Convert.ToInt32(parsed_line[4]), 4)); break; default: Console.WriteLine("ERROR: Invalid Note Detcted. Skipping..."); break; } } } // Also check for SP notes else if (parsed_line[2] == "S") notechartToReturn.SPNotes.Add(new Note(Convert.ToUInt32(parsed_line[0]), Convert.ToInt32(parsed_line[4]), 5)); } i++; } } // Close the string stream pattern_stream.Close(); return notechartToReturn; }
//Runs the backtest and displays the chart with buy/sell/exit icons. private string RunBacktest() { string ret = string.Empty; _oScript.ClearRecords(); _oBacktest.ClearRecords(); if (!VerifyForm()) { return(string.Empty); } if (!TestScripts()) { return(string.Empty); } if (_mCtlData == null) { return(string.Empty); } cmdBacktest.Text = "&Stop Backtest"; cmdBacktest.Border.BaseColor = Color.Red; EnableControls(false); cmdBacktest.Border.Update(); Periodicity periodicity; switch (cboPeriodicity.Text) { case "Day": periodicity = Periodicity.Daily; break; case "Hour": periodicity = Periodicity.Hourly; break; case "Minute": periodicity = Periodicity.Minutely; break; case "Week": periodicity = Periodicity.Weekly; break; case "Month": periodicity = Periodicity.Month; break; case "Year": periodicity = Periodicity.Year; break; default: periodicity = Periodicity.Minutely; break; } cmdBacktest.Enabled = false; //Get the data selection ChartSelection selection = new ChartSelection { Periodicity = periodicity, Symbol = txtSymbol.Text, Interval = Convert.ToInt32(txtInterval.Text), Bars = Convert.ToInt32(txtBars.Text), Source = "PLENA" }; _ctlPainelChart = _mCtlData.GetCtlPainelChart(selection, true); //Ensure the chart is new if (_ctlPainelChart == null) { goto Quit; } DataManager.BarData[] bars = _ctlPainelChart.GetDataFromChart(); if (bars.Length < 1) { goto Quit; } _ctlPainelChart.Subscribers += 1; _ctlPainelChart.RealTimeUpdates = false; //Get historic data cmdBacktest.Enabled = true; if (bars.Length < 3) { goto Quit; //Bad request } //Insert the data into all four instances of TradeScript _oScript.ClearRecords(); _oBacktest.ClearRecords(); DateTime td; double jdate; for (int n = 1; n < bars.Length - 1; n++) { td = bars[n].TradeDate; jdate = _oScript.ToJulianDate(td.Year, td.Month, td.Day, td.Hour, td.Minute, td.Second, 0); _oScript.AppendRecord(jdate, bars[n].OpenPrice, bars[n].HighPrice, bars[n].LowPrice, bars[n].ClosePrice, (int)bars[n].Volume); _oBacktest.AppendRecord(jdate, bars[n].OpenPrice, bars[n].HighPrice, bars[n].LowPrice, bars[n].ClosePrice, (int)bars[n].Volume); } //TODO ret = _oBacktest.Backtest(txtBuyScript.Text, txtSellScript.Text, txtExitLongScript.Text, txtExitShortScript.Text, 0.001); if (string.IsNullOrEmpty(ret)) { goto Quit; } string output = _oScript.GetScriptOutput(txtBuyScript.Text + " AND \r\n" + txtSellScript.Text + " AND \r\n" + txtExitLongScript.Text + " AND \r\n" + txtExitShortScript.Text); if (string.IsNullOrEmpty(output)) { goto Quit; } int row; string[] cols; int col; string[] rows = output.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); string[] header = SplitHeader(rows[0]); //StockChartX AxSTOCKCHARTXLib.AxStockChartX StockChartX1 = _ctlPainelChart.StockChartX1; StockChartX1.RemoveAllSeries(); string symbol = selection.Symbol; StockChartX1.Symbol = symbol; StockChartX1.AddChartPanel(); StockChartX1.AddSeries(symbol + ".open", STOCKCHARTXLib.SeriesType.stCandleChart, 0); StockChartX1.AddSeries(symbol + ".high", STOCKCHARTXLib.SeriesType.stCandleChart, 0); StockChartX1.AddSeries(symbol + ".low", STOCKCHARTXLib.SeriesType.stCandleChart, 0); StockChartX1.AddSeries(symbol + ".close", STOCKCHARTXLib.SeriesType.stCandleChart, 0); StockChartX1.set_SeriesColor(symbol + ".close", ColorTranslator.ToOle(Color.Black)); bool hasVolume = bars[0].Volume != -987654321; if (hasVolume) { StockChartX1.AddChartPanel(); StockChartX1.AddSeries(symbol + ".volume", STOCKCHARTXLib.SeriesType.stVolumeChart, 1); StockChartX1.set_SeriesColor(symbol + ".volume", ColorTranslator.ToOle(Color.Blue)); StockChartX1.set_SeriesWeight(symbol + ".volume", 3); StockChartX1.VolumePostfixLetter = "M"; //Google trades in millions } for (col = 6; col < header.Length; col++) { int panel = StockChartX1.AddChartPanel(); StockChartX1.AddSeries(header[col], STOCKCHARTXLib.SeriesType.stLineChart, panel); Color color; switch (col) { case 6: color = Color.Blue; break; case 7: color = Color.Red; break; case 8: color = Color.Green; break; case 9: color = Color.Orange; break; case 10: color = Color.Purple; break; default: color = Color.Blue; break; } StockChartX1.set_SeriesColor(header[col], ColorTranslator.ToOle(color)); } for (row = 1; row < rows.Length; row++) { cols = rows[row].Split(','); jdate = GetJDate(cols[0]); StockChartX1.AppendValue(symbol + ".open", jdate, Convert.ToDouble(cols[1], _ciEnUs)); StockChartX1.AppendValue(symbol + ".high", jdate, Convert.ToDouble(cols[2], _ciEnUs)); StockChartX1.AppendValue(symbol + ".low", jdate, Convert.ToDouble(cols[3], _ciEnUs)); StockChartX1.AppendValue(symbol + ".close", jdate, Convert.ToDouble(cols[4], _ciEnUs)); if (hasVolume) { StockChartX1.AppendValue(symbol + ".volume", jdate, Convert.ToDouble(cols[5], _ciEnUs) / 1000000); } for (col = 6; col < cols.Length; col++) { double value = Convert.ToDouble(cols[col], _ciEnUs); if (value == 0 && row < rows.Length * 0.2) { value = (double)STOCKCHARTXLib.DataType.dtNullValue; } StockChartX1.AppendValue(header[col], jdate, value); } } StockChartX1.Update(); Quit: if (_ctlPainelChart != null) { _ctlPainelChart.Show(); } cmdBacktest.Text = "&Back Test"; cmdBacktest.Border.BaseColor = Color.Lime; EnableControls(true); cmdBacktest.Border.Update(); if (_ctlPainelChart != null) { _ctlPainelChart.Subscribers -= 1; } return(ret); }
private void BtnCancelClick(object sender, EventArgs e) { _mSelection = new ChartSelection(); DialogResult = DialogResult.Cancel; }
//...generate API GET request format private Dictionary <string, string> FormRequest(ChartSelection selection, int start, int count, string endingTime) { //API Endpoint, e.g. //https://www.bitmex.com/api/v1/trade/bucketed?binSize=1m&partial=false&count=100&reverse=false&startTime=2018-10-10 //Set correct binSize //available options: 1m,5m,1h,1d var ep = ""; switch (selection.Periodicity) { case EPeriodicity.Hourly: if ((int)selection.Interval != 1) { MessageBox.Show("BitemexApi supports only 1m, 5m, 1h, 1d."); return(null); } ep = $"{(int) selection.Interval}h"; break; case EPeriodicity.Minutely: if ((int)selection.Interval != 1 && (int)selection.Interval != 5) { MessageBox.Show("BitemexApi supports only 1m, 5m, 1h, 1d."); return(null); } ep = $"{(int) selection.Interval}m"; break; case EPeriodicity.Daily: if ((int)selection.Interval != 1) { MessageBox.Show("BitemexApi supports only 1m, 5m, 1h, 1d."); return(null); } ep = $"{(int) selection.Interval}d"; break; default: MessageBox.Show("BitemexApi supports only 1m, 5m, 1h, 1d."); return(null); } //debug only //FireConnectionStatus("Get: " + requestUrl); //always ensure we have the last active bar var param = new Dictionary <string, string>(); param["symbol"] = selection.Symbol; param["binSize"] = ep; //... available options: 1m,5m,1h,1d param["partial"] = true.ToString(); //... will send in-progress (incomplete) bins for the current time period param["start"] = start.ToString(); param["count"] = count.ToString(); //param["filter"] = "{\"open\":true}"; //param["columns"] = ""; param["reverse"] = true.ToString(); //param["startTime"] = ""; param["endTime"] = endingTime; return(param); }
void ctlWeb_DragDrop(object sender, DragEventArgs e) { string symbol = e.Data.GetData(typeof(string)).ToString(); if (symbol == "") { return; } ChartSelection selection = null; switch (Properties.Settings.Default.DefaultPeriodicity) { case "Daily": selection = new ChartSelection { Symbol = symbol, Interval = 1, Bars = 500, Periodicity = M4Core.Entities.Periodicity.Daily, Source = "PLENA" }; break; case "Weekly": selection = new ChartSelection { Symbol = symbol, Interval = 1, Bars = 500, Periodicity = M4Core.Entities.Periodicity.Weekly, Source = "PLENA" }; break; case "Month": selection = new ChartSelection { Symbol = symbol, Interval = 1, Bars = 500, Periodicity = M4Core.Entities.Periodicity.Month, Source = "PLENA" }; break; case "Yearly": selection = new ChartSelection { Symbol = symbol, Interval = 1, Bars = 500, Periodicity = M4Core.Entities.Periodicity.Year, Source = "PLENA" }; break; default: selection = (new FrmSelectChart { CodeStock = symbol }).GetChartSelection(symbol); break; } if (selection == null) { return; } mFrmMain2.CreateNewCtlPainel(selection, chart => { M4.M4v2.Settings.Scheme.Instance().UpdateChartColors(chart.StockChartX1, Properties.Settings.Default.SchemeColor); chart.m_SchemeColor = Properties.Settings.Default.SchemeColor; chart.StockChartX1.Visible = true; this.Focus(); }); }
private void cmdCancel_Click(object sender, EventArgs e) { m_selection = new ChartSelection(); DialogResult = DialogResult.Cancel; }
//Loads all required data into memory. This function must be called first. public bool LoadAllSymbolsIntoMemory() { //Verify the input and check script for errors if (m_ctlData == null || !TestScripts()) { return(false); } EnableControls(false); //Clear everything m_stop = false; m_TSAlertDictionary.Clear(); m_DGVRowDictionary.Clear(); grdResults.Rows.Clear(); DataGridViewBarGraphColumn volumeCol = (DataGridViewBarGraphColumn)grdResults.Columns["Volume"]; if (volumeCol != null) { volumeCol.MaxValue = 0; } //Load history for all symbols into memory pnlProgress.Cursor = Cursors.WaitCursor; pnlProgress.Visible = true; if (Symbols.Count > 1) { ProgressBar1.Maximum = Symbols.Count - 1; } ChartSelection selection = new ChartSelection { Periodicity = (M4Core.Entities.Periodicity)Periodicity, Interval = Interval, Bars = Bars * 3 }; if (selection.Bars < 50) { selection.Bars = 50; } lblInfo.Text = "Priming scanner, please wait..."; for (int n = 0; n < Symbols.Count; n++) { string symbol = Symbols[n]; if (m_stop) { break; } if (m_TSAlertDictionary.ContainsKey(symbol)) { continue; } selection.Symbol = symbol; ProgressBar1.Value = n; lblSymbol.Text = symbol; Application.DoEvents(); //Get historic data var bars = m_ctlData.GetHistory(symbol, this, selection.Periodicity, selection.Interval, selection.Bars, "Plena", answer => { }); if (bars == null || bars.Count < 3) { continue; } //Insert the data into TradeScript Alert oAlert = new Alert { License = "XRT93NQR79ABTW788XR48" }; foreach (M4.DataServer.Interface.BarData t in bars) { double jDate = oAlert.ToJulianDate(t.TradeDate.Year, t.TradeDate.Month, t.TradeDate.Day, t.TradeDate.Hour, t.TradeDate.Minute, t.TradeDate.Second, t.TradeDate.Millisecond); oAlert.AppendHistoryRecord(jDate, t.OpenPrice, t.HighPrice, t.LowPrice, t.ClosePrice, (int)t.VolumeF); } //Start the alert object by adding the script oAlert.AlertScript = Script; oAlert.Symbol = symbol; oAlert.ScriptError += oScript_ScriptError; oAlert.Alert += OnAlert; m_TSAlertDictionary.Add(symbol, oAlert); //Add symbol to datagridview int row; try { row = grdResults.Rows.Add(new DataGridViewRow()); } catch (Exception) { return(false); } m_DGVRowDictionary.Add(symbol, grdResults.Rows[row]); grdResults.Rows[row].Height = 25; M4.DataServer.Interface.BarData lastBar = bars.Last(); DataGridViewTextBoxScannerColorCell alertDateTime = (DataGridViewTextBoxScannerColorCell)grdResults.Rows[row].Cells["Alert Time"]; alertDateTime.HighlightOnly = true; alertDateTime.Value = lastBar.TradeDate; alertDateTime.Interval = 5000; grdResults.Rows[row].Cells["Trade Time"].Value = lastBar.TradeDate; grdResults.Rows[row].Cells["Symbol"].Value = symbol; grdResults.Rows[row].Cells["Last"].Value = Format.ToUsCurrency(lastBar.ClosePrice); grdResults.Rows[row].Cells["Volume"].Value = Format.ToLocalInteger((int)lastBar.VolumeF); DataGridViewButtonCell button = (DataGridViewButtonCell)grdResults.Rows[row].Cells["Trade"]; button.Value = "Trade"; button.FlatStyle = FlatStyle.Flat; button = (DataGridViewButtonCell)grdResults.Rows[row].Cells["Chart"]; button.Value = "Chart"; button.FlatStyle = FlatStyle.Flat; button = (DataGridViewButtonCell)grdResults.Rows[row].Cells["Settings"]; button.Value = "Settings"; button.FlatStyle = FlatStyle.Flat; button = (DataGridViewButtonCell)grdResults.Rows[row].Cells["Start"]; button.Value = "Start"; button.FlatStyle = FlatStyle.Flat; DataGridViewImageButtonCell start = (DataGridViewImageButtonCell)grdResults.Rows[row].Cells["Start"]; start.ImageOn = Resources.Play; start.ImageOff = Resources.Pause; start.OffsetY = 4; DataGridViewImageButtonCell @lock = (DataGridViewImageButtonCell)grdResults.Rows[row].Cells["Locked"]; @lock.ImageOn = Resources.Lock; @lock.ImageOff = Resources.Unlock; @lock.OffsetY = 2; } lblInfo.Text = string.Empty; pnlProgress.Visible = false; pnlProgress.Cursor = Cursors.Arrow; EnableControls(true); return(true); }
//Handles grid button clicks private void grdResults_CellClick(object sender, DataGridViewCellEventArgs e) { // this method handles only cell click // if e.RowIndex == -1 it means user clicked on header, so ignore this if (e.RowIndex == -1) { return; } try { string symbol = grdResults.SelectedRows[0].Cells["Symbol"].Value.ToString(); Alert oAlert = m_TSAlertDictionary[symbol]; if (oAlert == null) { return; } if (e.ColumnIndex == 5) //Trade { grdResults.Rows[e.RowIndex].Selected = true; //m_frmMain.EnterOrder(symbol); } else if (e.ColumnIndex == 6) //Chart { EnableControls(true, false); grdResults.Cursor = Cursors.WaitCursor; grdResults.Rows[e.RowIndex].Selected = true; ChartSelection selection = GetSelection(symbol); m_frmMain.CreateNewCtlPainel(selection, new Action <CtlPainelChart>(chart => { })); grdResults.Cursor = Cursors.Arrow; EnableControls(true, true); } else if (e.ColumnIndex == 7) //Change the script for this individual alert { TempScript = string.IsNullOrEmpty(oAlert.AlertScript) ? oAlert.AlertName : oAlert.AlertScript; frmScannerScript settings = new frmScannerScript(this) { HeaderText = symbol + " Script" }; var result = settings.ShowDialog(); if (result == DialogResult.Abort) { m_frmMain.OpenURL("http://www.modulusfe.com/TradeScript/TradeScript.pdf", "TradeScript Help"); return; } if (result == DialogResult.OK) { oAlert.AlertScript = TempScript; oAlert.AlertName = string.Empty; DataGridViewImageButtonCell cell = (DataGridViewImageButtonCell)grdResults.Rows[e.RowIndex].Cells["Start"]; if (cell == null) { return; } cell.Checked = false; //Script is running now } }//else if Column Index 7 else if (e.ColumnIndex == 8) //Lock/unlock script to control effects of the "Edit Script" button { } else if (e.ColumnIndex == 9) //Play/pause { DataGridViewImageButtonCell cell = (DataGridViewImageButtonCell)grdResults.Rows[e.RowIndex].Cells[e.ColumnIndex]; if (cell == null) { return; } bool pause = cell.Checked; if (pause) { oAlert.AlertName = oAlert.AlertScript; //Using AlertName as a Tag oAlert.AlertScript = string.Empty; } else { if (!string.IsNullOrEmpty(oAlert.AlertName)) //Play { oAlert.AlertScript = oAlert.AlertName; oAlert.AlertName = string.Empty; } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Creates a notechart from the specified file and the actual charttype /// (i.e. ExpertSingle from Freebird.chart) /// </summary> /// <param name="chartSelection"> /// The information on which particular notechart to use. /// </param> /// <returns> /// A filled out Notechart containing the needed information from the *.chart file /// </returns> public static Notes GenerateNotechartFromChart(ChartSelection chartSelection) { string chartname = chartSelection.difficulty + chartSelection.instrument; StreamReader inputStream = new StreamReader(chartSelection.chartPath); string inputString = inputStream.ReadToEnd(); // Single out the specified section via regular expressions string pattern = Regex.Escape("[") + chartname + "]\\s*" + Regex.Escape("{") + "[^}]*"; Match matched_section = Regex.Match(inputString, pattern); // Create the stream from the singled out section of the input string StringReader pattern_stream = new StringReader(matched_section.ToString()); string current_line = ""; string[] parsed_line; // Create the resulting notechart and prep for input Notes notechartToReturn = new Notes(chartSelection.difficulty, chartSelection.instrument); //If specific notechart is not found, return a generic one if (!(matched_section.Success)) { notechartToReturn.notes.Add(new Note()); } // Else, read in all the chart information else { int i = 0; while ((current_line = pattern_stream.ReadLine()) != null) { // Trim and split the line to retrieve information current_line = current_line.Trim(); parsed_line = current_line.Split(' '); // If a valid note is found, add it to the list if (parsed_line.Length == 5) { if (parsed_line[2] == "N") { if ((notechartToReturn.notes.Count > 0) && (Convert.ToUInt32(parsed_line[0]) == notechartToReturn.notes[notechartToReturn.notes.Count - 1].tickValue)) { switch (Convert.ToInt32(parsed_line[3])) { case 0: notechartToReturn.notes[notechartToReturn.notes.Count - 1].addNote(0); break; case 1: notechartToReturn.notes[notechartToReturn.notes.Count - 1].addNote(1); break; case 2: notechartToReturn.notes[notechartToReturn.notes.Count - 1].addNote(2); break; case 3: notechartToReturn.notes[notechartToReturn.notes.Count - 1].addNote(3); break; case 4: notechartToReturn.notes[notechartToReturn.notes.Count - 1].addNote(4); break; default: Console.WriteLine("ERROR: Invalid Note Detcted. Skipping..."); break; } } else { // Find out which note the current line is, and add it to the respective list switch (Convert.ToInt32(parsed_line[3])) { case 0: notechartToReturn.notes.Add(new Note(Convert.ToUInt32(parsed_line[0]), Convert.ToInt32(parsed_line[4]), 0)); break; case 1: notechartToReturn.notes.Add(new Note(Convert.ToUInt32(parsed_line[0]), Convert.ToInt32(parsed_line[4]), 1)); break; case 2: notechartToReturn.notes.Add(new Note(Convert.ToUInt32(parsed_line[0]), Convert.ToInt32(parsed_line[4]), 2)); break; case 3: notechartToReturn.notes.Add(new Note(Convert.ToUInt32(parsed_line[0]), Convert.ToInt32(parsed_line[4]), 3)); break; case 4: notechartToReturn.notes.Add(new Note(Convert.ToUInt32(parsed_line[0]), Convert.ToInt32(parsed_line[4]), 4)); break; default: Console.WriteLine("ERROR: Invalid Note Detcted. Skipping..."); break; } } } // Also check for SP notes else if (parsed_line[2] == "S") { notechartToReturn.SPNotes.Add(new Note(Convert.ToUInt32(parsed_line[0]), Convert.ToInt32(parsed_line[4]), 5)); } } i++; } } // Close the string stream pattern_stream.Close(); return(notechartToReturn); }
/// <summary> /// Creates a notechart from the specified midi path and the actual charttype /// (i.e. ExpertSingle from notes.mid). Due to the overhead necessary to /// parse a midi file. I am going to cram all midi->chart operations into /// one function call. /// This function uses the Sanford midi parser. While it is horribly slow /// on larger (e.g. RB) midis, it works without a hitch on every midi I've /// come across. /// </summary> /// <param name="chartSelection"> /// The information on which particular notechart to use. /// </param> /// <param name="chartInfo">The metadata on the chart.</param> /// <param name="BPMChanges">The list of BPM changes for this chart.</param> /// <returns> /// A filled out Notechart containing the needed information from the *.mid file. /// </returns> public static Notes ParseMidiInformationSanford(ChartSelection chartSelection, Info chartInfo, List <BPMChange> BPMChanges) { Notes notechartToReturn = new Notes(); notechartToReturn.instrument = chartSelection.instrument; notechartToReturn.difficulty = chartSelection.difficulty; // The following two switch's are used to get the proper midi terminology for // the selected track and difficulty. string instrumentPart = null; int greenKey = 0; int redKey = 0; int yellowKey = 0; int blueKey = 0; int orangeKey = 0; switch (chartSelection.instrument) { case "Single": instrumentPart = "PART GUITAR"; break; case "DoubleGuitar": instrumentPart = "PART GUITAR COOP"; break; case "DoubleBass": instrumentPart = "PART BASS"; break; case "Drums": instrumentPart = "PART DRUMS"; break; default: instrumentPart = "PART GUITAR"; break; } switch (chartSelection.difficulty) { case "Expert": greenKey = 96; redKey = 97; yellowKey = 98; blueKey = 99; orangeKey = 100; break; case "Hard": greenKey = 84; redKey = 85; yellowKey = 86; blueKey = 87; orangeKey = 88; break; case "Medium": greenKey = 72; redKey = 73; yellowKey = 74; blueKey = 75; orangeKey = 76; break; case "Easy": greenKey = 60; redKey = 61; yellowKey = 62; blueKey = 63; orangeKey = 64; break; default: greenKey = 96; redKey = 97; yellowKey = 98; blueKey = 99; orangeKey = 100; break; } Sequence mySequence = new Sequence(chartSelection.directory + "\\notes.mid"); Track trackToUse = new Track(); chartInfo.resolution = mySequence.Division; // Go through each event in the first track (which contains the BPM changes) // and parse the resulting string. Track sanTrack = mySequence[0]; foreach (Sanford.Multimedia.Midi.MidiEvent currEvent in sanTrack.Iterator()) { if (currEvent.MidiMessage.MessageType == MessageType.Meta) { MetaMessage currMessage = currEvent.MidiMessage as MetaMessage; //currTickValue += Convert.ToUInt32(splitEventString[1]); if (currMessage.MetaType == MetaType.Tempo) { TempoChangeBuilder tempoBuilder = new TempoChangeBuilder(currMessage); int midiBPMChange = tempoBuilder.Tempo; // In midi files, bpm chages are stored as "microseconds per quarter note" // and must be converted to BPM, and then into the non decimal format the game // uses. double currBPMDouble = 60000000 / (double)midiBPMChange; uint BPMToAdd = (uint)(currBPMDouble * 1000); BPMChanges.Add(new BPMChange((uint)currEvent.AbsoluteTicks, (uint)BPMToAdd)); } } } // Find the specified instrument's track for (int i = 1; i < mySequence.Count; i++) { sanTrack = mySequence[i]; Sanford.Multimedia.Midi.MidiEvent currEvent = sanTrack.GetMidiEvent(0); if (currEvent.MidiMessage.MessageType == MessageType.Meta) { MetaMessage currMessage = currEvent.MidiMessage as MetaMessage; if (currMessage.MetaType == MetaType.TrackName) { MetaTextBuilder trackName = new MetaTextBuilder(currMessage); // -If we come across a "T1 GEMS" track, we're in GH1 territory. // -GH2/FoF has both PART BASS and PART RHYTHM (one or the other depending // on the chart). if ((trackName.Text == instrumentPart) || (trackName.Text == "T1 GEMS") || ((trackName.Text == "PART RHYTHM") && (instrumentPart == "PART BASS"))) { trackToUse = sanTrack; } } } } Note currNote = new Note(); bool blankNote = true; // Scan through and record every note specific to the selected difficulty foreach (Sanford.Multimedia.Midi.MidiEvent currEvent in trackToUse.Iterator()) { // We need to specify wether a note is blank or not so we don't add // blank notes from other difficulties into the chart, but if we have // a filled out note, any nonzero tick value means we are moving to a // new note, so we must cut our ties and add this note to the chart. if ((currEvent.DeltaTicks != 0) && !blankNote) { notechartToReturn.notes.Add(currNote); currNote = new Note(); blankNote = true; } if (currEvent.MidiMessage.MessageType == MessageType.Channel) { ChannelMessage currMessage = currEvent.MidiMessage as ChannelMessage; if (currMessage.Command == ChannelCommand.NoteOn) { // Only consider notes within the octave our difficulty is in. if (((currMessage.Data1 == greenKey) || (currMessage.Data1 == redKey) || (currMessage.Data1 == yellowKey) || (currMessage.Data1 == blueKey) || (currMessage.Data1 == orangeKey)) && (currMessage.Data2 != 0)) { // If it's a new note, we need to setup the tick value of it. if (blankNote) { //currNote.TickValue = totalTickValue; currNote.tickValue = (uint)currEvent.AbsoluteTicks; blankNote = false; } if (currMessage.Data1 == greenKey) { currNote.addNote(0); } else if (currMessage.Data1 == redKey) { currNote.addNote(1); } else if (currMessage.Data1 == yellowKey) { currNote.addNote(2); } else if (currMessage.Data1 == blueKey) { currNote.addNote(3); } else if (currMessage.Data1 == orangeKey) { currNote.addNote(4); } } } } } return(notechartToReturn); }
/// <summary> /// Creates a notechart from the specified midi path and the actual charttype /// (i.e. ExpertSingle from notes.mid). Due to the overhead necessary to /// parse a midi file. I am going to cram all midi->chart operations into /// one function call. /// This function uses the Toub midi parser which is much faster than Sanford, /// but will throw an exception on certian midi files. /// </summary> /// <param name="chartSelection"> /// The information on which particular notechart to use. /// </param> /// <param name="chartInfo">The metadata on the chart.</param> /// <param name="BPMChanges">The list of BPM changes for this chart.</param> /// <returns> /// A filled out Notechart containing the needed information from the *.mid file. /// </returns> public static Notes ParseMidiInformationToub(ChartSelection chartSelection, Info chartInfo, List<BPMChange> BPMChanges) { Notes notechartToReturn = new Notes(); notechartToReturn.instrument = chartSelection.instrument; notechartToReturn.difficulty = chartSelection.difficulty; // The following two switch's are used to get the proper midi terminology for // the selected track and difficulty. string instrumentPart = null; string greenKey = null; string redKey = null; string yellowKey = null; string blueKey = null; string orangeKey = null; switch (chartSelection.instrument) { case "Single": instrumentPart = "PART GUITAR"; break; case "DoubleGuitar": instrumentPart = "PART GUITAR COOP"; break; case "DoubleBass": instrumentPart = "PART BASS"; break; case "Drums": instrumentPart = "PART DRUMS"; break; default: instrumentPart = "PART GUITAR"; break; } switch (chartSelection.difficulty) { case "Expert": greenKey = "C8"; redKey = "C#8"; yellowKey = "D8"; blueKey = "D#8"; orangeKey = "E8"; break; case "Hard": greenKey = "C7"; redKey = "C#7"; yellowKey = "D7"; blueKey = "D#7"; orangeKey = "E7"; break; case "Medium": greenKey = "C6"; redKey = "C#6"; yellowKey = "D6"; blueKey = "D#6"; orangeKey = "E6"; break; case "Easy": greenKey = "C5"; redKey = "C#5"; yellowKey = "D5"; blueKey = "D#5"; orangeKey = "E5"; break; default: greenKey = "C8"; redKey = "C#8"; yellowKey = "D8"; blueKey = "D#8"; orangeKey = "E8"; break; } MidiSequence mySequence = MidiSequence.Import(chartSelection.directory + "\\notes.mid"); MidiTrack[] myTracks = mySequence.GetTracks(); chartInfo.resolution = mySequence.Division; MidiTrack trackToUse = new MidiTrack(); uint totalTickValue = 0; // Go through each event in the first track (which contains the BPM changes) // and parse the resulting string. for (int i = 0; i < myTracks[0].Events.Count; i++) { Toub.Sound.Midi.MidiEvent currEvent = myTracks[0].Events[i]; string eventString = currEvent.ToString(); string[] splitEventString = eventString.Split('\t'); // Since ticks are stored relative to each other (e.g. 300 ticks // until next note), we must maintain the total tick amout. totalTickValue += Convert.ToUInt32(splitEventString[1]); if (splitEventString[0] == "Tempo") { // In midi files, bpm chages are stored as "microseconds per quarter note" // and must be converted to BPM, and then into the non decimal format the game // uses. double currBPMDouble = 60000000 / Convert.ToDouble(splitEventString[3]); uint BPMToAdd = (uint)(currBPMDouble * 1000); BPMChanges.Add(new BPMChange(totalTickValue, BPMToAdd)); } } trackToUse = new MidiTrack(); // Find the specified instrument's track foreach (MidiTrack currTrack in myTracks) { string trackHeader = currTrack.Events[0].ToString(); string[] splitHeader = trackHeader.Split('\t'); // -If we come across a "T1 GEMS" track, we're in GH1 territory. // -GH2/FoF has both PART BASS and PART RHYTHM (one or the other depending // on the chart). if (((splitHeader[3] == instrumentPart) || (splitHeader[3] == "T1 GEMS")) || ((splitHeader[3] == "PART RHYTHM") && (instrumentPart == "PART BASS"))) { trackToUse = currTrack; } } totalTickValue = 0; uint currTickValue = 0; Note currNote = new Note(); bool blankNote = true; // Scan through and record every note specific to the selected difficulty for (int i = 0; i < trackToUse.Events.Count; i++) { string currEvent = trackToUse.Events[i].ToString(); string[] splitEvent = currEvent.Split('\t'); currTickValue = Convert.ToUInt32(splitEvent[1]); totalTickValue += currTickValue; // We need to specify wether a note is blank or not so we don't add // blank notes from other difficulties into the chart, but if we have // a filled out note, any nonzero tick value means we are moving to a // new note, so we must cut our ties and add this note to the chart. if ((currTickValue != 0) && !blankNote) { notechartToReturn.notes.Add(currNote); currNote = new Note(); blankNote = true; } // The "0x64" I think means "not was hit." There is another // set of notes that use "0x00" that all appear slightly after // the "0x64" notes. if ((splitEvent[0] == "NoteOn") && (splitEvent[4] != "0x00")) { // Only consider notes within the octave our difficulty is in. if ((splitEvent[3] == greenKey) || (splitEvent[3] == redKey) || (splitEvent[3] == yellowKey) || (splitEvent[3] == blueKey) || (splitEvent[3] == orangeKey)) { // If it's a new note, we need to setup the tick value of it. if (blankNote) { currNote.tickValue = totalTickValue; blankNote = false; } if (splitEvent[3] == greenKey) { currNote.addNote(0); } else if (splitEvent[3] == redKey) { currNote.addNote(1); } else if (splitEvent[3] == yellowKey) { currNote.addNote(2); } else if (splitEvent[3] == blueKey) { currNote.addNote(3); } else if (splitEvent[3] == orangeKey) { currNote.addNote(4); } } } } return notechartToReturn; }
/// <summary> /// Creates a notechart from the specified midi path and the actual charttype /// (i.e. ExpertSingle from notes.mid). Due to the overhead necessary to /// parse a midi file. I am going to cram all midi->chart operations into /// one function call. /// This function uses the Sanford midi parser. While it is horribly slow /// on larger (e.g. RB) midis, it works without a hitch on every midi I've /// come across. /// </summary> /// <param name="chartSelection"> /// The information on which particular notechart to use. /// </param> /// <param name="chartInfo">The metadata on the chart.</param> /// <param name="BPMChanges">The list of BPM changes for this chart.</param> /// <returns> /// A filled out Notechart containing the needed information from the *.mid file. /// </returns> public static Notes ParseMidiInformationSanford(ChartSelection chartSelection, Info chartInfo, List<BPMChange> BPMChanges) { Notes notechartToReturn = new Notes(); notechartToReturn.instrument = chartSelection.instrument; notechartToReturn.difficulty = chartSelection.difficulty; // The following two switch's are used to get the proper midi terminology for // the selected track and difficulty. string instrumentPart = null; int greenKey = 0; int redKey = 0; int yellowKey = 0; int blueKey = 0; int orangeKey = 0; switch (chartSelection.instrument) { case "Single": instrumentPart = "PART GUITAR"; break; case "DoubleGuitar": instrumentPart = "PART GUITAR COOP"; break; case "DoubleBass": instrumentPart = "PART BASS"; break; case "Drums": instrumentPart = "PART DRUMS"; break; default: instrumentPart = "PART GUITAR"; break; } switch (chartSelection.difficulty) { case "Expert": greenKey = 96; redKey = 97; yellowKey = 98; blueKey = 99; orangeKey = 100; break; case "Hard": greenKey = 84; redKey = 85; yellowKey = 86; blueKey = 87; orangeKey = 88; break; case "Medium": greenKey = 72; redKey = 73; yellowKey = 74; blueKey = 75; orangeKey = 76; break; case "Easy": greenKey = 60; redKey = 61; yellowKey = 62; blueKey = 63; orangeKey = 64; break; default: greenKey = 96; redKey = 97; yellowKey = 98; blueKey = 99; orangeKey = 100; break; } Sequence mySequence = new Sequence(chartSelection.directory + "\\notes.mid"); Track trackToUse = new Track(); chartInfo.resolution = mySequence.Division; // Go through each event in the first track (which contains the BPM changes) // and parse the resulting string. Track sanTrack = mySequence[0]; foreach (Sanford.Multimedia.Midi.MidiEvent currEvent in sanTrack.Iterator()) { if (currEvent.MidiMessage.MessageType == MessageType.Meta) { MetaMessage currMessage = currEvent.MidiMessage as MetaMessage; //currTickValue += Convert.ToUInt32(splitEventString[1]); if (currMessage.MetaType == MetaType.Tempo) { TempoChangeBuilder tempoBuilder = new TempoChangeBuilder(currMessage); int midiBPMChange = tempoBuilder.Tempo; // In midi files, bpm chages are stored as "microseconds per quarter note" // and must be converted to BPM, and then into the non decimal format the game // uses. double currBPMDouble = 60000000 / (double)midiBPMChange; uint BPMToAdd = (uint)(currBPMDouble * 1000); BPMChanges.Add(new BPMChange((uint)currEvent.AbsoluteTicks, (uint)BPMToAdd)); } } } // Find the specified instrument's track for (int i = 1; i < mySequence.Count; i++) { sanTrack = mySequence[i]; Sanford.Multimedia.Midi.MidiEvent currEvent = sanTrack.GetMidiEvent(0); if (currEvent.MidiMessage.MessageType == MessageType.Meta) { MetaMessage currMessage = currEvent.MidiMessage as MetaMessage; if (currMessage.MetaType == MetaType.TrackName) { MetaTextBuilder trackName = new MetaTextBuilder(currMessage); // -If we come across a "T1 GEMS" track, we're in GH1 territory. // -GH2/FoF has both PART BASS and PART RHYTHM (one or the other depending // on the chart). if ((trackName.Text == instrumentPart) || (trackName.Text == "T1 GEMS") || ((trackName.Text == "PART RHYTHM") && (instrumentPart == "PART BASS"))) { trackToUse = sanTrack; } } } } Note currNote = new Note(); bool blankNote = true; // Scan through and record every note specific to the selected difficulty foreach (Sanford.Multimedia.Midi.MidiEvent currEvent in trackToUse.Iterator()) { // We need to specify wether a note is blank or not so we don't add // blank notes from other difficulties into the chart, but if we have // a filled out note, any nonzero tick value means we are moving to a // new note, so we must cut our ties and add this note to the chart. if ((currEvent.DeltaTicks != 0) && !blankNote) { notechartToReturn.notes.Add(currNote); currNote = new Note(); blankNote = true; } if (currEvent.MidiMessage.MessageType == MessageType.Channel) { ChannelMessage currMessage = currEvent.MidiMessage as ChannelMessage; if (currMessage.Command == ChannelCommand.NoteOn) { // Only consider notes within the octave our difficulty is in. if (((currMessage.Data1 == greenKey) || (currMessage.Data1 == redKey) || (currMessage.Data1 == yellowKey) || (currMessage.Data1 == blueKey) || (currMessage.Data1 == orangeKey)) && (currMessage.Data2 != 0)) { // If it's a new note, we need to setup the tick value of it. if (blankNote) { //currNote.TickValue = totalTickValue; currNote.tickValue = (uint)currEvent.AbsoluteTicks; blankNote = false; } if (currMessage.Data1 == greenKey) { currNote.addNote(0); } else if (currMessage.Data1 == redKey) { currNote.addNote(1); } else if (currMessage.Data1 == yellowKey) { currNote.addNote(2); } else if (currMessage.Data1 == blueKey) { currNote.addNote(3); } else if (currMessage.Data1 == orangeKey) { currNote.addNote(4); } } } } } return notechartToReturn; }
private void ViewChart(string symbol) { if (_parentControl.MFrmMain.m_DockManager.DocumentManager.ActiveDocument != null) { if (_parentControl.MFrmMain.m_DockManager.DocumentManager.ActiveDocument.Client.Name == "CtlPainelChart") { MessageService.SubmitRequest(new MSRequest("m" + _parentControl.MFrmMain._messageRequestID, MSRequestStatus.Pending, MSRequestType.GetHistoricalData, MSRequestOwner.M4, new object[] { symbol, BaseType.Days.GetHashCode() })); _parentControl.MFrmMain.AddRequestedOperation( new Operations("m" + _parentControl.MFrmMain._messageRequestID, TypeOperations.LoadCtlPainelChart, new object[] { _parentControl.MFrmMain.m_DockManager.DocumentManager.ActiveDocument.ID, symbol, _parentControl.MFrmMain.MActiveChart.m_Periodicity, _parentControl.MFrmMain.MActiveChart.m_BarSize, _parentControl.MFrmMain.MActiveChart.m_Bars, _parentControl.MFrmMain.MActiveChart._source })); //Check if there's file with data first: /*string path = Directory.GetCurrentDirectory() + "\\Base\\"; * if ((_parentControl.MFrmMain.MActiveChart.m_Periodicity == Periodicity.Minutely) || (_parentControl.MFrmMain.MActiveChart.m_Periodicity == Periodicity.Hourly)) * path += "MINUTE\\" + _parentControl.MFrmMain.MActiveChart.MSymbol + ".csv"; * else * path += "DAILY\\" + _parentControl.MFrmMain.MActiveChart.MSymbol + ".csv"; * if (!File.Exists(path)) * { * MessageBox.Show(Program.LanguageDefault.DictionaryMessage["msgInvalidPeriodicity"] + _parentControl.MFrmMain.MActiveChart.MSymbol); * return; * } * _parentControl.MFrmMain.MActiveChart.m_StopLoadScroll = true; * * _parentControl.MFrmMain.MActiveChart.StockChartX1.SaveGeneralTemplate(ListTemplates._path + "TempTemplate" + ".sct"); * * _parentControl.MFrmMain.MActiveChart._source = _parentControl.MFrmMain.MActiveChart._mListSymbols.Where(r => r.Code.Equals(symbol)).Single().Source; * _parentControl.MFrmMain.MActiveChart.LoadChart(_parentControl.MFrmMain.MActiveChart.MSymbol); * * _parentControl.MFrmMain.MActiveChart.InitRTChartAsync(b => _parentControl.MFrmMain.MActiveChart._asyncOp.Post(() => * { * if (b) * { * _parentControl.MFrmMain.MActiveChart.BindContextMenuEvents(); * return; * } * * return; * })); * * _parentControl.MFrmMain.m_DockManager.DocumentManager.ActiveDocument.Text = _parentControl.MFrmMain.MActiveChart.GetChartTitle(); * _parentControl.MFrmMain.MActiveChart.StockChartX1.Update(); * * if (_parentControl.MFrmMain.MActiveChart.m_EndJDate != NULL_VALUE) * { * _parentControl.MFrmMain.MActiveChart.StockChartX1.FirstVisibleRecord = _parentControl.MFrmMain.MActiveChart.StockChartX1.GetRecordByJDate(_parentControl.MFrmMain.MActiveChart.m_EndJDate) - _parentControl.MFrmMain.MActiveChart.m_QtyJDate; * _parentControl.MFrmMain.MActiveChart.StockChartX1.LastVisibleRecord = _parentControl.MFrmMain.MActiveChart.StockChartX1.GetRecordByJDate(_parentControl.MFrmMain.MActiveChart.m_EndJDate); * } * _parentControl.MFrmMain.MActiveChart.LoadScroll();*/ return; } } ChartSelection selection = (new FrmSelectChart { CodeStock = symbol }).GetChartSelection(symbol); if (selection == null) { return; } MessageService.SubmitRequest(new MSRequest("m" + _parentControl.MFrmMain._messageRequestID, MSRequestStatus.Pending, MSRequestType.GetHistoricalData, MSRequestOwner.M4, new object[] { selection.Symbol, BaseType.Days.GetHashCode() })); _parentControl.MFrmMain.AddRequestedOperation( new Operations("m" + _parentControl.MFrmMain._messageRequestID, TypeOperations.CreateNewCtlPainelChart, new object[] { selection })); // _parentControl.MFrmMain.CreateNewCtlPainel(selection); }
//Starts alerts public bool StartAlerts() { Periodicity periodicity; ChartSelection selection = new ChartSelection(); if (!VerifyForm()) { return(false); } if (!TestScripts()) { return(false); } if (m_ctlData == null) { return(false); } cmdEnable.Text = "&Disable Alerts"; cmdEnable.Border.BaseColor = Color.Red; EnableControls(false); cmdEnable.Border.Update(); switch (cboPeriodicity.Text) { case "Minute": periodicity = Periodicity.Minutely; break; case "Hour": periodicity = Periodicity.Hourly; break; case "Day": periodicity = Periodicity.Daily; break; case "Week": periodicity = Periodicity.Weekly; break; default: periodicity = Periodicity.Minutely; break; } cmdEnable.Enabled = false; selection.Periodicity = periodicity; selection.Symbol = txtSymbol.Text; try { selection.Interval = (int)Math.Round(Convert.ToDouble(txtInterval.Text)); } catch { } try{ selection.Bars = (int)Math.Round(Convert.ToDouble(txtBars.Text)); } catch { } m_chart = m_ctlData.GetChart(selection, false); if (m_chart == null) { return(false); //Failed to get the chart } DataManager.BarData[] bars = m_chart.GetDataFromChart(); if (bars.Length < 1) { return(false); } m_chart.Subscribers++; //Increment (deincremented in frmMain UI unload) cmdEnable.Enabled = true; //Get historic data and subscribe to realtime updates if (bars.Length < 3) { return(false); //Bad request } //Insert the data into all four instances of TradeScript oBuyAlert.AlertScript = ""; oSellAlert.AlertScript = ""; oExitLongAlert.AlertScript = ""; oExitShortAlert.AlertScript = ""; oBuyAlert.ClearRecords(); oSellAlert.ClearRecords(); oExitLongAlert.ClearRecords(); oExitShortAlert.ClearRecords(); for (int n = 0; n <= bars.Length - 1; n++) { DateTime td = bars[n].TradeDate; double jdate = oBuyAlert.ToJulianDate(td.Year, td.Month, td.Day, td.Hour, td.Minute, td.Second, 0); oBuyAlert.AppendHistoryRecord(jdate, bars[n].OpenPrice, bars[n].HighPrice, bars[n].LowPrice, bars[n].ClosePrice, (int)Math.Round(bars[n].Volume)); oSellAlert.AppendHistoryRecord(jdate, bars[n].OpenPrice, bars[n].HighPrice, bars[n].LowPrice, bars[n].ClosePrice, (int)Math.Round(bars[n].Volume)); oExitLongAlert.AppendHistoryRecord(jdate, bars[n].OpenPrice, bars[n].HighPrice, bars[n].LowPrice, bars[n].ClosePrice, (int)Math.Round(bars[n].Volume)); oExitShortAlert.AppendHistoryRecord(jdate, bars[n].OpenPrice, bars[n].HighPrice, bars[n].LowPrice, bars[n].ClosePrice, (int)Math.Round(bars[n].Volume)); } //Now that the history has been added, turn the scripts on oBuyAlert.AlertName = "Buy Script"; oBuyAlert.AlertScript = txtBuyScript.Text; oSellAlert.AlertName = "Sell Script"; oSellAlert.AlertScript = txtSellScript.Text; oExitLongAlert.AlertName = "Exit Long Script"; oExitLongAlert.AlertScript = txtExitLongScript.Text; oExitShortAlert.AlertName = "Exit Short Script"; oExitShortAlert.AlertScript = txtExitShortScript.Text; //Start the data poll timer tmrUpdate.Enabled = true; return(true); }