PageRenderTime 101ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/Libs/Algobox.Financial/Structure/Finance/Strategies/FractionPrototype/FractionTrigger.cs

http://algobox.codeplex.com
C# | 293 lines | 241 code | 46 blank | 6 comment | 31 complexity | c66b80dc1e3bf67d532086b283881b56 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.ComponentModel;
  6. using Algobox.Feeds.Finance.MarketData;
  7. namespace Algobox.Structure.Finance.Strategies.FractionPrototype
  8. {
  9. public class FractionTrigger : INotifyPropertyChanged, IMarketUpdateLast
  10. {
  11. public FractionTrigger(IFractionComponent parent)
  12. {
  13. Father = parent;
  14. Value = parent.Value;
  15. Trigger = parent.Trigger;
  16. ExitTrigger = parent.Exit;
  17. FractionComponentDay day = parent as FractionComponentDay;
  18. if (day != null)
  19. {
  20. TriggerType = "Day";
  21. Entry = day.DayDifference;
  22. MidA = day.MidA;
  23. MidB = day.MidB;
  24. DayMoveA = day.DayMoveA;
  25. DayMoveB = day.DayMoveB;
  26. DayDifference = day.DayDifference;
  27. }
  28. else
  29. {
  30. FractionComponentOpen open = parent as FractionComponentOpen;
  31. TriggerType = "Open";
  32. Entry = open.OpenDifference;
  33. OpenA = open.OpenA;
  34. OpenB = open.OpenB;
  35. OpenMoveA = open.OpenMoveA;
  36. OpenMoveB = open.OpenMoveB;
  37. OpenDifference = open.OpenDifference;
  38. }
  39. // simulation for now
  40. // went long the spread?
  41. if (Entry >= Trigger)
  42. {
  43. _isLongSpread = true;
  44. PriceAIn = parent.Security.Prices.Bid.Price;
  45. QuantityAIn = (int)(-Value / (PriceAIn / 100));
  46. PriceBIn = parent.SecurityPair.Prices.Ask.Price;
  47. QuantityBIn = (int)(Value / (PriceBIn / 100));
  48. }
  49. // assume went short the spread
  50. else
  51. {
  52. _isLongSpread = false;
  53. PriceAIn = parent.Security.Prices.Ask.Price;
  54. QuantityAIn = (int)(Value / (PriceAIn / 100));
  55. PriceBIn = parent.SecurityPair.Prices.Bid.Price;
  56. QuantityBIn = (int)(-Value / (PriceBIn / 100));
  57. }
  58. PositionA = QuantityAIn;
  59. PositionB = QuantityBIn;
  60. TimeIn = DateTime.Now.TimeOfDay;
  61. // prime the mids
  62. TriggerMidA = (Father.Security.Prices.Ask.Price - Father.Security.Prices.Bid.Price) + Father.Security.Prices.Bid.Price;
  63. TriggerMoveA = (TriggerMidA - Father.Security.Prices.OHLC.Close) / Father.Security.Prices.OHLC.Close;
  64. TriggerMidB = (Father.SecurityPair.Prices.Ask.Price - Father.SecurityPair.Prices.Bid.Price) + Father.SecurityPair.Prices.Bid.Price;
  65. TriggerMoveB = (TriggerMidB - Father.SecurityPair.Prices.OHLC.Close) / Father.SecurityPair.Prices.OHLC.Close;
  66. TriggerDifference = (TriggerMoveA - TriggerMoveB) * 100;
  67. // potential threading issue
  68. // only subscribe once in a position
  69. parent.Manager.MarketFeed.SubscribeLast(parent.Security, this);
  70. parent.Manager.MarketFeed.SubscribeLast(parent.SecurityPair, this);
  71. }
  72. private static readonly NLog.Logger LOG = NLog.LogManager.GetCurrentClassLogger();
  73. private double _exitTrigger;
  74. private bool _isLongSpread;
  75. private bool _isComplete;
  76. public IFractionComponent Father { get; private set; }
  77. public string SymbolA { get { return Father.SymbolA; } }
  78. public string SymbolB { get { return Father.SymbolB; } }
  79. public double CloseA { get { return Father.CloseA; } }
  80. public double CloseB { get { return Father.CloseA; } }
  81. public double OpenA { get; private set; }
  82. public double OpenB { get; private set; }
  83. public double OpenMoveA { get; private set; }
  84. public double OpenMoveB { get; private set; }
  85. public double OpenDifference { get; private set; }
  86. public double MidA { get; private set; }
  87. public double MidB { get; private set; }
  88. public double DayMoveA { get; private set; }
  89. public double DayMoveB { get; private set; }
  90. public double DayDifference { get; private set; }
  91. public double TriggerMidA { get; private set; }
  92. public double TriggerMidB { get; private set; }
  93. public double TriggerMoveA { get; private set; }
  94. public double TriggerMoveB { get; private set; }
  95. public double TriggerDifference { get; private set; }
  96. public double Entry { get; private set; }
  97. public double Exit { get; private set; }
  98. public ushort Value { get; private set; }
  99. public string TriggerType { get; private set; }
  100. public double Trigger { get; private set; }
  101. public double ExitTrigger
  102. {
  103. get { return _exitTrigger; }
  104. set
  105. {
  106. if (value > 0 && value <= 100)
  107. {
  108. _exitTrigger = value;
  109. NotifyPropertyChanged("ExitTrigger");
  110. }
  111. }
  112. }
  113. public TimeSpan TimeIn { get; private set; }
  114. public TimeSpan TimeOut { get; private set; }
  115. public int PositionA { get; private set; }
  116. public int PositionB { get; private set; }
  117. public int QuantityAIn { get; internal set; }
  118. public int QuantityAOut { get; internal set; }
  119. public int QuantityBIn { get; internal set; }
  120. public int QuantityBOut { get; internal set; }
  121. public double PriceAIn { get; internal set; }
  122. public double PriceAOut { get; internal set; }
  123. public double PriceBIn { get; internal set; }
  124. public double PriceBOut { get; internal set; }
  125. public double PnL
  126. {
  127. get
  128. {
  129. return
  130. ((QuantityAIn * (-PriceAIn / 100)) +
  131. (QuantityBIn * (-PriceBIn / 100)) +
  132. (QuantityAOut * (-PriceAOut / 100)) +
  133. (QuantityBOut * (-PriceBOut / 100)) +
  134. (-PositionA * (-Father.Security.Prices.Last.Price / 100)) +
  135. (-PositionB * (-Father.SecurityPair.Prices.Last.Price / 100)))
  136. ;
  137. }
  138. }
  139. public event PropertyChangedEventHandler PropertyChanged;
  140. private void NotifyPropertyChanged(string propertyName)
  141. {
  142. if (PropertyChanged != null)
  143. {
  144. PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  145. }
  146. }
  147. public void ExitA()
  148. {
  149. if (PositionA == 0)
  150. return;
  151. TimeOut = DateTime.Now.TimeOfDay;
  152. if (PositionA > 0)
  153. PriceAOut = Father.Security.Prices.Bid.Price;
  154. else
  155. PriceAOut = Father.Security.Prices.Ask.Price;
  156. QuantityAOut = -PositionA;
  157. PositionA = 0;
  158. NotifyPropertyChanged("TimeOut");
  159. NotifyPropertyChanged("PositionA");
  160. NotifyPropertyChanged("PriceAOut");
  161. NotifyPropertyChanged("QuantityAOut");
  162. NotifyPropertyChanged("PnL");
  163. if (PositionB == 0)
  164. {
  165. _isComplete = true;
  166. Father.OnFractionTriggerComplete(this);
  167. }
  168. }
  169. public void ExitB()
  170. {
  171. if (PositionB == 0)
  172. return;
  173. TimeOut = DateTime.Now.TimeOfDay;
  174. if (PositionB > 0)
  175. PriceBOut = Father.SecurityPair.Prices.Bid.Price;
  176. else
  177. PriceBOut = Father.SecurityPair.Prices.Ask.Price;
  178. QuantityBOut = -PositionB;
  179. PositionB = 0;
  180. NotifyPropertyChanged("TimeOut");
  181. NotifyPropertyChanged("PositionB");
  182. NotifyPropertyChanged("PriceBOut");
  183. NotifyPropertyChanged("QuantityBOut");
  184. NotifyPropertyChanged("PnL");
  185. if (PositionA == 0)
  186. {
  187. _isComplete = true;
  188. Father.OnFractionTriggerComplete(this);
  189. }
  190. }
  191. public void OnPriceLast(Objects.Finance.Assets.Stock.IStock stock, Objects.Finance.Prices.PriceVolume last)
  192. {
  193. if (_isComplete)
  194. {
  195. Father.Manager.MarketFeed.UnsubscribeLast(Father.Security, this);
  196. Father.Manager.MarketFeed.UnsubscribeLast(Father.SecurityPair, this);
  197. }
  198. else
  199. {
  200. NotifyPropertyChanged("PnL");
  201. double mid;
  202. if (stock == Father.Security)
  203. {
  204. mid = (Father.Security.Prices.Ask.Price - Father.Security.Prices.Bid.Price) + Father.Security.Prices.Bid.Price;
  205. if (mid != TriggerMidA)
  206. {
  207. TriggerMidA = mid;
  208. TriggerMoveA = (mid - Father.Security.Prices.OHLC.Close) / Father.Security.Prices.OHLC.Close;
  209. TriggerDifference = (TriggerMoveA - TriggerMoveB) * 100;
  210. CheckExit();
  211. NotifyPropertyChanged("TriggerMidA");
  212. NotifyPropertyChanged("TriggerMoveA");
  213. NotifyPropertyChanged("TriggerDifference");
  214. }
  215. }
  216. else if (stock == Father.SecurityPair)
  217. {
  218. mid = (Father.SecurityPair.Prices.Ask.Price - Father.SecurityPair.Prices.Bid.Price) + Father.SecurityPair.Prices.Bid.Price;
  219. if (mid != TriggerMidB)
  220. {
  221. TriggerMidB = mid;
  222. TriggerMoveB = (mid - Father.SecurityPair.Prices.OHLC.Close) / Father.SecurityPair.Prices.OHLC.Close;
  223. TriggerDifference = (TriggerMoveA - TriggerMoveB) * 100;
  224. CheckExit();
  225. NotifyPropertyChanged("TriggerMidB");
  226. NotifyPropertyChanged("TriggerMoveB");
  227. NotifyPropertyChanged("TriggerDifference");
  228. }
  229. }
  230. }
  231. }
  232. private bool CheckExit()
  233. {
  234. if ((Entry > 0 && TriggerDifference <= _exitTrigger)
  235. || (Entry < 0 && TriggerDifference >= _exitTrigger))
  236. {
  237. ExitA();
  238. ExitB();
  239. Exit = TriggerDifference;
  240. Father.Manager.MarketFeed.SubscribeLast(Father.Security, this);
  241. Father.Manager.MarketFeed.SubscribeLast(Father.SecurityPair, this);
  242. return true;
  243. }
  244. return false;
  245. }
  246. }
  247. }