/// <summary> /// Ends the experiment session. /// </summary> public void End() { if (hasInitialised) { if (inTrial) { currentTrial.End(); } SaveResults(); // raise cleanup event if (cleanUp != null) { cleanUp(); } // end FileIOManager - forces immediate writing of all files fileIOManager.End(); currentTrialNum = 0; currentBlockNum = 0; blocks = new List <Block>(); _hasInitialised = false; Debug.Log("Ended session."); onSessionEnd.Invoke(this); } }
private PokerService() { _socket = IO.Socket(FHConfig.GetInstance().GetHost()); _socket.On("sessions", data => { var session = JsonConvert.DeserializeObject <Session>((string)data); SessionEvent?.Invoke(this, new SessionEventArgs { Session = session }); }); _socket.On("sessionUpdated", data => { var user = JsonConvert.DeserializeObject <User>((string)data); SessionUpdatedEvent?.Invoke(this, new UserEventArgs { User = user }); }); _socket.On("voteUpdated", data => { var user = JsonConvert.DeserializeObject <User>((string)data); SessionVoteEvent?.Invoke(this, new UserEventArgs { User = user }); }); _socket.On("finish", data => { SessionFinishEvent?.Invoke(this, (string)data); }); }
/// <summary> /// Initialises a Session /// </summary> /// <param name="experimentName">A name for the experiment</param> /// <param name="participantId">A unique ID associated with a participant</param> /// <param name="baseFolder">Location where data should be stored</param> /// <param name="sessionNumber">A number for the session (optional: default 1)</param> /// <param name="participantDetails">Dictionary of information about the participant to be used within the experiment (optional: default null)</param> /// <param name="settings">A Settings instance (optional: default empty settings)</param> public void Begin(string experimentName, string participantId, int sessionNumber = 1, Dictionary <string, object> participantDetails = null, Settings settings = null) { this.experimentName = experimentName; ppid = participantId; number = sessionNumber; if (participantDetails == null) { participantDetails = new Dictionary <string, object>(); } this.participantDetails = participantDetails; if (settings == null) { settings = Settings.empty; } this.settings = settings; // Initialise DataHandlers foreach (var dataHandler in ActiveDataHandlers) { dataHandler.Initialise(this); dataHandler.SetUp(); } _hasInitialised = true; Utilities.UXFDebugLog("Beginning session."); // raise the session events onSessionBegin.Invoke(this); }
/// <summary> /// Ends the experiment session. /// </summary> public void End() { if (hasInitialised) { isEnding = true; if (InTrial) { try { CurrentTrial.End(); } catch (Exception e) { Debug.LogException(e); } } SaveResults(); try { preSessionEnd.Invoke(this); } catch (Exception e) { Debug.LogException(e); } // end DataHandler - forces completion of tasks foreach (var dataHandler in ActiveDataHandlers) { dataHandler.CleanUp(); } try { onSessionEnd.Invoke(this); } catch (Exception e) { Debug.LogException(e); } currentTrialNum = 0; currentBlockNum = 0; blocks = new List <Block>(); _hasInitialised = false; Debug.Log("Ended session."); isEnding = false; } }
/// <summary> /// Ends the experiment session. /// </summary> public void End() { if (hasInitialised) { isEnding = true; if (InTrial) { try { CurrentTrial.End(); } catch (Exception e) { Debug.LogException(e); } } SaveResults(); try { preSessionEnd.Invoke(this); } catch (Exception e) { Debug.LogException(e); } if (storeSessionSettings) { // copy Settings to session folder SaveJSONSerializableObject(new Dictionary <string, object>(settings.baseDict), "settings", dataType: UXFDataType.Settings); } if (storeParticipantDetails) { // copy participant details to session folder // we convert to a DataTable because we know the dictionary will be "flat" (one value per key) UXFDataTable ppDetailsTable = new UXFDataTable(participantDetails.Keys.ToArray()); var row = new UXFDataRow(); foreach (var kvp in participantDetails) { row.Add((kvp.Key, kvp.Value)); } ppDetailsTable.AddCompleteRow(row); var ppDetailsLines = ppDetailsTable.GetCSVLines(); SaveDataTable(ppDetailsTable, "participant_details", dataType: UXFDataType.ParticipantDetails); } // end DataHandlers - forces completion of tasks foreach (var dataHandler in ActiveDataHandlers) { try { dataHandler.CleanUp(); } catch (Exception e) { Debug.LogException(e); } } try { onSessionEnd.Invoke(this); } catch (Exception e) { Debug.LogException(e); } currentTrialNum = 0; currentBlockNum = 0; blocks = new List <Block>(); _hasInitialised = false; Utilities.UXFDebugLog("Ended session."); isEnding = false; } }
/// <summary> /// Initialises a Session /// </summary> /// <param name="experimentName">A name for the experiment</param> /// <param name="participantId">A unique ID associated with a participant</param> /// <param name="baseFolder">Location where data should be stored</param> /// <param name="sessionNumber">A number for the session (optional: default 1)</param> /// <param name="participantDetails">Dictionary of information about the participant to be used within the experiment (optional: default null)</param> /// <param name="settings">A Settings instance (optional: default empty settings)</param> public void Begin(string experimentName, string participantId, int sessionNumber = 1, Dictionary <string, object> participantDetails = null, Settings settings = null) { this.experimentName = experimentName; ppid = participantId; number = sessionNumber; if (participantDetails == null) { participantDetails = new Dictionary <string, object>(); } this.participantDetails = participantDetails; if (settings == null) { settings = Settings.empty; } this.settings = settings; // Initialise DataHandlers foreach (var dataHandler in ActiveDataHandlers) { dataHandler.Initialise(this); dataHandler.SetUp(); } _hasInitialised = true; // raise the session events onSessionBegin.Invoke(this); if (storeSessionSettings) { // copy Settings to session folder SaveJSONSerializableObject(new Dictionary <string, object>(settings.baseDict), "settings", dataType: UXFDataType.Settings); } if (storeParticipantDetails) { // copy participant details to session folder // we convert to a DataTable because we know the dictionary will be "flat" (one value per key) UXFDataTable ppDetailsTable = new UXFDataTable(participantDetails.Keys.ToArray()); var row = new UXFDataRow(); foreach (var kvp in participantDetails) { row.Add((kvp.Key, kvp.Value)); } ppDetailsTable.AddCompleteRow(row); var ppDetailsLines = ppDetailsTable.GetCSVLines(); SaveDataTable(ppDetailsTable, "participant_details", dataType: UXFDataType.ParticipantDetails); } }
/// <summary> /// Initialises a Session /// </summary> /// <param name="experimentName">A name for the experiment</param> /// <param name="participantId">A unique ID associated with a participant</param> /// <param name="baseFolder">Location where data should be stored</param> /// <param name="sessionNumber">A number for the session (optional: default 1)</param> /// <param name="participantDetails">Dictionary of information about the participant to be used within the experiment (optional: default null)</param> /// <param name="settings">A Settings instance (optional: default empty settings)</param> public void Begin(string experimentName, string participantId, string baseFolder, int sessionNumber = 1, Dictionary <string, object> participantDetails = null, Settings settings = null) { baseFolder = Path.IsPathRooted(baseFolder) ? baseFolder : Path.Combine(Directory.GetCurrentDirectory(), baseFolder); if (!Directory.Exists(baseFolder)) { throw new DirectoryNotFoundException(string.Format("Initialising session failed, cannot find {0}", baseFolder)); } this.experimentName = experimentName; ppid = participantId; number = sessionNumber; basePath = baseFolder; if (participantDetails == null) { participantDetails = new Dictionary <string, object>(); } this.participantDetails = participantDetails; if (settings == null) { settings = Settings.empty; } this.settings = settings; // setup folders InitFolder(); // Initialise FileIOManager if (!fileIOManager.IsActive) { fileIOManager.Begin(); } _hasInitialised = true; // raise the session events onSessionBegin.Invoke(this); // copy participant details to session folder WriteDictToSessionFolder( new Dictionary <string, object>(participantDetails), // makes a copy "participant_details"); // copy Settings to session folder WriteDictToSessionFolder( new Dictionary <string, object>(settings.baseDict), // makes a copy "settings"); }
private void CheckSessionOrders(long dotime) { #region objectLock if (SessionOrders.Count == 0 && checkRunning) { return; } if (checkSessionDoTime == -1) { lock (objectLock) { if (checkSessionDoTime == -1) { checkSessionDoTime = dotime; } } } #endregion if (checkSessionDoTime == dotime) { try { //判断Order与缓存验证互斥操作 lock (sessionLock) { if (SessionOrders.Count == 0 || checkRunning) { return; } checkRunning = true; #region 判断单边、平仓 if (SessionOrders.Count == 0) { return; } var lastFilledOrderTime = SessionOrders.Max(a => a.create_date); int buycount = SessionOrders.Count(a => a.type == "buy"); int sellcount = SessionOrders.Count(a => a.type == "sell"); //if (buycount == 0 || sellcount == 0 || Utils.GetDateTimeDec(-1000) < lastFilledOrderTime ) bool Reset = false; if (buycount == 0 || sellcount == 0) { if (Utils.GetUtcTimeDec(-180) > lastFilledOrderTime) { Reset = true; Log4NetUtility.Info("Reset", $"单边3分钟"); } } if (Utils.GetUtcTimeDec(-600) > lastFilledOrderTime) { Reset = true; Log4NetUtility.Info("Reset", $"缓存静止10分钟"); } if (Reset) { SessionEvent?.Invoke(null, new SessionEventArgs(SessionEventType.Reset)); return; } #endregion #region 撤销重复 bool flag = false; var doubleorder = SessionOrders.FirstOrDefault(b => SessionOrders.Exists(a => a.price == b.price && a.type == b.type && a.order_id != b.order_id)); if (doubleorder != null) { SessionEvent?.Invoke(null, new SessionEventArgs(SessionEventType.DoubleOrder, new List <Order>() { doubleorder })); //Log4NetUtility.Info("", "存在重复缓存单 Price:" + doubleorder.price); //string msg = ""; #region //CancelOrder //CancelOrder cancel = robotTrade.CancelOrder(symbol, doubleorder.order_id); //if (cancel.result) //{ // sessionOrders.Remove(doubleorder); // doubleorder.status = "3"; // //DbHelper.DBSaveChange(doubleorder, "UpDate"); // Log4NetUtility.Info("缓存单验证", "已撤销重复Order。id:" + Utils.ShortID(doubleorder.order_id) + " Price:" + doubleorder.price); // CheckSessionDoTime = -1; // return; //} //else //{ // string errmsg = ""; // if (cancel.error_code.Contains("3008")) // { // sessionOrders.Remove(doubleorder); // //DbHelper.CreateInstance().RemoveOrder(doubleorder); // errmsg = "已清除脏数据Order。id:" + Utils.ShortID(doubleorder.order_id) + " Price:" + doubleorder.price; // } // else // { // errmsg = "撤销重复Order失败。id:" + Utils.ShortID(doubleorder.order_id) + " msg:" + cancel.error_code + cancel.msg; // } // Log4NetUtility.Info("缓存单验证", errmsg); // //DbHelper.CreateInstance().AddErrInfo("缓存单验证", errmsg); //} #endregion flag = true; } #endregion #region 撤销异常价格 List <Order> errPriceOrders = SessionOrders.Where(a => a.price < 50m).ToList(); if (errPriceOrders.Count > 0) { SessionEvent?.Invoke(null, new SessionEventArgs(SessionEventType.ErrPrice, errPriceOrders)); foreach (var order in errPriceOrders) { //Log4NetUtility.Info("", "存在异常价格存单 Price:" + order.price); #region CancelOrder //CancelOrder cancel = robotTrade.CancelOrder(symbol, order.order_id); //if (cancel.result) //{ // sessionOrders.Remove(order); // order.status = "3"; // //DbHelper.DBSaveChange(doubleorder, "UpDate"); // Log4NetUtility.Info("缓存单验证", "已撤销重复Order。id:" + Utils.ShortID(order.order_id) + " Price:" + order.price); //} //else //{ // string errmsg = ""; // if (cancel.error_code.Contains("3008")) // { // sessionOrders.Remove(order); // //DbHelper.CreateInstance().RemoveOrder(doubleorder); // errmsg = "已清除脏数据Order。id:" + Utils.ShortID(order.order_id) + " Price:" + order.price; // } // else // { // errmsg = "撤销重复Order失败。id:" + Utils.ShortID(doubleorder.order_id) + " msg:" + cancel.error_code + cancel.msg; // } // Log4NetUtility.Info("缓存单验证", errmsg); // //DbHelper.CreateInstance().AddErrInfo("缓存单验证", errmsg); //} #endregion } //CheckSessionDoTime = -1; flag = true; } if (flag) { return; } #endregion #region 调整订单数量 if return int deff = buycount + sellcount - info.buyOrderCount - info.sellOrderCount; #region 多单 return if (deff > 1) { Log4NetUtility.Info("MoreOrder", string.Format("Order数大于初始值,现值:{0} 初始:{1}", buycount + sellcount, info.buyOrderCount + info.sellOrderCount)); Order cancelOrder; if (buycount > sellcount) { cancelOrder = SessionOrders.OrderBy(a => a.price).First(); } else { cancelOrder = SessionOrders.OrderBy(a => a.price).Last(); } SessionEvent?.Invoke(null, new SessionEventArgs(SessionEventType.MoreOrder, new List <Order>() { cancelOrder })); return; } #endregion #region 少单 return if (deff < -1) { Log4NetUtility.Info("LessOrder", string.Format("Order数小于初始值,现值{0} 初始{1}", buycount + sellcount, info.buyOrderCount + info.sellOrderCount)); SessionEvent?.Invoke(null, new SessionEventArgs(SessionEventType.LessOrder)); return; } #endregion #endregion #region 判断补充丢单 if return var lostorder = GetLostOrder(SessionOrders); if (lostorder != null) { SessionEvent?.Invoke(null, new SessionEventArgs(SessionEventType.LostOrder, new List <Order>() { lostorder })); return; } #endregion } } #region catch\finally catch (Exception e) { //DbHelper.CreateInstance().AddErrInfo("缓存验证", e); Log4NetUtility.Error("缓存验证", Utils.Exception2String(e)); DbHelper.CreateInstance().AddError("缓存验证", e); } finally { checkSessionDoTime = -1; checkRunning = false; } #endregion } }