παπι Δημοσ. 1 Οκτωβρίου 2012 Δημοσ. 1 Οκτωβρίου 2012 Λοιπον, επειδη δεν μπορω να εξηγησω με λογια καποιες απο τις αποριες μου θα τις ζωγραφισω. Ολα εχουν να κανουν με IT/chart γυρο απο stock data. Το σχημα της βασης Το table που με απασχολει ειναι το intraday που ειναι τεραστιο μια μερα ειναι 30-60κ records. Ως ασχετος απο βασεις, στην αρχη εβαλα συνθετο κλειδι id_name & ts(datetime) αλλα δυστυχος ειχα συγκρουσεις.. απο google ειδα οτι δεν συμβαδιζουν τα ms του datetime της C# με αυτο της sqlite και ετσι εβαλα ενα id για να μην ασχοληθω αλλο, ελα ομως που το βαρος των select το εχει το ts με αποτελεσμα να θελω 1 sec για ενα δεικτη και 10 για 10. Η πρωτη απορια ειναι πως θα αλλαξω το σχημα ωστε να ειναι πιο γρηγορο. Η δευτερη απορια μου εχει να κανει με.. να παρω τα δεδομενα με ενα συγκεκριμενο τροπο για να φτιαξω ενα κερι (candlestick chart) ενα κερι θελει 4 νουμερακια open close high low αυτα τα 4 νουμερακια πρεπει να τα παρω απο μια σειρα πραξεων (trade) σε Ν χρονο (οπου Ν 1 λεπτο ή 5 ή μερα κλπ) Και τωρα ζωγραφιζω. ουσιαστικα θελω να τα παρω απο την βαση ως groups που το καθε group θα εχει τις πρεαξεις μιας ωρας (ή καποια αλλη περιοδο). Βεβαια θα ηθελα να παρω απο καθε group το max(ts) min(ts) max(price) min(price) Ολα αυτα σε linq.
MitsakosGR Δημοσ. 2 Οκτωβρίου 2012 Δημοσ. 2 Οκτωβρίου 2012 Για την απορία #1. Φτιάξε Index στο column που θες να επιταχύνεις την αναζήτηση. Δες εδώ. Για την #2 δεν γνωρίζω... :s Λογικά με διαφορετικό Index στην date θα επιταχύνεις την αναζήτηση. Για το Linq δεν έχω ασχοληθεί ιδιαίτερα οπότε δεν γνωρίζω... Απορία: Γιατί να το κάνεις με Linq και δεν χρησιμοποιείς SQL κατευθείαν πάνω στη βάση; Για τόσα πολλά δεδομένα πιστεύω ότι η βάση θα είναι πολύ πιο γρήγορη απο Linq... 1
παπι Δημοσ. 2 Οκτωβρίου 2012 Μέλος Δημοσ. 2 Οκτωβρίου 2012 ου λαλα! ΤΕΡΑΤΩΔΕΣ* διαφορα με το index να΄σε καλα *υπερθετικος του τεραστια, δεν θυμαμαι ποιος ειναι χεχε
MitsakosGR Δημοσ. 2 Οκτωβρίου 2012 Δημοσ. 2 Οκτωβρίου 2012 ου λαλα! ΤΕΡΑΤΩΔΕΣ* διαφορα με το index να΄σε καλα *υπερθετικος του τεραστια, δεν θυμαμαι ποιος ειναι χεχε Τεραστιατότατη....
defacer Δημοσ. 2 Οκτωβρίου 2012 Δημοσ. 2 Οκτωβρίου 2012 @παπί: Where() για το φιλτράρισμα, GroupBy() για το ξεχώρισμα σε γκρουπάκια και μετά Select() ό,τι θέλεις. Το μόνο που μπορεί να προβληματίσει είναι το GroupBy γιατί εκεί θα χρειαστεί να βγάλεις από το TS κάποια δεδομένα (π.χ. isolate την ώρα αν θέλεις να πάρεις στατιστικά ανα ώρα). Εκεί θα πρέπει να γράψεις το query χρησιμοποιώντας functions που να καταλαβαίνει ο LINQ provider που χρησιμοποιείς -- ποιός είναι; Κάτι λες για sqlite -- DBLinq? Απορία: Γιατί να το κάνεις με Linq και δεν χρησιμοποιείς SQL κατευθείαν πάνω στη βάση; Για τόσα πολλά δεδομένα πιστεύω ότι η βάση θα είναι πολύ πιο γρήγορη απο Linq... LINQ = query κατευθείαν πάνω στη βάση εκτός κι αν κάνεις κάτι πολύ λάθος.
Latency Δημοσ. 2 Οκτωβρίου 2012 Δημοσ. 2 Οκτωβρίου 2012 @παπί: Where() για το φιλτράρισμα, GroupBy() για το ξεχώρισμα σε γκρουπάκια και μετά Select() ό,τι θέλεις. Το μόνο που μπορεί να προβληματίσει είναι το GroupBy γιατί εκεί θα χρειαστεί να βγάλεις από το TS κάποια δεδομένα (π.χ. isolate την ώρα αν θέλεις να πάρεις στατιστικά ανα ώρα). Εκεί θα πρέπει να γράψεις το query χρησιμοποιώντας functions που να καταλαβαίνει ο LINQ provider που χρησιμοποιείς -- ποιός είναι; Κάτι λες για sqlite -- DBLinq? LINQ = query κατευθείαν πάνω στη βάση εκτός κι αν κάνεις κάτι πολύ λάθος. //Αγγρε, έχεις απόλυτο δίκαιο @παπι, κάνε αυτό που είναι ο από πάνω.
παπι Δημοσ. 2 Οκτωβρίου 2012 Μέλος Δημοσ. 2 Οκτωβρίου 2012 > private void ShowChart() { if (string.IsNullOrEmpty(SelectedSymbol)) return; try { using (var db = new Xaa.Ado.DBEntities(FormXAA.DBConnectiongString)) { var nameid = db.Names .Where(x => x.namegr == SelectedSymbol) .Take(1) .First(); var intraday = db.Intraday .Where(x => x.id_name == nameid.id) .OrderBy(x => x.ts); var min = intraday.Min(x => x.price); var max = intraday.Max(x => x.price); this.chart.Series.Clear(); var priceSeries = this.chart.Series.Add(SelectedSymbol); priceSeries.IsXValueIndexed = true; //todo design chart.ChartAreas[0].AxisX.LabelStyle.Format = "hh:mm"; chart.ChartAreas[0].AxisX.Interval = 1; chart.ChartAreas[0].AxisX.IntervalType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Minutes; chart.ChartAreas[0].AxisY.LabelStyle.Format = "C3"; chart.ChartAreas[0].CursorX.IsUserEnabled = true; chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true; chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true; chart.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true; chart.ChartAreas[0].AxisX.IsLabelAutoFit = true; chart.ChartAreas[0].AxisY.Maximum = max + ((max - min) / 10.0); chart.ChartAreas[0].AxisY.Minimum = min - ((max - min) / 10.0); //main chart (price/date) //line if (priceChartType == Xaa_01.PriceChartType.Line) { priceSeries.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; priceSeries.IsXValueIndexed = true; priceSeries.Points.DataBind(intraday, "ts", "price", ""); } //candlestick else if (priceChartType == Xaa_01.PriceChartType.Candlestick) { priceSeries.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Candlestick; var hloc = from obj in intraday group obj by obj.ts.Minute into groups select new { O= groups.First().price, C= groups.Last().price, H= groups.Max( x => x.price), L= groups.Min( x => x.price), Ts = groups.Last().ts }; chart.ChartAreas[0].AxisX.ScaleView.Size = 30; priceSeries.BorderWidth = 2; priceSeries.Points.DataBind(hloc, "Ts", "H,L,O,C", ""); chart.ChartAreas[0].AxisX.ScaleView.Scroll(System.Windows.Forms.DataVisualization.Charting.ScrollType.Last); } } } catch (Exception ex)//ingore ALL fucking errors { Log.CreateLog(ex); } } > else if (priceChartType == Xaa_01.PriceChartType.Candlestick) { priceSeries.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Candlestick; var hloc = from obj in intraday group obj by obj.ts.Minute into groups select new { O= groups.First().price, C= groups.Last().price, H= groups.Max( x => x.price), L= groups.Min( x => x.price), Ts = groups.Last().ts }; chart.ChartAreas[0].AxisX.ScaleView.Size = 30; priceSeries.BorderWidth = 2; priceSeries.Points.DataBind(hloc, "Ts", "H,L,O,C", ""); Με λεει οτι το first μπορω να το χρησιμοποιησω μονο στο τελικο ερωτημα....... The method 'First' can only be used as a final query operation. Consider using the method 'FirstOrDefault' in this instance instead.
defacer Δημοσ. 2 Οκτωβρίου 2012 Δημοσ. 2 Οκτωβρίου 2012 Σκέψου πώς μεταφράζεται αυτό σε SQL: >SELECT ??? AS O, ??? AS C, MAX(price) AS H, MAX(price) AS L, ??? AS Ts FROM intraday GROUP BY (πάρε κάπως το Minute από το ts) Τι θα μπορούσες να γράψεις στα ερωτηματικά για να δουλέψει? Τίποτα. Οπότε και το αντίστοιχο σε LINQ δεν ισχύει (εδώ το abstraction "γράφε ότι θες" χαλάει, αν ήταν LINQ to objects θα δούλευε φυσικά). Για να παίξει αυτό το query θα έπρεπε να γίνει πολύ πιο περίπλοκο. Ας πούμε για να πάρεις το Ο θα έπρεπε να είναι >SELECT price AS O FROM intraday WHERE id IN (SELECT id FROM intraday GROUP BY (ts.Minute) ORDER BY ts.Minute LIMIT 1) ή αντίστοιχα με JOIN: >SELECT temp1.price AS O FROM intraday LEFT JOIN (SELECT id, price FROM intraday GROUP BY (ts.Minute) ORDER BY ts.Minute LIMIT 1) temp1 ON intraday.id = temp1.id Η τελευταία μορφή δε φαίνεται προτιμότερη αλλά αν εκτός από το O θέλεις να πάρεις και τα C και TS τότε μπορεί να γραφτεί μόνο μ' αυτό τον τρόπο, και συγκεκριμένα προσθέτοντας ένα JOIN για κάθε τιμή που θέλεις να εξάγεις. Το ζουμί εδώ είναι πως το subquery μέσα στο JOIN μπορεί κάλλιστα να μην επιστρέψει κανένα record (άσχετα που στην πράξη ξέρουμε ότι θα επιστρέψει), στην οποία περίπτωση το join condition δε θα κάνει match τίποτα και θα πάρεις null σαν αποτέλεσμα. Και αυτό θα γίνει στην πλευρά της SQL, οπότε μετά όταν περάσουν τα αποτελέσματα στον query provider αυτός δε θα ξέρει τι ακριβώς παίχτηκε και βγήκε null εκεί. Οπότε το LINQ σου λέει ότι φίλε, κοίτα να δεις, θα με βάλεις να κάνω outer join εδώ και πρέπει να ξέρεις ότι το outer join μπορεί να επιστρέψει και κενό resultset, οπότε δε μπορώ να σου εγγυηθώ ότι το .First() θα παίξει. Βάλε .FirstOrDefault() για να δείξεις ότι είσαι ενήμερος και όλα καλά. Οπότε αν απλά βάλεις FirstOrDefault και φροντίσεις και την περίπτωση όπου αυτό θα δώσει null θα πρέπει να παίξει μια χαρά.
παπι Δημοσ. 2 Οκτωβρίου 2012 Μέλος Δημοσ. 2 Οκτωβρίου 2012 Ξεχασα να γραψω οτι ουτε με firstordefault δεν δουλευει. LINQ to Entities does not recognize the method 'Xaa.Ado.Intraday LastOrDefault[intraday](System.Collections.Generic.IEnumerable`1[Xaa.Ado.Intraday])' method, and this method cannot be translated into a store expression. Τεσπα θα κοιταξω καλυτερα αυτα που γραφεις Ουτε αυτο groups.Aggregate((x,y) => x.ts > y.ts ? x : y).price Πωωω... Το εκανα ετσι > else if (priceChartType == Xaa_01.PriceChartType.Candlestick) { priceSeries.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Candlestick; /* var hloc = from obj in intraday group obj by obj.ts.Hour into groups select new { O = groups.Aggregate((x,y) => x.ts > y.ts ? x : y).price, C = groups.Where(x => x.ts == groups.Max(y => y.ts)), H= groups.Max( x => x.price), L= groups.Min( x => x.price), Ts = groups.Max(x=>x.ts) }; */ List<object> hloc1 = new List<object>(); foreach (var item in intraday.GroupBy(x=> x.ts.Minute)) { hloc1.Add( new { O = item.First().price, C = item.Last().price, H = item.Max(x => x.price), L = item.Min(x => x.price), Ts = item.Max(x => x.ts) } ); } chart.ChartAreas[0].AxisX.ScaleView.Size = 30; priceSeries.BorderWidth = 2; priceSeries.Points.DataBind(hloc1, "Ts", "H,L,O,C", ""); chart.ChartAreas[0].AxisX.ScaleView.Scroll(System.Windows.Forms.DataVisualization.Charting.ScrollType.Last); } Ναι μεν δουλευει, αλλα κανει 213421423423423423423423 ωρες το κερατο μου
defacer Δημοσ. 2 Οκτωβρίου 2012 Δημοσ. 2 Οκτωβρίου 2012 Πρέπει να κάνεις OrderBy τα groups και μετά FirstOrDefault -- LastOrDefault δε σου χρειάζεται, απλά γυρνάς το order σε ανάποδο. Επίσης έχε υπόψη ότι δεν έχει νόημα να πεις "από το πρώτο group θέλω την τιμή" γιατί το grouping γίνεται βάσει χρόνου και το πρώτο group έχει ενδεχομένως πολλά records. Κατά τα άλλα επειδή έχω λαλήσει τώρα και γράφω βλακείες (έχω γράψει και παραπάνω μεγάλες) θα επανέλθω Δημήτριος αργότερα.
παπι Δημοσ. 2 Οκτωβρίου 2012 Μέλος Δημοσ. 2 Οκτωβρίου 2012 Εχεις λαλησει; Εγω να δεις αχαχαχαχα. Οκ τωρα που ειμαι πιο χαλαρος. Το εκανα και δουλευει > else if (priceChartType == Xaa_01.PriceChartType.Candlestick) { priceSeries.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Candlestick; var buffer = new List<Xaa.Ado.Intraday>(); DateTime dt = intraday.First().ts; foreach (var item in intraday) { if ((item.ts - dt).TotalSeconds > period.TotalSeconds) { dt = item.ts; priceSeries.Points.AddXY(dt, buffer.Max(x => x.price), buffer.Min(x => x.price), buffer.First().price, buffer.Last().price); buffer.Clear(); } buffer.Add(item); } chart.ChartAreas[0].AxisX.ScaleView.Size = 30; priceSeries.BorderWidth = 2; // priceSeries.Points.DataBind(intraday.hi, "Ts", "High,Low,Open,Close", ""); chart.ChartAreas[0].AxisX.ScaleView.Scroll(System.Windows.Forms.DataVisualization.Charting.ScrollType.Last); } Το καλο απο το προηγουμενο ειναι οτι δεν χρειαζετε να φορτωσω ολα τα δεδομενα στο προγραμμα. Το κακο ειναι οτι πρεπει να περασω ολα τα δεδομενα απο την βαση στο προγραμμα.
Latency Δημοσ. 2 Οκτωβρίου 2012 Δημοσ. 2 Οκτωβρίου 2012 παπί, σε τι φάση είσαι στην ζωή σου, βλέπω το αβαταρ σου και γελάω.
παπι Δημοσ. 10 Οκτωβρίου 2012 Μέλος Δημοσ. 10 Οκτωβρίου 2012 Αρχιζει και κολλαει.. Υπαρχει κανα καλυτερο σχημα για τη βαση; Αν και σεφτομαι να κραταω τα δεδομενα μονο για 5 μερες και τα υπολοιπα να τα κανω hloc του 30/15λεπτου...
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα