88 lines
3.4 KiB
C#
88 lines
3.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using MarketData.MarketDataModel;
|
|
using MarketData.Utils;
|
|
|
|
namespace MarketData.Helper
|
|
{
|
|
public class SwingTradeHelper
|
|
{
|
|
private SwingTradeHelper()
|
|
{
|
|
}
|
|
public static SwingTrades FindSwingTrades(Prices prices,DMAPricesByDate ma21,BollingerBandElementsByDate bollingerBandElements=null)
|
|
{
|
|
SwingTrades swingTrades=new SwingTrades();
|
|
if (null == prices) return swingTrades;
|
|
prices.Sort(new PriceComparerDesc());
|
|
for (int index = 0; index < prices.Count; index++)
|
|
{
|
|
SwingTrade swingTrade = FindSwing(prices, index, ma21, bollingerBandElements);
|
|
if (null == swingTrade) continue;
|
|
swingTrades.Add(swingTrade);
|
|
}
|
|
return swingTrades;
|
|
}
|
|
private static SwingTrade FindSwing(Prices prices, int startIndex,DMAPricesByDate ma21,BollingerBandElementsByDate bollingerBandElements=null)
|
|
{
|
|
if (startIndex + 4 > prices.Count) return null;
|
|
DMAPrice maPrice = null;
|
|
Price p = prices[startIndex];
|
|
Price p1 = prices[startIndex + 1];
|
|
Price p2 = prices[startIndex + 2];
|
|
Price p3 = prices[startIndex + 3];
|
|
if(!ma21.ContainsKey(p.Date))return null;
|
|
maPrice = ma21[p.Date];
|
|
if (p1.Low >= maPrice.AVGPrice) return null;
|
|
if (!(p1.Low < p.Low && p2.Low < p1.Low && p3.Low > p2.Low)) return null;
|
|
SwingTrade swingTrade = new SwingTrade();
|
|
swingTrade.Symbol = p.Symbol;
|
|
DateGenerator dateGenerator = new DateGenerator();
|
|
if (null != bollingerBandElements && bollingerBandElements.ContainsKey(p1.Date) && bollingerBandElements.ContainsKey(p2.Date) && bollingerBandElements.ContainsKey(p3.Date))
|
|
{
|
|
BollingerBandElement b1=bollingerBandElements[p1.Date];
|
|
BollingerBandElement b2=bollingerBandElements[p2.Date];
|
|
BollingerBandElement b3 = bollingerBandElements[p3.Date];
|
|
if (p1.Low < b1.L && p2.Low < b2.L && p3.Low > b3.L)
|
|
{
|
|
swingTrade.SwingType = SwingTrade.TypeOfSwing.LongBand;
|
|
swingTrade.CandleDate = p1.Date;
|
|
swingTrade.CandleHigh = p1.High;
|
|
swingTrade.StopPrice = p1.Low;
|
|
swingTrade.CloseDate = p3.Date;
|
|
swingTrade.EntryDate = dateGenerator.FindNextBusinessDay(swingTrade.CloseDate);
|
|
return swingTrade;
|
|
}
|
|
}
|
|
DateTime? closeDate = FindCloseAboveCandle(prices, p1, startIndex + 4);
|
|
swingTrade.SwingType = SwingTrade.TypeOfSwing.Long;
|
|
swingTrade.CandleDate = p1.Date;
|
|
swingTrade.CandleHigh = p1.High;
|
|
swingTrade.StopPrice = p1.Low;
|
|
if (null != closeDate)
|
|
{
|
|
swingTrade.CloseDate = closeDate.Value;
|
|
swingTrade.EntryDate = dateGenerator.FindNextBusinessDay(swingTrade.CloseDate);
|
|
}
|
|
else
|
|
{
|
|
swingTrade.CloseDate = Utility.Epoch;
|
|
swingTrade.EntryDate = Utility.Epoch;
|
|
}
|
|
if (!swingTrade.EntryDate.Equals(Utility.Epoch) && dateGenerator.DaysBetween(swingTrade.CandleDate, swingTrade.EntryDate) > 15) return null;
|
|
return swingTrade;
|
|
}
|
|
private static DateTime? FindCloseAboveCandle(Prices prices, Price priceCandle, int startIndex)
|
|
{
|
|
if (startIndex > prices.Count) return null;
|
|
for (int index = startIndex; index < prices.Count; index++)
|
|
{
|
|
Price price = prices[index];
|
|
if (price.Close > priceCandle.High) return price.Date;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
}
|