Add logic to all models to avoid selling and immediately buying back the same security as this is considered a Wash Trade and is illegal.
This commit is contained in:
@@ -392,6 +392,7 @@ namespace MarketData.Generator.CMMomentum
|
||||
else
|
||||
{
|
||||
Positions slotPositions = ActivePositions[slotIndex];
|
||||
List<String> slotSymbols = slotPositions.ConvertAll(x=>x.Symbol); // capture sell symbols to exclude from purchases to eliminate wash trades
|
||||
SellPositions(slotPositions, TradeDate);
|
||||
DisplaySales(slotPositions, TradeDate);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG, "********************* S E L L *********************");
|
||||
@@ -401,7 +402,7 @@ namespace MarketData.Generator.CMMomentum
|
||||
ActivePositions[slotIndex].Clear();
|
||||
DisplayBalance();
|
||||
double cashAllocation = Math.Min(CashBalance, (ActivePositions.GetExposure() + CashBalance) / HoldingPeriod); // Even out the cash allocation so that no one slot eats up all the cash
|
||||
Positions positions=BuyPositions(slotIndex,TradeDate,AnalysisDate,cashAllocation,SymbolsHeld());
|
||||
Positions positions=BuyPositions(slotIndex,TradeDate,AnalysisDate,cashAllocation,new List<String>(SymbolsHeld().Concat(slotSymbols)));
|
||||
DisplayPurchases(positions, TradeDate);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,"********************** B U Y ********************");
|
||||
positions.Display();
|
||||
|
||||
@@ -623,7 +623,7 @@ namespace MarketData.Generator.CMTrend
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("TradeDate ({0}) must be greater than or equal to the max position date ({1}) in the trade file.",TradeDate.ToShortDateString(),ActivePositions.Select(x => x.PurchaseDate).Max().ToShortDateString()));
|
||||
return result;
|
||||
}
|
||||
ManageOpenPositions(TradeDate);
|
||||
List<String> closedSymbols = ManageOpenPositions(TradeDate); // capture any closed symbols so we don't re-enter immediately (wash trades)
|
||||
ManageCandidates(TradeDate);
|
||||
// ************************************************************************************************************************************************************************
|
||||
// **************************************************************************** N E W P O S I T I O N S *****************************************************************
|
||||
@@ -641,7 +641,7 @@ namespace MarketData.Generator.CMTrend
|
||||
result.Success=true;
|
||||
return result;
|
||||
}
|
||||
Positions positions=BuyCandidates(TradeDate,CashBalance,ActivePositions.GetSymbols());
|
||||
Positions positions=BuyCandidates(TradeDate,CashBalance,new List<String>(ActivePositions.GetSymbols().Concat(closedSymbols)));
|
||||
if(null != positions && 0!=positions.Count)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,"******************** B U Y ********************");
|
||||
@@ -735,7 +735,7 @@ namespace MarketData.Generator.CMTrend
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("TradeDate ({0}) must be greater than or equal to the max position date ({1}) in the trade file.",TradeDate.ToShortDateString(),ActivePositions.Select(x => x.PurchaseDate).Max().ToShortDateString()));
|
||||
return result;
|
||||
}
|
||||
ManageOpenPositions(TradeDate);
|
||||
List<String> closedSymbols = ManageOpenPositions(TradeDate); // capture any closed symbols so we don't re-enter immediately (wash trades)
|
||||
ManageCandidates(TradeDate);
|
||||
if(ActivePositions.PositionsOn(TradeDate)>=Parameters.MaxDailyPositions)
|
||||
{
|
||||
@@ -743,7 +743,7 @@ namespace MarketData.Generator.CMTrend
|
||||
result.Success=true;
|
||||
continue;
|
||||
}
|
||||
Positions positions=BuyCandidates(TradeDate,CashBalance,ActivePositions.GetSymbols());
|
||||
Positions positions=BuyCandidates(TradeDate,CashBalance,new List<String>(ActivePositions.GetSymbols().Concat(closedSymbols)));
|
||||
if(null!=positions&&0!=positions.Count)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,"******************** B U Y ********************");
|
||||
@@ -884,11 +884,11 @@ namespace MarketData.Generator.CMTrend
|
||||
// ***********************************************************************************************************************************************************************
|
||||
// *********************************************************************** M A N A G E O P E N P O S I T I O N S *****************************************************
|
||||
// ***********************************************************************************************************************************************************************
|
||||
private void ManageOpenPositions(DateTime tradeDate)
|
||||
private List<String> ManageOpenPositions(DateTime tradeDate)
|
||||
{
|
||||
if(0==ActivePositions.Count) return;
|
||||
List<String> closedSymbols = new List<String>();
|
||||
if(0==ActivePositions.Count) return closedSymbols;
|
||||
Positions closedPositions = new Positions();
|
||||
// List<Position> closedPositions=new List<Position>();
|
||||
foreach(Position position in ActivePositions)
|
||||
{
|
||||
Price price=GBPriceCache.GetInstance().GetPrice(position.Symbol,tradeDate);
|
||||
@@ -960,6 +960,8 @@ namespace MarketData.Generator.CMTrend
|
||||
ActivePositions.Remove(closedPosition);
|
||||
}
|
||||
}
|
||||
if(closedPositions.Count>0)closedSymbols = closedPositions.ConvertAll(x => x.Symbol);
|
||||
return closedSymbols;
|
||||
}
|
||||
|
||||
// **********************************************************************************************************************************************************
|
||||
|
||||
@@ -509,8 +509,10 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
public void SellAndBuySlotPositions(int slotIndex)
|
||||
{
|
||||
MGSHPositions slotPositions=ActivePositions[slotIndex];
|
||||
List<String> closedSymbols = new List<string>();
|
||||
if(!Configuration.KeepSlotPositions) // if we are not configured to KeepSlotPositions then don't sell anything just buy to the max positions allowed for the slot
|
||||
{
|
||||
closedSymbols = slotPositions.ConvertAll(x => x.Symbol);
|
||||
SellPositions(slotPositions,TradeDate);
|
||||
DisplaySales(slotPositions, TradeDate);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,"********************* S E L L *********************");
|
||||
@@ -524,7 +526,7 @@ namespace MarketData.Generator.MGSHMomentum
|
||||
int positionsToFill = MaxPositions-slotPositions.Count;
|
||||
double cashAllocation = (CashBalance / ((HoldingPeriod * MaxPositions) - ActivePositions.GetCount()))*positionsToFill; // split the cash between the total positions we can own less the number of positions we have
|
||||
MGSHPositions positions = null;
|
||||
positions=BuyPositions(slotIndex, TradeDate,AnalysisDate,cashAllocation,SymbolsHeld(TradeDate), positionsToFill);
|
||||
positions=BuyPositions(slotIndex, TradeDate,AnalysisDate,cashAllocation,new List<String>(SymbolsHeld(TradeDate).Concat(closedSymbols)), positionsToFill);
|
||||
if(CashBalance-positions.Exposure<=0.00)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("********** Insufficient funds to make additional purchases.**************"));
|
||||
|
||||
@@ -380,6 +380,7 @@ namespace MarketData.Generator.Momentum
|
||||
else
|
||||
{
|
||||
Positions slotPositions=ActivePositions[slotIndex];
|
||||
List<String> closedSymbols = slotPositions.ConvertAll(x => x.Symbol); // capture the closed symbols so we don't re-enter the position (avoid wash trades)
|
||||
SellPositions(slotPositions,TradeDate);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,"********************* S E L L *********************");
|
||||
slotPositions.Display();
|
||||
@@ -392,7 +393,7 @@ namespace MarketData.Generator.Momentum
|
||||
cashAllocation = Math.Min(CashBalance, (ActivePositions.GetExposure() + CashBalance) / (double)HoldingPeriod);
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("CASH ALLOCATION:{0}",Utility.FormatCurrency(cashAllocation)));
|
||||
Positions positions = null;
|
||||
positions=BuyPositions(TradeDate,AnalysisDate,cashAllocation,SymbolsHeld(TradeDate));
|
||||
positions=BuyPositions(TradeDate,AnalysisDate,cashAllocation,new List<String>(SymbolsHeld(TradeDate).Concat(closedSymbols)));
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,"********************** B U Y ********************");
|
||||
positions.Display();
|
||||
if(CashBalance-positions.Exposure<=0.00)
|
||||
|
||||
@@ -5660,32 +5660,56 @@ namespace MarketData.Helper
|
||||
return price;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
||||
/// GetDailyPrices - Retrieve prices from Yahoo. This feed can retrieve historical prices from Yahoo as well as current day price
|
||||
|
||||
/// </summary>
|
||||
|
||||
/// <param name="symbol"></param>
|
||||
|
||||
/// <param name="startDate"></param>
|
||||
|
||||
/// <param name="endDate"></param>
|
||||
|
||||
/// <returns></returns>
|
||||
|
||||
public static Prices GetDailyPrices(String symbol, DateTime startDate, DateTime endDate)
|
||||
|
||||
{
|
||||
HttpNetResponse httpNetResponse=null;
|
||||
|
||||
try
|
||||
{
|
||||
if(symbol==null)return null;
|
||||
CompanyProfile companyProfile=CompanyProfileDA.GetCompanyProfile(symbol);
|
||||
if(null!=companyProfile && companyProfile.FreezePricing)
|
||||
{
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Pricing for {0} is frozen.",symbol));
|
||||
return null;
|
||||
}
|
||||
startDate=startDate.Date;
|
||||
endDate=endDate.Date;
|
||||
if(startDate>endDate)
|
||||
if(symbol==null)return null;
|
||||
CompanyProfile companyProfile=CompanyProfileDA.GetCompanyProfile(symbol);
|
||||
if(null!=companyProfile && companyProfile.FreezePricing)
|
||||
{
|
||||
DateTime tempDate=startDate;
|
||||
startDate=endDate;
|
||||
endDate=tempDate;
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Pricing for {0} is frozen.",symbol));
|
||||
return null;
|
||||
}
|
||||
DateTime period1 = startDate.Date;
|
||||
DateTime period2 = endDate.Date;
|
||||
|
||||
if(period1>period2)
|
||||
{
|
||||
DateTime tempDate=period1;
|
||||
period1=period2;
|
||||
period2=tempDate;
|
||||
}
|
||||
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[MarketDataHelper:GetDailyPrices]{0} start:{1} end:{2}",symbol,Utility.DateTimeToStringMMHDDHYYYY(startDate),Utility.DateTimeToStringMMHDDHYYYY(endDate)));
|
||||
if(period1.Equals(period2))
|
||||
{
|
||||
DateGenerator dateGenerator=new DateGenerator();
|
||||
period1 = dateGenerator.FindPrevBusinessDay(period2);
|
||||
}
|
||||
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[MarketDataHelper:GetDailyPrices]{0} start:{1} end:{2}",symbol,Utility.DateTimeToStringMMHDDHYYYY(period1),Utility.DateTimeToStringMMHDDHYYYY(period2)));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String strRequest;
|
||||
Prices prices=null;
|
||||
sb.Append("https://query1.finance.yahoo.com/v7/finance/chart/").Append(symbol).Append("?period1=").Append(Utility.DateToUnixDate(startDate)).Append("&period2=").Append(Utility.DateToUnixDate(endDate)).Append("&interval=1d&events=history");
|
||||
sb.Append("https://query1.finance.yahoo.com/v7/finance/chart/").Append(symbol).Append("?period1=").Append(Utility.DateToUnixDate(period1)).Append("&period2=").Append(Utility.DateToUnixDate(period2)).Append("&interval=1d&events=history");
|
||||
strRequest=sb.ToString();
|
||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Query:{0}",strRequest));
|
||||
WebProxy webProxy=HttpNetRequest.GetProxy("GetDailyPrices");
|
||||
@@ -5694,6 +5718,10 @@ namespace MarketData.Helper
|
||||
if(!httpNetResponse.Success) return null;
|
||||
JObject json=JObject.Parse(httpNetResponse.ResponseString);
|
||||
prices=GetPricesFromJSONString(json,symbol);
|
||||
if(startDate.Date.Equals(endDate.Date))
|
||||
{
|
||||
prices = new Prices(prices.Where(x => x.Date.Date.Equals(startDate.Date)).ToList());
|
||||
}
|
||||
return prices;
|
||||
}
|
||||
catch(Exception exception)
|
||||
@@ -5706,6 +5734,53 @@ namespace MarketData.Helper
|
||||
if(null!=httpNetResponse)httpNetResponse.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
//public static Prices GetDailyPrices(String symbol, DateTime startDate, DateTime endDate)
|
||||
//{
|
||||
// HttpNetResponse httpNetResponse=null;
|
||||
// try
|
||||
// {
|
||||
// if(symbol==null)return null;
|
||||
// CompanyProfile companyProfile=CompanyProfileDA.GetCompanyProfile(symbol);
|
||||
// if(null!=companyProfile && companyProfile.FreezePricing)
|
||||
// {
|
||||
// MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Pricing for {0} is frozen.",symbol));
|
||||
// return null;
|
||||
// }
|
||||
// startDate=startDate.Date;
|
||||
// endDate=endDate.Date;
|
||||
// if(startDate>endDate)
|
||||
// {
|
||||
// DateTime tempDate=startDate;
|
||||
// startDate=endDate;
|
||||
// endDate=tempDate;
|
||||
// }
|
||||
|
||||
// MDTrace.WriteLine(LogLevel.DEBUG,String.Format("[MarketDataHelper:GetDailyPrices]{0} start:{1} end:{2}",symbol,Utility.DateTimeToStringMMHDDHYYYY(startDate),Utility.DateTimeToStringMMHDDHYYYY(endDate)));
|
||||
// StringBuilder sb = new StringBuilder();
|
||||
// String strRequest;
|
||||
// Prices prices=null;
|
||||
// sb.Append("https://query1.finance.yahoo.com/v7/finance/chart/").Append(symbol).Append("?period1=").Append(Utility.DateToUnixDate(startDate)).Append("&period2=").Append(Utility.DateToUnixDate(endDate)).Append("&interval=1d&events=history");
|
||||
// strRequest=sb.ToString();
|
||||
// MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Query:{0}",strRequest));
|
||||
// WebProxy webProxy=HttpNetRequest.GetProxy("GetDailyPrices");
|
||||
// CookieCollection cookieCollection=new CookieCollection();
|
||||
// httpNetResponse=HttpNetRequest.GetRequestNoEncodingV3B(strRequest,cookieCollection,webProxy);
|
||||
// if(!httpNetResponse.Success) return null;
|
||||
// JObject json=JObject.Parse(httpNetResponse.ResponseString);
|
||||
// prices=GetPricesFromJSONString(json,symbol);
|
||||
// return prices;
|
||||
// }
|
||||
// catch(Exception exception)
|
||||
// {
|
||||
// MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Exception:{0}",exception.ToString()));
|
||||
// return null;
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// if(null!=httpNetResponse)httpNetResponse.Dispose();
|
||||
// }
|
||||
//}
|
||||
private static Prices GetPricesFromJSONString(JObject json,String symbol)
|
||||
{
|
||||
Prices prices=new Prices();
|
||||
|
||||
Reference in New Issue
Block a user