using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TradeIdeas.TIProGUI;
using TradeIdeas.MiscSupport;
using System.ComponentModel;
using TradeIdeas.TIProData;
using TradeIdeas.ServerConnection;
using TradeIdeas.XML;
using System.Xml;
using System.Web;
using System.Collections.Specialized;
using System.Drawing;
using TradeIdeas.TIProData.Configuration;
namespace AIStrategyWindow
{
public delegate void NewAlertHandler(RowData rowData, AIStrategy strategy);
public delegate void NewStrategyTradeHandler(StrategyTrade trade, AIStrategy strategy);
public delegate void CloudLinkLoadedHandler(AIStrategy strategy);
public delegate void HistoryCompleteHandler(AIStrategy strategy);
public class AIStrategy: IRowDataCapable
{
private string _name = "";
///
/// Name of the strategy.
///
[ColumnInfoAttribute(SizeHint="Opening Range Breakdown Hold 3_30pmXXXX")]
public string Strategy
{
get { return _name; }
set { _name = value; }
}
private double? _winrate = null;
[ColumnInfoAttribute(DisplayName = "Win %", Format="1", SizeHint = "Win %XX", MidForColor = 50, MinForColor = 40, MaxForColor = 65.0)]
public double? WinRate
{
get { return _winrate; }
set { _winrate = value; }
}
private double _profitFactor = 1.0;
[ColumnInfoAttribute(DisplayName = "Profit Factor", Format="2", SizeHint = "ProfitXX", MinForColor = 0.8, MidForColor = 1, MaxForColor = 2.5)]
public double ProfitFactor
{
get { return _profitFactor; }
set { _profitFactor = value; }
}
private string _lastSymbol = "";
[ColumnInfoAttribute(DisplayName = "Last Symbol", SizeHint = "MSFTXX", RealTimeUpdates = true)]
public string LastSymbol
{
get { return _lastSymbol; }
set { _lastSymbol = value; }
}
private double? _lastSignalPrice = null;
[ColumnInfoAttribute(DisplayName = "Last Signal Price", SizeHint = "SymbolXX", Format="2", RealTimeUpdates = true)]
public double? LastSignalPrice
{
get { return _lastSignalPrice; }
set { _lastSignalPrice = value; }
}
private DateTime? _lastSignalTime = null;
[ColumnInfoAttribute(Format = "relativetime", DisplayName = "Last Signal Time", SizeHint = "Last SignalXX", RealTimeUpdates = true)]
public DateTime? LastSignalTime
{
get { return _lastSignalTime; }
set { _lastSignalTime = value; }
}
private double? _lastStopPrice = null;
[ColumnInfoAttribute(DisplayName = "Last Stop Price", SizeHint = "SymbolXX", Format="2", RealTimeUpdates = true)]
public double? LastStopPrice
{
get { return _lastStopPrice; }
set { _lastStopPrice = value; }
}
private double? _lastSmartStop = null;
[ColumnInfoAttribute(DisplayName = "Last Smart Stop", SizeHint = "SymbolXX", Format="2", RealTimeUpdates = true)]
public double? LastSmartStop
{
get { return _lastSmartStop; }
set { _lastSmartStop = value; }
}
private double? _lastTargetPrice = null;
[ColumnInfoAttribute(DisplayName = "Last Target Price", SizeHint = "SymbolXX", Format="2", RealTimeUpdates = true)]
public double? LastTargetPrice
{
get { return _lastTargetPrice; }
set { _lastTargetPrice = value; }
}
///
/// Sum of profit from each trade in this strategy
///
[ColumnInfoAttribute(DisplayName = "Profit", SizeHint = "XXXX.XX", Format = "dollars", RealTimeUpdates = true)]
public double Profit
{
get
{
double? profit = _strategyTrades.Sum(x => x.Profit);
if (profit.HasValue)
return profit.Value;
return 0.0;
}
}
///
/// Sum of Non-Exit profit from each trade in this strategy
///
[ColumnInfoAttribute(DisplayName = "Risk On Profit", SizeHint = "XXXX.XX", Format = "dollars", RealTimeUpdates = true)]
public double NonExitProfit
{
get
{
double? nonExitProfit = _strategyTrades.Sum(x => x.NonExitProfit);
if (nonExitProfit.HasValue)
return nonExitProfit.Value;
return 0.0;
}
}
[ColumnInfoAttribute(DisplayName = "Profit Basis Points", SizeHint = "XXXX.XX", Format = "0", RealTimeUpdates = true, DefaultVisible = false)]
public double ProfitBasisPoints
{
get
{
double? basisPoints = _strategyTrades.Sum(x => x.ProfitBasisPoints);
if (basisPoints.HasValue)
return basisPoints.Value;
return 0.0;
}
}
[ColumnInfoAttribute(DisplayName = "Open Profit", SizeHint = "XXXX.XX", Format = "dollars", RealTimeUpdates = true, DefaultVisible = false)]
public double OpenProfit
{
get
{
List openTrades = _strategyTrades.Where(x => !x.ExitTime.HasValue).ToList();
if (openTrades.Count > 0)
{
double? profit = openTrades.Sum(x => x.Profit);
if (profit.HasValue)
return profit.Value;
}
return 0.0;
}
}
[ColumnInfoAttribute(DisplayName = "Open Profit Basis Points", SizeHint = "XXXX.XX", Format = "0", RealTimeUpdates = true, DefaultVisible = false)]
public double OpenProfitBasisPoints
{
get
{
List openTrades = _strategyTrades.Where(x => !x.ExitTime.HasValue).ToList();
if (openTrades.Count > 0)
{
double? profit = openTrades.Sum(x => x.ProfitBasisPoints);
if (profit.HasValue)
return profit.Value;
}
return 0.0;
}
}
[ColumnInfoAttribute(DisplayName = "Risk Off Profit", SizeHint = "XXXX.XX", Format = "dollars", RealTimeUpdates = true, DefaultVisible = false)]
public double ClosedProfit
{
get
{
List closedTrades = _strategyTrades.Where(x => x.ExitTime.HasValue).ToList();
if (closedTrades.Count > 0)
{
double? profit = closedTrades.Sum(x => x.Profit);
if (profit.HasValue)
return profit.Value;
}
return 0.0;
}
}
[ColumnInfoAttribute(DisplayName = "Closed Profit Basis Points", SizeHint = "XXXX.XX", Format = "0", RealTimeUpdates = true, DefaultVisible = false)]
public double ClosedProfitBasisPoints
{
get
{
List closedTrades = _strategyTrades.Where(x => x.ExitTime.HasValue).ToList();
if (closedTrades.Count > 0)
{
double? profit = closedTrades.Sum(x => x.ProfitBasisPoints);
if (profit.HasValue)
return profit.Value;
}
return 0.0;
}
}
[ColumnInfoAttribute(DisplayName = "Trades Today", SizeHint = "XXXX", Format = "0", RealTimeUpdates = true)]
public int TradesToday
{
get
{
return _strategyTrades.Count;
}
}
[ColumnInfoAttribute(DisplayName = "Open Trades Today", SizeHint = "XXXX", Format = "0", RealTimeUpdates = true, DefaultVisible = false)]
public int OpenTradesToday
{
get
{
return _strategyTrades.Where(x => x.IsOpen).Count();
}
}
[ColumnInfoAttribute(DisplayName = "Closed Trades Today", SizeHint = "XXXX", Format = "0", RealTimeUpdates = true, DefaultVisible = false)]
public int ClosedTradesToday
{
get
{
return _strategyTrades.Where(x => !x.IsOpen).Count();
}
}
[ColumnInfoAttribute(DisplayName = "Average Profit Per Trade Today", SizeHint = "XXXX.XX", Format = "dollars", RealTimeUpdates = true)]
public double? AvgProfitToday
{
get
{
if (_strategyTrades.Count > 0)
return _strategyTrades.Where(x => x.Profit.HasValue).Sum(x => x.Profit.Value) / _strategyTrades.Count;
else
return null;
}
}
[ColumnInfoAttribute(DisplayName = "Win % Today", SizeHint = "XXXX", Format = "1", RealTimeUpdates = true, MidForColor = 50, MinForColor = 15, MaxForColor = 85.0)]
public double? WinRateToday
{
get
{
if (_strategyTrades.Count > 0)
return (double)_strategyTrades.Where(x => x.Profit.HasValue && x.Profit.Value > 0).Count() / _strategyTrades.Count * 100;
else
return null;
}
}
private double _totalTrades = 0;
[ColumnInfoAttribute(DisplayName = "Total Trades", Format="0", SizeHint = "XXXXXXX")]
public double TotalTrades
{
get { return _totalTrades; }
set { _totalTrades = value; }
}
private double _maxTradesPerDay = 0.0;
[ColumnInfoAttribute(DisplayName = "Max Trades Per Day (observed)", SizeHint = "XXXXXXX", Format="0")]
public double MaxTradesPerDay
{
get { return _maxTradesPerDay; }
set { _maxTradesPerDay = value; }
}
[ColumnInfoAttribute(DisplayName = "Recent Performance", Format = "thermograph", SizeHint = "XXXXXXXXXXXXXXXXXXXXXXX", DefaultVisible = true)]
public Thermograph RecentPerformance { get; set; }
[ColumnInfoAttribute(DisplayName = "Time Stop", SizeHint = "XXXXXXXXXX")]
public string TimeStop
{
get
{
if (null == _oddsMakerRequest)
return "";
else
{
if (_oddsMakerRequest.UseExitTimeMinutesAfter)
return _oddsMakerRequest.ExitTimeMinutesAfter + "min";
else if (_oddsMakerRequest.UseExitAtTimeOfDay)
{
int minutesBeforeClose = _oddsMakerRequest.ExitTimeMinutesBefore;
DateTime marketClose = GuiEnvironment.GetMarketCloseLocalTime();
DateTime timeStop = marketClose.AddMinutes(-minutesBeforeClose);
return timeStop.ToString(GuiEnvironment.AlertTimeShortFormat);
}
else if (_oddsMakerRequest.UseExitTimeFutureOpen)
{
DateTime marketOpen = GuiEnvironment.GetMarketOpenLocalTime();
return "+" + _oddsMakerRequest.ExitTimeOpenDays + " days at " + marketOpen.ToString(GuiEnvironment.AlertTimeShortFormat);
}
else if (_oddsMakerRequest.UseExitTimeFutureClose)
{
DateTime marketClose = GuiEnvironment.GetMarketCloseLocalTime();
return "+" + _oddsMakerRequest.ExitTimeCloseDays + " days at " + marketClose.ToString(GuiEnvironment.AlertTimeShortFormat);
}
}
return "";
}
}
[ColumnInfoAttribute(DisplayName = "Stop Loss", SizeHint = "XXXXXXXXXX")]
public string StopLoss
{
get
{
if (null == _oddsMakerRequest || !_oddsMakerRequest.UseStopLoss)
return "";
else
{
if (_oddsMakerRequest.UseStopFilter)
{
ConfigurationWindowManager configurationWindowManager = AiUtils.ConfigurationWindowManager(_connectionMaster, _config);
Filter filter = configurationWindowManager.FindFilter(_oddsMakerRequest.StopFilter);
if (null != filter)
return filter.LongDescription;
return _oddsMakerRequest.StopFilter;
}
else if (_oddsMakerRequest.StopLoss.HasValue)
{
if (_oddsMakerRequest.UsePercent)
return _oddsMakerRequest.StopLoss.Value.ToString("N2") + "%";
else
return "$" + _oddsMakerRequest.StopLoss.Value.ToString("N2");
}
}
return "";
}
}
[ColumnInfoAttribute(DisplayName = "Profit Target", SizeHint = "XXXXXXXXXX")]
public string ProfitTarget
{
get
{
if (null == _oddsMakerRequest || !_oddsMakerRequest.UseProfitTarget)
return "";
else
{
if (_oddsMakerRequest.UseTargetFilter)
{
ConfigurationWindowManager configurationWindowManager = AiUtils.ConfigurationWindowManager(_connectionMaster, _config);
Filter filter = configurationWindowManager.FindFilter(_oddsMakerRequest.TargetFilter);
if (null != filter)
return filter.LongDescription;
return _oddsMakerRequest.TargetFilter;
}
else if (_oddsMakerRequest.ProfitTarget.HasValue)
{
if (_oddsMakerRequest.UsePercent)
return _oddsMakerRequest.ProfitTarget.Value.ToString("N2") + "%";
else
return "$" + _oddsMakerRequest.ProfitTarget.Value.ToString("N2");
}
}
return "";
}
}
private string _config = "";
[Browsable(false)]
public string Config
{
get { return _config; }
set
{
_config = ScrubConfig(value);
//SetConfig();
}
}
private bool _historyComplete = false;
[Browsable(false)]
public bool HistoryComplete
{
get { return _historyComplete; }
set { _historyComplete = value; }
}
private bool _cloudLinkLoaded = false;
[Browsable(false)]
public bool CloudLinkLoaded
{
get { return _cloudLinkLoaded; }
set { _cloudLinkLoaded = value; }
}
private DateTime? _lastUpdated = null;
[Browsable(false)]
public DateTime? LastUpdated
{
get { return _lastUpdated; }
set { _lastUpdated = value; }
}
private string _cloudLink = "";
[Browsable(false)]
public string CloudLink
{
get { return _cloudLink; }
set
{
_cloudLink = value;
LoadCloudLink();
}
}
private bool _isLong = true;
[ColumnInfoAttribute(DisplayName = "L/S", Format="longshort", SizeHint = "XXXXXXX")]
public bool IsLong
{
get { return _isLong; }
set { _isLong = value; }
}
private string _timeframe = "";
[ColumnInfoAttribute(DisplayName = "Timeframe", SizeHint = "XXXXXXXXXX")]
public string TimeFrame
{
get { return _timeframe; }
set { _timeframe = value; }
}
private DateTime? _optimizedDate = null;
[ColumnInfoAttribute(DisplayName = "Optimized Date", Format = "t")]
public DateTime? OptimizedDate
{
get { return _optimizedDate; }
set { _optimizedDate = value; }
}
private DateTime? _creationDate = null;
[ColumnInfoAttribute(DisplayName = "Creation Date", Format = "t")]
public DateTime? CreationDate
{
get { return _creationDate; }
set { _creationDate = value; }
}
private DateTime? _dataLastUpdated = null;
[ColumnInfoAttribute(DisplayName = "Data Last Updated", Format = "relativetime", DefaultVisible = false, RealTimeUpdates = true)]
public DateTime? DataLastUpdated
{
get { return _dataLastUpdated; }
set { _dataLastUpdated = value; }
}
private StreamingAlerts _streamingAlerts = null;
[Browsable(false)]
public StreamingAlerts StreamingAlerts
{
get { return _streamingAlerts; }
}
private List _strategyTrades = new List();
[Browsable(false)]
public List StrategyTrades
{
get { return _strategyTrades; }
}
[ColumnInfoAttribute(DisplayName = "Today Performance Risk Off", Format = "thermograph", SizeHint = "XXXXXXXXXXXXXXXXXXXXXXX", DefaultVisible = true)]
public Thermograph TodayPerformance { get; set; }
[ColumnInfoAttribute(DisplayName = "Today Performance Risk On", Format = "thermograph", SizeHint = "XXXXXXXXXXXXXXXXXXXXXXX", DefaultVisible = true)]
public Thermograph TodayPerformanceNonExit { get; set; }
[ColumnInfoAttribute(DisplayName = "Today Performance (BP)", Format = "thermograph", SizeHint = "XXXXXXXXXXXXXXXXXXXXXXX", DefaultVisible = true)]
[Browsable(false)]
public Thermograph TodayBasisPoints { get; set; }
private ConnectionMaster _connectionMaster = null;
public event NewAlertHandler onNewAlertReceived;
public event NewStrategyTradeHandler onNewStrategyTradeReceived;
public event CloudLinkLoadedHandler onCloudLinkLoaded;
public event HistoryCompleteHandler HistoryCompleted;
public AIStrategy()
{
_connectionMaster = GuiEnvironment.FindConnectionMaster("");
}
///
/// Allows us to reset signals each day.
///
private DateTime? _lastAlertReceived = null;
private List _allAlerts = new List();
///
/// Adds an alert and it may convert it and add it to StrategyTrades if required. Should be called in order from oldest to most recent.
///
/// Alert
public void AddAlert(RowData rowData)
{
string symbol = rowData.GetSymbol();
DateTime? alertTime = rowData.GetTime();
if (!alertTime.HasValue)
return;
// if last alert received was yesterday, then reset alerts to a new day
if (_lastAlertReceived.HasValue && _lastAlertReceived.Value.ToMarketTimeZone().ToString("yyyy-MM-dd") != alertTime.Value.ToMarketTimeZone().ToString("yyyy-MM-dd"))
ResetAlerts();
if (TooEarly(alertTime.Value))
return;
if (TooLate(alertTime.Value))
return;
_allAlerts.Add(rowData);
// if there are multiple signals per symbol, only add the first one
if (_strategyTrades.Where(x => x.Symbol == symbol).Count() > 0)
return;
StrategyTrade strategyTrade = GetStrategyTrade(rowData);
SetLastSignalData(strategyTrade);
if (null != onNewStrategyTradeReceived)
onNewStrategyTradeReceived(strategyTrade, this);
}
private bool TooEarly(DateTime entryTime)
{
int minutesAfterOpen = GetStartTime();
return GuiEnvironment.GetMarketOpenInMarketTimeZone().AddMinutes(minutesAfterOpen) > entryTime.ToMarketTimeZone();
}
private bool TooLate(DateTime entryTime)
{
int minutesBeforeClose = GetEndTime();
return GuiEnvironment.GetMarketCloseInMarketTimeZone().AddMinutes(-minutesBeforeClose) < entryTime.ToMarketTimeZone();
}
private int GetStartTime()
{
int hours = _oddsMakerRequest.EntryHoursStart;
int minutes = _oddsMakerRequest.EntryMinutesStart;
return hours * 60 + minutes;
}
private int GetEndTime()
{
int hours = _oddsMakerRequest.EntryHoursEnd;
int minutes = _oddsMakerRequest.EntryMinutesEnd;
return hours * 60 + minutes;
}
public StrategyTrade GetStrategyTrade(RowData rowData)
{
string symbol = rowData.GetSymbol();
int? entryTimeT = rowData.GetAsInt("ENTRY_TIME", 0);
DateTime? entryTime = rowData.GetTime();
if (entryTimeT.HasValue && !entryTime.HasValue)
entryTime = ServerFormats.FromTimeT(entryTimeT.Value);
double entryPrice = rowData.GetPrice();
if (entryPrice == 0.0)
entryPrice = rowData.GetAsDouble("ENTRY_PRICE", 0.0);
StrategyTrade strategyTrade = new StrategyTrade();
string id = rowData.GetAsString("ID", "");
bool newTrade = false;
if (_strategyTrades.Where(x => x.ID == id).Count() > 0)
strategyTrade = _strategyTrades.Where(x => x.ID == id).First();
else
{
newTrade = true;
strategyTrade.ID = id;
}
strategyTrade.IsNew = rowData.GetAsDouble("NEW", 0.0) == 1;
//System.Diagnostics.Debug.WriteLine("[GetStrategyTrade] IsNew is " + strategyTrade.IsNew + " for " + strategyTrade.Symbol);
double exitTimeT = rowData.GetAsDouble("EXIT_TIME", 0.0);
if (exitTimeT != 0.0)
strategyTrade.ExitTime = ServerFormats.FromTimeT((int)exitTimeT);
strategyTrade.ExitReason = rowData.GetAsString("EXIT_REASON", "");
if (rowData.GetAsDouble("EXIT_PRICE", 0.0) != 0.0)
strategyTrade.ExitPrice = rowData.GetAsDouble("EXIT_PRICE", 0.0);
strategyTrade.Symbol = symbol;
strategyTrade.EntryTime = entryTime.Value;
strategyTrade.EntryPrice = entryPrice;
strategyTrade.IsLong = _isLong;
if (rowData.GetAsDouble("STOP_PRICE", 0.0) != 0.0)
strategyTrade.StopPrice = rowData.GetAsDouble("STOP_PRICE", 0.0);
else
strategyTrade.StopPrice = GetStopPrice(entryPrice, rowData);
strategyTrade.Shares = GetShares(strategyTrade.EntryPrice, strategyTrade.StopPrice);
if (rowData.GetAsDouble("TARGET_PRICE", 0.0) != 0.0)
strategyTrade.TargetPrice = rowData.GetAsDouble("TARGET_PRICE", 0.0);
else
strategyTrade.TargetPrice = GetTargetPrice(entryPrice, rowData);
if (rowData.GetAsDouble("TIME_STOP", 0.0) != 0.0)
strategyTrade.TimeStop = ServerFormats.FromTimeT((long)rowData.GetAsDouble("TIME_STOP", 0.0)).Value;
else
strategyTrade.TimeStop = GetTimeStop(entryTime);
if (rowData.GetAsDouble("PROFIT", 0.0) != 0)
strategyTrade.Profit = rowData.GetAsDouble("PROFIT", 0.0) * (double)strategyTrade.Shares;
if (rowData.GetAsDouble("NONEXIT_PROFIT", 0.0) != 0)
strategyTrade.NonExitProfit = rowData.GetAsDouble("NONEXIT_PROFIT", 0.0) * (double)strategyTrade.Shares;
else
strategyTrade.SetNonExitProfitFromLast();
int? tradeZone = rowData.GetAsInt("TRADE_ZONE", 0);
if (tradeZone.HasValue)
strategyTrade.TradeZone = tradeZone.Value;
if (rowData.GetAsDouble("PROFIT_CHANGE_15", 0.0) != 0)
strategyTrade.ProfitChange15 = rowData.GetAsDouble("PROFIT_CHANGE_15", 0.0) * (double)strategyTrade.Shares;
if (rowData.GetAsDouble("PROFIT_CHANGE_5", 0.0) != 0)
strategyTrade.ProfitChange5 = rowData.GetAsDouble("PROFIT_CHANGE_5", 0.0) * (double)strategyTrade.Shares;
if (rowData.GetAsDouble("SMART_STOP", 0.0) != 0)
strategyTrade.SmartStop = rowData.GetAsDouble("SMART_STOP", 0.0);
else if (rowData.GetAsDouble("c_SmartStopD", 0.0) != 0)
strategyTrade.SmartStop = rowData.GetAsDouble("c_SmartStopD", 0.0);
strategyTrade.Strategy = this;
_strategyTrades.Add(strategyTrade);
if (newTrade)
{
SetLastSignalData(strategyTrade);
if (null != onNewStrategyTradeReceived)
onNewStrategyTradeReceived(strategyTrade, this);
}
return strategyTrade;
}
///
/// Gets the number of shares that should be used. The stop price is needed when the user has chosen AiPositionSizingType.BasedOnStopLoss.
///
/// The entry price.
/// The stop price.
///
public static int GetShares(double entryPrice, double? stopPrice)
{
if (GuiEnvironment.AiPositionSizingType == GuiEnvironment.AiPositionSizing.FixedShares)
return GuiEnvironment.AiSharesPerTrade;
else if (GuiEnvironment.AiPositionSizingType == GuiEnvironment.AiPositionSizing.FixedDollars)
return (int)(GuiEnvironment.AiDollarsPerTrade / entryPrice);
else if (GuiEnvironment.AiPositionSizingType == GuiEnvironment.AiPositionSizing.BasedOnStopLoss && stopPrice.HasValue && stopPrice.Value > 0)
return (int)Math.Round(GuiEnvironment.AiRiskDollars / Math.Abs(entryPrice - stopPrice.Value));
else
return 1;
}
///
/// Returns the time stop based on the strategy. Might be based on the entry time depending on timed exit selection.
///
/// Entry time of trade
/// DateTime of
private DateTime? GetTimeStop(DateTime? entryTime)
{
DateTime? toReturn = null;
if (_oddsMakerRequest.UseExitTimeFutureClose)
{
int days = _oddsMakerRequest.ExitTimeOpenDays;
toReturn = GuiEnvironment.GetMarketCloseLocalTime(entryTime.Value.AddDays(days));
if (toReturn.Value.DayOfWeek == DayOfWeek.Saturday || toReturn.Value.DayOfWeek == DayOfWeek.Sunday)
toReturn = toReturn.Value.AddDays(2);
}
else if (_oddsMakerRequest.UseExitTimeFutureOpen)
{
int days = _oddsMakerRequest.ExitTimeOpenDays;
toReturn = GuiEnvironment.GetMarketOpenLocalTime(entryTime.Value.AddDays(days));
if (toReturn.Value.DayOfWeek == DayOfWeek.Saturday || toReturn.Value.DayOfWeek == DayOfWeek.Sunday)
toReturn = toReturn.Value.AddDays(2);
}
else if (_oddsMakerRequest.UseExitAtTimeOfDay)
{
int minutesBefore = _oddsMakerRequest.ExitTimeMinutesBefore;
toReturn = GuiEnvironment.GetMarketCloseLocalTime(entryTime.Value).AddMinutes(-minutesBefore);
}
else
{
int minutesAfter = _oddsMakerRequest.ExitTimeMinutesAfter;
toReturn = entryTime.Value.AddMinutes(minutesAfter);
DateTime timeStopMarketClose = GuiEnvironment.GetMarketCloseLocalTime(toReturn.Value);
if (toReturn.Value > timeStopMarketClose)
toReturn = timeStopMarketClose;
}
return toReturn;
}
///
/// Returns the target price for a given entry price.
///
/// Entry price for the trade
/// Row data from alert
/// Target price suitable for using as a limit price.
private double? GetTargetPrice(double entryPrice, RowData alertData)
{
if (null != _oddsMakerRequest && _oddsMakerRequest.UseProfitTarget)
{
if (_oddsMakerRequest.UseTargetFilter && _oddsMakerRequest.TargetFilter != "")
{
double targetDistance = alertData.GetAsDouble("c_" + _oddsMakerRequest.TargetFilter, 0.0);
if (targetDistance == 0.0)
return null;
else if (_isLong)
return entryPrice + targetDistance;
else
return entryPrice - targetDistance;
}
else if (_oddsMakerRequest.ProfitTarget.HasValue)
{
if (_isLong)
if (_oddsMakerRequest.UseDollars)
return entryPrice + _oddsMakerRequest.ProfitTarget.Value;
else
{
double targetPercent = _oddsMakerRequest.ProfitTarget.Value;
double targetDistance = targetPercent * entryPrice;
return entryPrice + targetDistance;
}
else
{
if (_oddsMakerRequest.UseDollars)
return entryPrice - _oddsMakerRequest.ProfitTarget.Value;
else
{
double targetPercent = _oddsMakerRequest.ProfitTarget.Value;
double targetDistance = targetPercent * entryPrice;
return entryPrice - targetDistance;
}
}
}
else
return null;
}
return null;
}
///
/// Returns stop price for a given entry price.
///
/// Entry price for the trade.
/// Row data for the alert
/// Stop price level.
private double? GetStopPrice(double entryPrice, RowData alertData)
{
if ( null != _oddsMakerRequest && _oddsMakerRequest.UseStopLoss)
{
if (_oddsMakerRequest.UseStopFilter && _oddsMakerRequest.StopFilter != "")
{
double stopDistance = alertData.GetAsDouble("c_" + _oddsMakerRequest.StopFilter, 0.0);
if (stopDistance == 0.0)
return null;
else if (_isLong)
return entryPrice - stopDistance;
else
return entryPrice + stopDistance;
}
else if (_oddsMakerRequest.StopLoss.HasValue)
{
if (_isLong)
if (_oddsMakerRequest.UseDollars)
return entryPrice - _oddsMakerRequest.StopLoss.Value;
else
{
double stopPercent = _oddsMakerRequest.StopLoss.Value / 100;
double stopDistance = stopPercent * entryPrice;
return entryPrice - stopDistance;
}
else
{
if (_oddsMakerRequest.UseDollars)
return entryPrice + _oddsMakerRequest.StopLoss.Value;
else
{
double stopPercent = _oddsMakerRequest.StopLoss.Value / 100;
double stopDistance = stopPercent * entryPrice;
return entryPrice + stopDistance;
}
}
}
else
return null;
}
return null;
}
///
/// Resets all private variables for new trading day
///
private void ResetAlerts()
{
_allAlerts.Clear();
_lastAlertReceived = null;
_strategyTrades.Clear();
}
private bool _historyRunning = false;
private History _history;
private List _historyQueue = new List();
public void LoadHistory()
{
DateTime now = GuiEnvironment.GetNowInMarketTimeZone();
DateTime marketOpen = GuiEnvironment.GetMarketOpenInMarketTimeZone();
// don't load history if we're in the pre market
if (now < marketOpen)
{
if (null != HistoryCompleted)
HistoryCompleted(this);
return;
}
HistoryRequest historyRequest = new HistoryRequest();
historyRequest.Config = _config;
historyRequest.EndTime = GuiEnvironment.GetMarketOpenLocalTime();
historyRequest.MaxCount = 100;
historyRequest.StartTime = null;
_history = _connectionMaster.HistoryManager.GetHistory(historyRequest);
_history.HistoryData += _history_HistoryData;
_history.HistoryStatus += _history_HistoryStatus;
_historyQueue.Clear();
_historyRunning = true;
_history.Start();
}
void _history_HistoryStatus(History sender)
{
_historyRunning = sender.HistoryDisposition != HistoryDisposition.Done && sender.HistoryDisposition != HistoryDisposition.NotSent;
if (sender.HistoryDisposition == HistoryDisposition.MoreAvailable)
_history.Start();
if (sender.HistoryDisposition == HistoryDisposition.Done)
LoadHistoryQueue();
}
private void LoadHistoryQueue()
{
try
{
foreach (RowData rowData in _historyQueue)
{
AddAlert(rowData);
}
_historyQueue.Clear();
if (null != onNewAlertReceived)
onNewAlertReceived(null, this);
_historyComplete = true;
if (null != HistoryCompleted)
HistoryCompleted(this);
}
catch (Exception e)
{
string debugView = e.StackTrace;
}
}
void _history_HistoryData(List alerts, History sender)
{
foreach (RowData rowData in alerts)
{
_historyQueue.Insert(0, rowData);
}
}
private void SetLastSignalData(StrategyTrade trade)
{
string symbol = trade.Symbol;
_lastSymbol = symbol;
double price = trade.EntryPrice;
if (price != 0.0)
_lastSignalPrice = price;
// Depending on the local system clock, this could display to the user as in the future.
// If that's the case, just use current system time to avoid that situation.
DateTime? lastSignalTime = trade.EntryTime;
if (lastSignalTime.HasValue)
{
if (lastSignalTime > ServerFormats.Now)
_lastSignalTime = ServerFormats.Now;
else
_lastSignalTime = lastSignalTime;
}
if (trade.StopPrice.HasValue)
_lastStopPrice = trade.StopPrice.Value;
if (trade.TargetPrice.HasValue)
_lastTargetPrice = trade.TargetPrice.Value;
if (trade.SmartStop.HasValue)
_lastSmartStop = trade.SmartStop.Value;
_lastUpdated = ServerFormats.Now;
}
public RowData ToRowData()
{
RowData rowData = new RowData();
rowData.Data.Add("Strategy", _name);
rowData.Data.Add("WinRate", _winrate);
rowData.Data.Add("ProfitFactor", _profitFactor);
rowData.Data.Add("LastSymbol", _lastSymbol);
if (null != _lastSignalTime)
rowData.Data.Add("LastSignalTime", _lastSignalTime);
if (null != _lastSignalPrice)
rowData.Data.Add("LastSignalPrice", _lastSignalPrice);
rowData.Data.Add("TimeFrame", _timeframe);
rowData.Data.Add("IsLong", _isLong);
rowData.Data.Add("MaxTradesPerDay", _maxTradesPerDay);
rowData.Data.Add("TotalTrades", _totalTrades);
rowData.Data.Add("LastUpdated", _lastUpdated);
rowData.Data.Add("RecentPerformance", RecentPerformance);
rowData.Data.Add("Profit", Profit);
rowData.Data.Add("NonExitProfit", NonExitProfit);
rowData.Data.Add("ProfitBasisPoints", ProfitBasisPoints);
rowData.Data.Add("ClosedProfit", ClosedProfit);
rowData.Data.Add("ClosedProfitBasisPoints", ClosedProfitBasisPoints);
rowData.Data.Add("OpenProfit", OpenProfit);
rowData.Data.Add("OpenProfitBasisPoints", OpenProfitBasisPoints);
rowData.Data.Add("TradesToday", TradesToday);
rowData.Data.Add("OpenTradesToday", OpenTradesToday);
rowData.Data.Add("ClosedTradesToday", ClosedTradesToday);
rowData.Data.Add("AvgProfitToday", AvgProfitToday);
rowData.Data.Add("WinRateToday", WinRateToday);
rowData.Data.Add("TimeStop", TimeStop);
rowData.Data.Add("StopLoss", StopLoss);
rowData.Data.Add("ProfitTarget", ProfitTarget);
rowData.Data.Add("TodayPerformance", TodayPerformance);
rowData.Data.Add("TodayBasisPoints", TodayBasisPoints);
rowData.Data.Add("TodayPerformanceNonExit", TodayPerformanceNonExit);
if (_optimizedDate.HasValue)
rowData.Data.Add("OptimizedDate", _optimizedDate);
if (_creationDate.HasValue)
rowData.Data.Add("CreationDate", _creationDate);
if (_lastStopPrice.HasValue)
rowData.Data.Add("LastStopPrice", _lastStopPrice);
if (_lastSmartStop.HasValue)
rowData.Data.Add("LastSmartStop", _lastSmartStop);
if (_lastTargetPrice.HasValue)
rowData.Data.Add("LastTargetPrice", _lastTargetPrice);
if (_dataLastUpdated.HasValue)
rowData.Data.Add("DataLastUpdated", _dataLastUpdated);
rowData.Data.Add("object", this);
return rowData;
}
private void SetConfig()
{
if (null != _streamingAlerts)
_streamingAlerts.Stop();
_streamingAlerts = _connectionMaster.StreamingAlertsManager.GetAlerts(_config);
StartStreamingAlerts();
}
private void StartStreamingAlerts()
{
if (_streamingAlerts.Config != "")
{
_streamingAlerts.StreamingAlertsData += _streamingAlerts_StreamingAlertsData;
_streamingAlerts.StreamingAlertsConfig += _streamingAlerts_StreamingAlertsConfig;
_streamingAlerts.Start();
}
}
void _streamingAlerts_StreamingAlertsConfig(StreamingAlerts source)
{
}
void _streamingAlerts_StreamingAlertsData(List data, StreamingAlerts source)
{
foreach (RowData rowData in data)
{
if (rowData.GetSymbol() != "")
AddAlert(rowData);
if (null != onNewAlertReceived)
onNewAlertReceived(rowData, this);
}
}
private void LoadCloudLink()
{
Dictionary command = TalkWithServer.CreateMessage("command", "cloud_import", "code", _cloudLink);
SendLoadImportCommand(command);
}
private void SendLoadImportCommand(object command)
{
try
{
_connectionMaster.SendManager.SendMessage((Dictionary)command, LoadImportCommandResponse, false, command);
}
catch (Exception e)
{
string debugView = e.StackTrace;
}
}
private void LoadImportCommandResponse(byte[] body, object clientid)
{
if (null == body)
SendLoadImportCommand(clientid);
else
LoadImportCommandResponse(body);
}
private OddsMakerConfiguration.OddsMakerConfigMemento _oddsMakerRequest;
private void LoadImportCommandResponse(byte[] body)
{
XmlNode wrapper = XmlHelper.Get(body).Node(0).Node("LAYOUT");
bool clearPrevious = wrapper.Property("CLEAR_PREVIOUS", false);
XmlDocument layout = XmlHelper.Get(Encoding.UTF8.GetBytes(wrapper.Text()));
if (null == layout)
{
StringBuilder sb = new StringBuilder("Unable to load this item.");
if (wrapper.Text() == "")
sb.Append(" (Not found.)");
else
sb.Append(" (Corrupted.)");
return;
}
_oddsMakerRequest = GetOddsMakerRequest(layout);
_cloudLinkLoaded = true;
if (null != onCloudLinkLoaded)
onCloudLinkLoaded(this);
if (GuiEnvironment.AppConfig.Node("GUI_LIB").Node("AI_STRATEGIES").Node("TRADE_CLIENT").Property("VALUE", 0) == 1)
LoadHistory();
}
private OddsMakerConfiguration.OddsMakerConfigMemento GetOddsMakerRequest(XmlDocument layout)
{
OddsMakerConfiguration.OddsMakerConfigMemento toReturn = new OddsMakerConfiguration.OddsMakerConfigMemento();
if (layout.HasChildNodes)
{
XmlNode layoutNode = layout.FirstChild;
XmlNode windowNode = layoutNode.Node("WINDOW");
if (null != windowNode)
{
try
{
toReturn.Load(windowNode);
}
catch (Exception e)
{
string debugView = e.StackTrace;
}
}
}
return toReturn;
}
internal void RefreshStrategyTrade(StrategyTrade strategyTrade, RowData rowData, LumenWorks.Framework.IO.Csv.CsvReader csvReader = null)
{
strategyTrade.Shares = GetShares(strategyTrade.EntryPrice, strategyTrade.StopPrice);
strategyTrade.Profit = rowData.GetAsDouble("PROFIT", 0.0) * (double)strategyTrade.Shares;
strategyTrade.ProfitChange15 = rowData.GetAsDouble("PROFIT_CHANGE_15", 0.0) * (double)strategyTrade.Shares;
strategyTrade.ProfitChange5 = rowData.GetAsDouble("PROFIT_CHANGE_5", 0.0) * (double)strategyTrade.Shares;
strategyTrade.MaxProfit = rowData.GetAsDouble("MAX_PROFIT", 0.0) * (double)strategyTrade.Shares;
strategyTrade.MinProfit = rowData.GetAsDouble("MIN_PROFIT", 0.0) * (double)strategyTrade.Shares;
strategyTrade.LastPrice = rowData.GetAsDouble("LAST", strategyTrade.EntryPrice);
if (!double.IsNaN(rowData.GetAsDouble("NONEXIT_PROFIT", double.NaN)))
strategyTrade.NonExitProfit = rowData.GetAsDouble("NONEXIT_PROFIT", double.NaN) * (double)strategyTrade.Shares;
else
strategyTrade.SetNonExitProfitFromLast();
strategyTrade.IsNew = rowData.GetAsDouble("NEW", 0.0) == 1;
int? tradeZone = rowData.GetAsInt("TRADE_ZONE", 0);
if (tradeZone.HasValue)
strategyTrade.TradeZone = tradeZone.Value;
if (rowData.GetAsDouble("EXIT_PRICE", 0.0) != 0.0)
strategyTrade.ExitPrice = rowData.GetAsDouble("EXIT_PRICE", 0.0);
else
strategyTrade.ExitPrice = null;
if (rowData.GetAsDouble("EXIT_TIME", 0.0) > 0)
strategyTrade.ExitTime = ServerFormats.FromTimeT((int)rowData.GetAsDouble("EXIT_TIME", 0.0));
else
strategyTrade.ExitTime = null;
if (rowData.GetAsDouble("MAX_PROFIT_TIME", 0.0) != 0.0)
strategyTrade.MaxProfitTime = ServerFormats.FromTimeT((int)rowData.GetAsDouble("MAX_PROFIT_TIME", 0.0));
else
strategyTrade.MaxProfitTime = null;
if (rowData.GetAsDouble("MIN_PROFIT_TIME", 0.0) != 0.0)
strategyTrade.MinProfitTime = ServerFormats.FromTimeT((int)rowData.GetAsDouble("MIN_PROFIT_TIME", 0.0));
else
strategyTrade.MinProfitTime = null;
strategyTrade.ExitReason = rowData.GetAsString("EXIT_REASON", "");
if (null != csvReader && csvReader.GetFieldHeaders().Contains("PROFIT_HISTORY") && csvReader["PROFIT_HISTORY"] != "")
strategyTrade.TodayPerformance = RowDataHelper.GetThermograph(csvReader["PROFIT_HISTORY"], strategyTrade.Shares, 1);
else
strategyTrade.TodayPerformance = null;
if (null != csvReader && csvReader.GetFieldHeaders().Contains("PROFIT_HISTORY_NONEXIT") && csvReader["PROFIT_HISTORY_NONEXIT"] != "")
strategyTrade.TodayPerformanceNonExit = RowDataHelper.GetThermograph(csvReader["PROFIT_HISTORY_NONEXIT"], strategyTrade.Shares, 1);
else
strategyTrade.TodayPerformanceNonExit = null;
strategyTrade.DataLastUpdated = ServerFormats.Now;
}
internal void Dispose()
{
if (null != _streamingAlerts)
{
_streamingAlerts.Stop();
_streamingAlerts = null;
}
if (null != _history)
{
_history.Stop();
_history = null;
}
}
private readonly string SMART_STOP_CODE = "SmartStopD";
private string ScrubConfig(string config)
{
NameValueCollection parameters = HttpUtility.ParseQueryString(config);
bool found = false;
int largestShow = 0;
foreach (string name in parameters.AllKeys)
{
if (name.StartsWith("show"))
{
if (parameters[name] == SMART_STOP_CODE)
found = true;
string number = name.Replace("show", "");
int showNumber = -1;
if (int.TryParse(number, out showNumber))
{
if (showNumber > largestShow)
largestShow = showNumber;
}
}
}
if (!found)
config += "&show" + (largestShow + 1) + "=" + SMART_STOP_CODE;
return config;
}
internal void ComputeTodayPerformance()
{
try
{
if (_strategyTrades.Count > 0)
{
List profits = new List();
List profitsNonExit = new List();
List basisPoints = new List();
bool foundRiskOffProfit = false;
bool foundNonExitProfit = false;
DateTime entryFirstTrade = _strategyTrades.Min(x => x.EntryTime);
if (entryFirstTrade > GuiEnvironment.GetMarketOpenLocalTime(entryFirstTrade) && entryFirstTrade < GuiEnvironment.GetMarketCloseLocalTime(entryFirstTrade))
{
DateTime entryTime = entryFirstTrade;
DateTime now = ServerFormats.Now;
while (entryTime < GuiEnvironment.GetMarketCloseLocalTime(entryTime) && entryTime < now)
{
double profit = 0;
double profitNonExit = 0;
double basisPoint = 0;
foreach (StrategyTrade strategyTrade in _strategyTrades)
{
TimeSpan sinceEntry = entryTime - strategyTrade.EntryTime;
double minutesSinceEntry = sinceEntry.TotalMinutes;
if (minutesSinceEntry > 0)
{
int index = (int)minutesSinceEntry;
TimeSpan sinceExit = TimeSpan.MinValue;
if (strategyTrade.ExitTime.HasValue)
{
sinceExit = entryTime - strategyTrade.ExitTime.Value;
if (sinceExit.TotalMinutes > 0)
{
profit += strategyTrade.Profit.Value;
basisPoint += strategyTrade.ProfitBasisPoints.Value;
}
}
if (null != strategyTrade.TodayPerformance && null != strategyTrade.TodayPerformance.Values && strategyTrade.TodayPerformance.Values.Count >= index + 1)
{
double thisProfit = strategyTrade.TodayPerformance.Values[index];
profit += thisProfit;
double basisPointAtTime = thisProfit / strategyTrade.EntryPrice * 100 * 100;
basisPoint += basisPointAtTime;
foundRiskOffProfit = true;
}
if (null != strategyTrade.TodayPerformanceNonExit && null != strategyTrade.TodayPerformanceNonExit.Values && strategyTrade.TodayPerformanceNonExit.Values.Count >= index + 1)
{
double thisProfitNonExit = strategyTrade.TodayPerformanceNonExit.Values[index];
profitNonExit += thisProfitNonExit;
foundNonExitProfit = true;
}
}
}
if (foundRiskOffProfit)
profits.Add(profit);
if (foundNonExitProfit)
profitsNonExit.Add(profitNonExit);
basisPoints.Add(basisPoint);
entryTime = entryTime.AddMinutes(1);
}
}
if (profits.Count > 0)
{
double max = Math.Max(profits.Max(), Math.Abs(profits.Min()));
TodayPerformance = new Thermograph();
TodayPerformance.Max = max;
TodayPerformance.Mid = 0;
TodayPerformance.MidColor = Color.Black;
TodayPerformance.Min = -max;
TodayPerformance.Values = profits;
}
else
TodayPerformance = null;
if (profitsNonExit.Count > 0)
{
double max = Math.Max(profitsNonExit.Max(), Math.Abs(profitsNonExit.Min()));
TodayPerformanceNonExit = new Thermograph();
TodayPerformanceNonExit.Max = max;
TodayPerformanceNonExit.Mid = 0;
TodayPerformanceNonExit.MidColor = Color.Black;
TodayPerformanceNonExit.Min = -max;
TodayPerformanceNonExit.Values = profitsNonExit;
}
else
TodayPerformanceNonExit = null;
if (basisPoints.Count > 0)
{
double max = Math.Max(basisPoints.Max(), Math.Abs(basisPoints.Min()));
TodayBasisPoints = new Thermograph();
TodayBasisPoints.Max = max;
TodayBasisPoints.Mid = 0;
TodayBasisPoints.MidColor = Color.Black;
TodayBasisPoints.Min = -max;
TodayBasisPoints.Values = basisPoints;
}
}
}
catch (Exception e)
{
string debugView = e.StackTrace;
}
}
}
}