コピペ: OmegaChart Fibonacciリトレースメント Fibonacci.cs 新規追加 ※差し替え その3

形式
Plain text
投稿日時
2018-02-10 14:09
公開期間
無期限
  1. using System;
  2. using System.Collections;
  3. using System.Drawing;
  4. using System.Text;
  5. using Zanetti.Data;
  6. using Travis.Storage;
  7. namespace Zanetti.UI
  8. {
  9. /// <summary>
  10. /// Fibonacci の概要の説明です。
  11. /// </summary>
  12. internal class Fibonacci
  13. {
  14. private PointF _pivot;
  15. private PointF _destination;
  16. private int _id; //SolidFibonacciからの作成時のみセット、それ以外は-1
  17. private LineDrawMode _mode;
  18. public enum LineDrawMode
  19. {
  20. Normal,
  21. Hilight
  22. }
  23. public Fibonacci(PointF p)
  24. {
  25. _pivot = p;
  26. _destination = p;
  27. _id = -1;
  28. }
  29. public Fibonacci(PointF p1, PointF p2)
  30. {
  31. _pivot = p1;
  32. _destination = p2;
  33. _id = -1;
  34. }
  35. //リサイズしたときなどの再計算
  36. public Fibonacci(DataFarm farm, int firstdateindex, SolidFibonacci fl, Trans value_to_y)
  37. {
  38. int p = Env.Layout.DatePitch;
  39. _pivot = new PointF((farm.DateToIndex(fl._date1) - firstdateindex) * p + p / 2, (float)value_to_y.TransValue(fl._value1));
  40. _destination = new PointF((farm.DateToIndex(fl._date2) - firstdateindex) * p + p / 2, (float)value_to_y.TransValue(fl._value2));
  41. _id = fl._id;
  42. }
  43. public PointF Pivot
  44. {
  45. get
  46. {
  47. return _pivot;
  48. }
  49. set
  50. {
  51. _pivot = value;
  52. }
  53. }
  54. public PointF Destination
  55. {
  56. get
  57. {
  58. return _destination;
  59. }
  60. set
  61. {
  62. _destination = value;
  63. }
  64. }
  65. public LineDrawMode DrawMode
  66. {
  67. get
  68. {
  69. return _mode;
  70. }
  71. set
  72. {
  73. _mode = value;
  74. }
  75. }
  76. public int ID
  77. {
  78. get
  79. {
  80. return _id;
  81. }
  82. }
  83. public void SetHighPriceAndLowPrice(DataFarm farm, Trans pricetrans, float x1, float x2, int FirstDateIndex)
  84. {
  85. if (x1 > Env.Layout.ChartAreaWidth || x2 > Env.Layout.ChartAreaWidth)
  86. return;
  87. int ind1 = FirstDateIndex + (int)Math.Floor((double)Math.Min(x1, x2) / Env.Layout.DatePitch);
  88. int ind2 = FirstDateIndex + (int)Math.Floor((double)Math.Max(x1, x2) / Env.Layout.DatePitch);
  89. if (ind1 < 0) ind1 = 0;
  90. if (ind2 < 0) ind2 = 0;
  91. if (ind1 >= farm.TotalLength) ind1 = farm.FilledLength - 1;
  92. if (ind2 >= farm.TotalLength) ind2 = farm.FilledLength - 1;
  93. //最高値と最安値の株価
  94. //double range_max = new IndicatorTimeSeries(farm, Env.CurrentIndicators.GetPrimitive(PrimitiveIndicator.High), ind1, ind2).Max;
  95. //double range_min = new IndicatorTimeSeries(farm, Env.CurrentIndicators.GetPrimitive(PrimitiveIndicator.Low), ind1, ind2).Min;
  96. double range_max = Max(farm, ind1, ind2);
  97. double range_min = Min(farm, ind1, ind2);
  98. //最高値と最安値の画面上の位置
  99. double top = pricetrans.TransValue(range_max);
  100. double bot = pricetrans.TransValue(range_min);
  101. _pivot = new PointF(x1, (float)bot);
  102. _destination = new PointF(x2, (float)top);
  103. }
  104. private double Max(DataFarm farm, int ind1, int ind2)
  105. {
  106. var pos = ind1;
  107. var max = double.MinValue;
  108. var last = ind2 > farm.FilledLength ? farm.FilledLength - 1 : ind2;
  109. while (pos <= last)
  110. {
  111. var a = BitConverter.ToInt32(farm.RawDataImage, pos * 32 + 4 * 2) * farm.Brand.PriceScale / (Env.Preference.AdjustSplit ? farm.CalcSplitRatio(BitConverter.ToInt32(farm.RawDataImage, pos * 32)) : 1);
  112. if (max < a) max = a;
  113. pos++;
  114. }
  115. return max;
  116. }
  117. private double Min(DataFarm farm, int ind1, int ind2)
  118. {
  119. var pos = ind1;
  120. var min = double.MaxValue;
  121. var last = ind2 > farm.FilledLength ? farm.FilledLength - 1 : ind2;
  122. while (pos <= last)
  123. {
  124. var a = BitConverter.ToInt32(farm.RawDataImage, pos * 32 + 4 * 3) * farm.Brand.PriceScale / (Env.Preference.AdjustSplit ? farm.CalcSplitRatio(BitConverter.ToInt32(farm.RawDataImage, pos * 32)) : 1);
  125. if (min > a) min = a;
  126. pos++;
  127. }
  128. return min;
  129. }
  130. public Rectangle GetInclusion(Rectangle rect)
  131. {
  132. if (_pivot == _destination)
  133. return new Rectangle(new Point((int)_pivot.X, (int)_pivot.Y), new Size(0, 0));
  134. Point[] es = GetEdge(rect, new Point((int)_pivot.X, (int)_pivot.Y), new Point((int)_destination.X, (int)_destination.Y));
  135. return new Rectangle(Math.Min(es[0].X, es[1].X), Math.Min(es[0].Y, es[1].Y), Math.Abs(es[0].X - es[1].X), Math.Abs(es[0].Y - es[1].Y));
  136. }
  137. //十分に離した位置でないと線を確定させないようにする
  138. public bool PivotHasEnoughDistanceTo(PointF pt)
  139. {
  140. return Math.Abs(_pivot.X - pt.X) > 10 || Math.Abs(_pivot.Y - pt.Y) > 10;
  141. }
  142. public void Draw(Trans pricetrans, Rectangle rect, IntPtr hdc)
  143. {
  144. Win32.POINT pt = new Win32.POINT();
  145. Win32.SelectObject(hdc, _mode == LineDrawMode.Normal ? Env.Preference.FibonacciPen.Handle : Env.Preference.FibonacciBoldPen.Handle);
  146. PointF p1 = _pivot;
  147. PointF p2 = _destination;
  148. var m = Math.Min(p1.X, p2.X);
  149. var l = Math.Max(p1.X, p2.X);
  150. var y1 = 0F;
  151. var y2 = 0F;
  152. var y3 = 0F;
  153. var y4 = 0F;
  154. var y5 = 0F;
  155. var k1 = .0;
  156. var k2 = .0;
  157. var k3 = .0;
  158. var k4 = .0;
  159. var k5 = .0;
  160. if (Env.Preference.LogScale)
  161. {
  162. k1 = pricetrans.Inverse(Math.Min(p1.Y, p2.Y));
  163. k2 = pricetrans.Inverse(Math.Abs(p1.Y - p2.Y) * 0.382 + Math.Min(p1.Y, p2.Y));
  164. k3 = pricetrans.Inverse(Math.Abs(p1.Y - p2.Y) * 0.500 + Math.Min(p1.Y, p2.Y));
  165. k4 = pricetrans.Inverse(Math.Abs(p1.Y - p2.Y) * 0.618 + Math.Min(p1.Y, p2.Y));
  166. k5 = pricetrans.Inverse(Math.Max(p1.Y, p2.Y));
  167. y1 = Math.Min(p1.Y, p2.Y);
  168. y2 = (float)(Math.Abs(p1.Y - p2.Y) * 0.382 + Math.Min(p1.Y, p2.Y));
  169. y3 = (p1.Y + p2.Y) / 2;
  170. y4 = (float)(Math.Abs(p1.Y - p2.Y) * 0.618 + Math.Min(p1.Y, p2.Y));
  171. y5 = Math.Max(p1.Y, p2.Y);
  172. }
  173. else
  174. {
  175. k1 = pricetrans.Inverse(Math.Min(p1.Y, p2.Y));
  176. k5 = pricetrans.Inverse(Math.Max(p1.Y, p2.Y));
  177. k2 = Math.Abs(k1 - k5) * 0.618 + k5;
  178. k3 = (k5 + k1) / 2;
  179. k4 = Math.Abs(k1 - k5) * 0.382 + k5;
  180. y1 = Math.Min(p1.Y, p2.Y);
  181. y2 = (float)pricetrans.TransValue(k2);
  182. y3 = (float)pricetrans.TransValue(k3);
  183. y4 = (float)pricetrans.TransValue(k4);
  184. y5 = Math.Max(p1.Y, p2.Y);
  185. }
  186. DrawTheLine(hdc, m, l, y1, k1, out pt);
  187. DrawTheLine(hdc, m, l, y2, k2, out pt);
  188. DrawTheLine(hdc, m, l, y3, k3, out pt);
  189. DrawTheLine(hdc, m, l, y4, k4, out pt);
  190. DrawTheLine(hdc, m, l, y5, k5, out pt);
  191. }
  192. private void DrawTheLine(IntPtr hdc, float px1, float px2, float py, double kabuka, out Win32.POINT pt)
  193. {
  194. Win32.MoveToEx(hdc, (int)px1, (int)py, out pt);
  195. Win32.LineTo(hdc, (int)px2, (int)py);
  196. DrawText(hdc, (int)px2, (int)py, kabuka);
  197. }
  198. private void DrawText(IntPtr hdc, int x, int y, double d)
  199. {
  200. Win32.SetTextColor(hdc, Util.ToCOLORREF(Color.White));
  201. ChartUtil.DrawText(hdc, x + 3, y - 6, string.Format("{0:N}", d));
  202. }
  203. //p1,p2がrectに入っているとき、p1からp2に伸ばした線とp2からp1に伸ばした線がそれぞれrectと交差するところを返す
  204. private static Point[] GetEdge(Rectangle rect, Point p1, Point p2)
  205. {
  206. Point[] result = new Point[2];
  207. ArrayList ar = GetAllEdges(rect, p1, p2);
  208. if (ar.Count == 2) return (Point[])ar.ToArray(typeof(Point));
  209. result[0] = (Point)(p1.X > p2.X ? ar[1] : ar[2]);
  210. result[1] = (Point)(p1.X > p2.X ? ar[2] : ar[1]);
  211. return result;
  212. }
  213. //p1とp2を結ぶ線がrectを構成する4直線と交差する点を返す。水平・垂直のときは2個になる
  214. private static ArrayList GetAllEdges(Rectangle rect, Point p1, Point p2)
  215. {
  216. ArrayList ar = new ArrayList();
  217. if (p1.X == p2.X)
  218. {
  219. ar.Add(new Point(p1.X, p1.Y < p2.Y ? rect.Bottom : rect.Top));
  220. ar.Add(new Point(p1.X, p1.Y > p2.Y ? rect.Bottom : rect.Top));
  221. return ar;
  222. }
  223. else if (p1.Y == p2.Y)
  224. {
  225. ar.Add(new Point(p1.X < p2.X ? rect.Right : rect.Left, p1.Y));
  226. ar.Add(new Point(p1.X > p2.X ? rect.Right : rect.Left, p1.Y));
  227. return ar;
  228. }
  229. LinearTrans lt = LinearTrans.Solve(p1.X, p1.Y, p2.X, p2.Y);
  230. ar.Add(new Point(rect.Left, (int)lt.TransValue(rect.Left)));
  231. ar.Add(new Point(rect.Right, (int)lt.TransValue(rect.Right)));
  232. ar.Add(new Point((int)lt.Inverse(rect.Top), rect.Top));
  233. ar.Add(new Point((int)lt.Inverse(rect.Bottom), rect.Bottom));
  234. //この4点をX座標の順に並べ、2番目と3番目が答え
  235. ar.Sort(new PointComparer());
  236. return ar;
  237. }
  238. private class PointComparer : IComparer
  239. {
  240. public int Compare(object x, object y)
  241. {
  242. return ((Point)x).X - ((Point)y).X;
  243. }
  244. }
  245. public SolidFibonacci ToSolid(DataFarm farm, int firstdateindex, Trans value_to_y)
  246. {
  247. SolidFibonacci fl = new SolidFibonacci();
  248. int ind1 = firstdateindex + (int)Math.Floor((double)_pivot.X / Env.Layout.DatePitch);
  249. int ind2 = firstdateindex + (int)Math.Floor((double)_destination.X / Env.Layout.DatePitch);
  250. LinearTrans tr = LinearTrans.Solve(ind1, _pivot.Y, ind2, _destination.Y);
  251. double y1 = _pivot.Y;
  252. if (ind1 >= farm.FilledLength)
  253. {
  254. ind1 = farm.FilledLength - 1;
  255. y1 = tr.TransValue(ind1);
  256. }
  257. else if (ind1 < 0)
  258. {
  259. ind1 = 0;
  260. y1 = tr.TransValue(ind1);
  261. }
  262. fl._date1 = farm.GetByIndex(ind1).Date;
  263. fl._value1 = value_to_y.Inverse(y1);
  264. double y2 = _destination.Y;
  265. if (ind2 >= farm.FilledLength)
  266. {
  267. ind2 = farm.FilledLength - 1;
  268. y2 = tr.TransValue(ind2);
  269. }
  270. else if (ind2 < 0)
  271. {
  272. ind2 = 0;
  273. y2 = tr.TransValue(0);
  274. }
  275. fl._date2 = farm.GetByIndex(ind2).Date;
  276. //fl._value2 = value_to_y.Inverse(y2);
  277. fl._value2 = value_to_y.Inverse(_destination.Y);
  278. if (_id == -1)
  279. {
  280. fl._id = SolidFibonacci.NextID++;
  281. _id = fl._id;
  282. }
  283. else
  284. {
  285. fl._id = _id;
  286. }
  287. return fl;
  288. }
  289. //p1,p2を結ぶ直線とpの距離を返す
  290. public double GetDistance(Point p)
  291. {
  292. double[] par = GetNormalizedParam();
  293. return Math.Abs(par[0] * p.X + par[1] * p.Y + par[2]);
  294. }
  295. //両端を通る直線を ax+by+c=0, a^2+b^2=1 となる形式でa,b,cの配列で返す
  296. private double[] GetNormalizedParam()
  297. {
  298. double a, b, c;
  299. if (_pivot.X == _destination.X)
  300. {
  301. a = 1;
  302. b = 0;
  303. }
  304. else
  305. {
  306. double d = -(_pivot.Y - _destination.Y) / (double)(_pivot.X - _destination.X);
  307. b = Math.Sqrt(1 / (1 + d * d));
  308. a = b * d;
  309. }
  310. c = -(a * _pivot.X + b * _pivot.Y);
  311. return new double[] { a, b, c };
  312. }
  313. }
  314. internal class SolidFibonacci
  315. {
  316. public int _id;
  317. public int _code;
  318. public ChartFormat _targetFormat;
  319. public bool _logScale;
  320. public int _date1;
  321. public double _value1;
  322. public int _date2;
  323. public double _value2;
  324. private static int _nextID;
  325. public static int NextID
  326. {
  327. get
  328. {
  329. return _nextID;
  330. }
  331. set
  332. {
  333. _nextID = value;
  334. }
  335. }
  336. }
  337. internal class FibonacciCollection
  338. {
  339. private ArrayList _data;
  340. public FibonacciCollection()
  341. {
  342. _data = new ArrayList();
  343. }
  344. public int Count
  345. {
  346. get
  347. {
  348. return _data.Count;
  349. }
  350. }
  351. public void Add(AbstractBrand br, ChartFormat format, bool logScale, SolidFibonacci fl)
  352. {
  353. fl._code = br.Code;
  354. fl._targetFormat = format;
  355. fl._logScale = logScale;
  356. _data.Add(fl);
  357. }
  358. public SolidFibonacci[] Find(AbstractBrand br, ChartFormat format, bool logScale)
  359. {
  360. ArrayList t = new ArrayList();
  361. foreach (SolidFibonacci fl in _data)
  362. {
  363. if (fl._code == br.Code && fl._targetFormat == format && fl._logScale == logScale)
  364. t.Add(fl);
  365. }
  366. return (SolidFibonacci[])t.ToArray(typeof(SolidFibonacci));
  367. }
  368. public void ClearAll()
  369. {
  370. _data.Clear();
  371. }
  372. public void Clear(AbstractBrand br, ChartFormat format, bool logScale)
  373. {
  374. ArrayList temp = new ArrayList();
  375. IEnumerator ie = _data.GetEnumerator();
  376. while (ie.MoveNext())
  377. {
  378. SolidFibonacci fl = (SolidFibonacci)ie.Current;
  379. if (!(fl._code == br.Code && fl._targetFormat == format && fl._logScale == logScale))
  380. temp.Add(fl);
  381. }
  382. _data = temp;
  383. }
  384. public void Remove(int id)
  385. {
  386. for (int i = 0; i < _data.Count; i++)
  387. {
  388. SolidFibonacci l = (SolidFibonacci)_data[i];
  389. if (l._id == id)
  390. {
  391. _data.RemoveAt(i);
  392. break;
  393. }
  394. }
  395. }
  396. public void Load(StorageNode parent)
  397. {
  398. string t = parent["fibonacci-lines"];
  399. if (t == null) return;
  400. foreach (string ee in t.Split(','))
  401. {
  402. if (ee == null) continue;
  403. if (ee.Trim() == string.Empty) continue;
  404. SolidFibonacci fl = new SolidFibonacci();
  405. string[] e = ee.Split(':');
  406. fl._code = Int32.Parse(e[0]);
  407. switch (e[1])
  408. {
  409. case "D":
  410. fl._targetFormat = ChartFormat.Daily;
  411. fl._logScale = false;
  412. break;
  413. case "W":
  414. fl._targetFormat = ChartFormat.Weekly;
  415. fl._logScale = false;
  416. break;
  417. case "M":
  418. fl._targetFormat = ChartFormat.Monthly;
  419. fl._logScale = false;
  420. break;
  421. case "Y":
  422. fl._targetFormat = ChartFormat.Yearly;
  423. fl._logScale = false;
  424. break;
  425. case "DL":
  426. fl._targetFormat = ChartFormat.Daily;
  427. fl._logScale = true;
  428. break;
  429. case "WL":
  430. fl._targetFormat = ChartFormat.Weekly;
  431. fl._logScale = true;
  432. break;
  433. case "ML":
  434. fl._targetFormat = ChartFormat.Monthly;
  435. fl._logScale = true;
  436. break;
  437. case "YL":
  438. fl._targetFormat = ChartFormat.Yearly;
  439. fl._logScale = true;
  440. break;
  441. }
  442. fl._date1 = Int32.Parse(e[2]);
  443. fl._value1 = Double.Parse(e[3]);
  444. fl._date2 = Int32.Parse(e[4]);
  445. fl._value2 = Double.Parse(e[5]);
  446. fl._id = SolidFibonacci.NextID++;
  447. _data.Add(fl);
  448. }
  449. }
  450. public void SaveTo(StorageNode parent)
  451. {
  452. StringBuilder bld = new StringBuilder();
  453. foreach (SolidFibonacci sl in _data)
  454. {
  455. if (bld.Length > 0) bld.Append(",");
  456. String format;
  457. switch (sl._targetFormat)
  458. {
  459. case ChartFormat.Daily:
  460. default:
  461. format = "D";
  462. break;
  463. case ChartFormat.Weekly:
  464. format = "W";
  465. break;
  466. case ChartFormat.Monthly:
  467. format = "M";
  468. break;
  469. case ChartFormat.Yearly:
  470. format = "Y";
  471. break;
  472. }
  473. if (sl._logScale)
  474. {
  475. format += "L";
  476. }
  477. bld.Append(String.Format("{0}:{1}:{2}:{3:F2}:{4}:{5:F2}", sl._code, format, sl._date1, sl._value1, sl._date2, sl._value2));
  478. }
  479. parent["fibonacci-lines"] = bld.ToString();
  480. }
  481. }
  482. }
ダウンロード 印刷用表示

このコピペの URL

JavaScript での埋め込み

iframe での埋め込み

元のテキスト