コピペ: OmegaChart Fibonacciリトレースメント Fibonacci.cs 新規追加 ※フィボナッチの位置情報(61.8%とか)も描画

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

このコピペの URL

JavaScript での埋め込み

iframe での埋め込み

元のテキスト