public TradeInfoEventArgs(TRANS_TYPE aType, TradeRecordResult aTrade) { FromUsercode = null; ToUsercode = null; TradeType = aType; Trade = aTrade; }
protected override void OnPumpTrade(TRANS_TYPE aType, TradeRecordResult aRecord) { var handler = OnNewTrade; if (handler != null) { handler(this, new TradeInfoEventArgs(aType, aRecord)); } }
private void Trade2Mysql(TRANS_TYPE aType, TradeRecordResult aRecord, Match j, int leverage, double pov, float pip_coefficient = 1.0f, string aFromCode = null, string aToCode = null) { var sql = string.Empty; var match = j.Groups; aRecord.symbol = match["symbol"].ToString(); using (var cmd = new MySqlCommand()) { cmd.Connection = TradeSource.MysqlSource; if (aType == TRANS_TYPE.TRANS_ADD) { sql = "INSERT INTO `order`(mt4_id, order_id, " + "login, symbol, digits, cmd, volume, open_time, " + "state, open_price, sl, tp, close_time, value_date, " + "expiration, reason, commission, commission_agent, storage, " + "close_price, profit, taxes, magic, comment, internal_id, " + "activation, spread, margin_rate, leverage, pov, pip_coefficient, " + "from_code, to_code) " + " VALUES(@mt4id, @orderid, " + "@login, @symbol, @digits, @cmd, @volume, @open_time, " + "@state, @open_price, @sl, @tp, @close_time, @value_date, " + "@expiration, @reason, @commission, @commission_agent, @storage, " + "@close_price, @profit, @taxes, @magic, @comment, @internal_id, " + "@activation, @spread, @margin_rate, @leverage, @pov, @pip_coefficient, " + "@from_code, @to_code) " + "ON DUPLICATE KEY UPDATE " + "login=@login, symbol=@symbol, digits=@digits, cmd=@cmd, volume=@volume, open_time=@open_time, " + "state=@state, open_price=@open_price, sl=@sl, tp=@tp, close_time=@close_time, value_date=@value_date, " + "expiration=@expiration, reason=@reason, commission=@commission, commission_agent=@commission_agent, storage=@storage, " + "close_price=@close_price, profit=@profit, taxes=@taxes, magic=@magic, comment=@comment, internal_id=@internal_id, " + "activation=@activation, spread=@spread, margin_rate=@margin_rate, " + "leverage=@leverage, pov=@pov, pip_coefficient=@pip_coefficient"; cmd.CommandText = sql; cmd.Parameters.AddWithValue("@mt4id", aRecord.login); cmd.Parameters.AddWithValue("@orderid", aRecord.order); cmd.Parameters.AddWithValue("@login", aRecord.login); cmd.Parameters.AddWithValue("@symbol", aRecord.symbol); cmd.Parameters.AddWithValue("@digits", aRecord.digits); cmd.Parameters.AddWithValue("@cmd", aRecord.cmd); cmd.Parameters.AddWithValue("@volume", aRecord.volume); cmd.Parameters.AddWithValue("@open_time", aRecord.open_time.FromTime32()); cmd.Parameters.AddWithValue("@state", aRecord.state); cmd.Parameters.AddWithValue("@open_price", aRecord.open_price); cmd.Parameters.AddWithValue("@sl", aRecord.sl); cmd.Parameters.AddWithValue("@tp", aRecord.tp); cmd.Parameters.AddWithValue("@close_time", aRecord.close_time.FromTime32()); cmd.Parameters.AddWithValue("@value_date", aRecord.value_date); cmd.Parameters.AddWithValue("@expiration", aRecord.expiration); cmd.Parameters.AddWithValue("@reason", aRecord.reason); cmd.Parameters.AddWithValue("@commission", aRecord.commission); cmd.Parameters.AddWithValue("@commission_agent", aRecord.commission_agent); cmd.Parameters.AddWithValue("@storage", aRecord.storage); cmd.Parameters.AddWithValue("@close_price", aRecord.close_price); cmd.Parameters.AddWithValue("@profit", aRecord.profit); cmd.Parameters.AddWithValue("@taxes", aRecord.taxes); cmd.Parameters.AddWithValue("@magic", aRecord.magic); cmd.Parameters.AddWithValue("@comment", aRecord.comment); cmd.Parameters.AddWithValue("@internal_id", aRecord.internal_id); cmd.Parameters.AddWithValue("@activation", aRecord.activation); cmd.Parameters.AddWithValue("@spread", aRecord.spread); cmd.Parameters.AddWithValue("@margin_rate", aRecord.margin_rate); cmd.Parameters.AddWithValue("@leverage", leverage); cmd.Parameters.AddWithValue("@pov", pov); cmd.Parameters.AddWithValue("@pip_coefficient", pip_coefficient); cmd.Parameters.AddWithValue("@from_code", aFromCode); cmd.Parameters.AddWithValue("@to_code", aToCode); cmd.ExecuteNonQuery(); } else if (aType == TRANS_TYPE.TRANS_DELETE) { sql = "INSERT INTO history(mt4_id, timestamp, order_id, " + "login, symbol, digits, cmd, volume, open_time, " + "state, open_price, sl, tp, close_time, value_date, " + "expiration, reason, commission, commission_agent, storage, " + "close_price, profit, taxes, magic, comment, internal_id, " + "activation, spread, margin_rate, leverage, pov, pip_coefficient, " + "from_code, to_code) " + "VALUES(@mt4id, @timestamp, @orderid, " + "@login, @symbol, @digits, @cmd, @volume, @open_time, " + "@state, @open_price, @sl, @tp, @close_time, @value_date, " + "@expiration, @reason, @commission, @commission_agent, @storage, " + "@close_price, @profit, @taxes, @magic, @comment, @internal_id, " + "@activation, @spread, @margin_rate, @leverage, @pov, @pip_coefficient, " + "@from_code, @to_code) " + "ON DUPLICATE KEY UPDATE " + "login=@login, symbol=@symbol, digits=@digits, cmd=@cmd, volume=@volume, open_time=@open_time, " + "state=@state, open_price=@open_price, sl=@sl, tp=@tp, close_time=@close_time, value_date=@value_date, " + "expiration=@expiration, reason=@reason, commission=@commission, commission_agent=@commission_agent, storage=@storage, " + "close_price=@close_price, profit=@profit, taxes=@taxes, magic=@magic, comment=@comment, internal_id=@internal_id, " + "activation=@activation, spread=@spread, margin_rate=@margin_rate, " + "leverage=@leverage, pov=@pov, pip_coefficient=@pip_coefficient"; cmd.CommandText = sql; cmd.Parameters.AddWithValue("@mt4id", aRecord.login); cmd.Parameters.AddWithValue("@timestamp", aRecord.timestamp.FromTime32()); cmd.Parameters.AddWithValue("@orderid", aRecord.order); cmd.Parameters.AddWithValue("@login", aRecord.login); cmd.Parameters.AddWithValue("@symbol", aRecord.symbol); cmd.Parameters.AddWithValue("@digits", aRecord.digits); cmd.Parameters.AddWithValue("@cmd", aRecord.cmd); cmd.Parameters.AddWithValue("@volume", aRecord.volume); cmd.Parameters.AddWithValue("@open_time", aRecord.open_time.FromTime32()); cmd.Parameters.AddWithValue("@state", aRecord.state); cmd.Parameters.AddWithValue("@open_price", aRecord.open_price); cmd.Parameters.AddWithValue("@sl", aRecord.sl); cmd.Parameters.AddWithValue("@tp", aRecord.tp); cmd.Parameters.AddWithValue("@close_time", aRecord.close_time.FromTime32()); cmd.Parameters.AddWithValue("@value_date", aRecord.value_date); cmd.Parameters.AddWithValue("@expiration", aRecord.expiration); cmd.Parameters.AddWithValue("@reason", aRecord.reason); cmd.Parameters.AddWithValue("@commission", aRecord.commission); cmd.Parameters.AddWithValue("@commission_agent", aRecord.commission_agent); cmd.Parameters.AddWithValue("@storage", aRecord.storage); cmd.Parameters.AddWithValue("@close_price", aRecord.close_price); cmd.Parameters.AddWithValue("@profit", aRecord.profit); cmd.Parameters.AddWithValue("@taxes", aRecord.taxes); cmd.Parameters.AddWithValue("@magic", aRecord.magic); cmd.Parameters.AddWithValue("@comment", aRecord.comment); cmd.Parameters.AddWithValue("@internal_id", aRecord.internal_id); cmd.Parameters.AddWithValue("@activation", aRecord.activation); cmd.Parameters.AddWithValue("@spread", aRecord.spread); cmd.Parameters.AddWithValue("@margin_rate", aRecord.margin_rate); cmd.Parameters.AddWithValue("@leverage", leverage); cmd.Parameters.AddWithValue("@pov", pov); cmd.Parameters.AddWithValue("@pip_coefficient", pip_coefficient); cmd.Parameters.AddWithValue("@from_code", aFromCode); cmd.Parameters.AddWithValue("@to_code", aToCode); cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); cmd.CommandText = "DELETE FROM `order` WHERE order_id = @orderid"; cmd.Parameters.AddWithValue("@orderid", aRecord.order); cmd.ExecuteNonQuery(); } } }
private static void CopyNewTrade(TradeRecordResult trade, int mt4_from, IEnumerable <dynamic> items, DateTime trade_date, MT4Wrapper api, double balance, DockServer dock, int source) { foreach (var i in items) { var mt4_to = 0; try { mt4_to = i.to_mt4; var to_source = i.source; var amount = i.amount; Utils.CommonLog.Info("将[MT4:{0}]的订单{1}复制给[MT4:{2}]", mt4_from, trade.order, mt4_to); var volume = ForexMath.CopyTransform(balance, trade.volume, amount); var now = TimeServer.Now; if (to_source == 0 && Math.Abs((now - trade_date).TotalSeconds) > 1) { Utils.CommonLog.Info("将[MT4:{0}]的订单{1}复制给[MT4:{2}],时间过长,单据时间:{3},此时:{4}", mt4_from, trade.order, mt4_to, trade_date, now); continue; } if (volume <= 0) { Utils.CommonLog.Info("将[MT4:{0}]的订单{1}复制给[MT4:{2}],复制单成交量过小,跳过复制", mt4_from, trade.order, mt4_to); continue; } var args = new TradeTransInfoArgsResult { type = TradeTransInfoTypes.TT_BR_ORDER_OPEN, cmd = (short)trade.cmd, orderby = mt4_to, price = trade.open_price, symbol = trade.symbol, volume = volume, comment = "copy", }; var result = api.TradeTransaction(ref args); if (result == RET_CODE.RET_OK) { var sql = "INSERT INTO copy_order(mt4_from, mt4_to, order_from, order_to," + "direction, volume, source) VALUES(@mt4_from, @mt4_to, @order_from," + "@order_to, @direction, @volume, @source)"; using (var cmd = new SQLiteCommand(sql, dock.CopySource)) { cmd.Parameters.AddWithValue("@mt4_from", mt4_from); cmd.Parameters.AddWithValue("@mt4_to", mt4_to); cmd.Parameters.AddWithValue("@order_from", trade.order); cmd.Parameters.AddWithValue("@order_to", args.order); cmd.Parameters.AddWithValue("@direction", args.cmd); cmd.Parameters.AddWithValue("@volume", volume); cmd.Parameters.AddWithValue("@source", source); cmd.ExecuteNonQuery(); } Utils.CommonLog.Info("将[MT4:{0}]的订单{1}复制给[MT4:{2}],复制成功", mt4_from, trade.order, mt4_to); } else { Utils.CommonLog.Warn("将[MT4:{0}]的订单{1}复制给[MT4:{2}],复制结果失败,原因:{5}", mt4_from, trade.order, mt4_to, result); } } catch (Exception e) { Utils.CommonLog.Error("Copy订单{0}复制给MT4[{1}]出现问题{2},{3}", trade.order, mt4_to, e.Message, e.StackTrace); } } }
private static void CopyBalanceTrade(TradeRecordResult trade, int mt4_from, IEnumerable <dynamic> items, MT4Wrapper api, DockServer dock, int source) { var key = string.Empty; foreach (var i in items) { var copy_order = 0; try { copy_order = i.order_to; var volume = i.volume; var to_source = i.source == 0 ? "real" : "demo"; var mt4_to = i.mt4_to; Utils.CommonLog.Info("自动平掉复制订单{0}的copy订单{1},成交量{2},位置{3}", trade.order, copy_order, volume, to_source); var args = new TradeTransInfoArgsResult { type = TradeTransInfoTypes.TT_BR_ORDER_CLOSE, cmd = (short)trade.cmd, order = copy_order, price = trade.close_price, volume = volume, }; var result = api.TradeTransaction(ref args); if (result == RET_CODE.RET_OK) { var sql = string.Empty; sql = "INSERT INTO pre_delete(order_from) VALUES(@order_from)"; using (var cmd = new SQLiteCommand(sql, dock.CopySource)) { cmd.Parameters.AddWithValue("@order_from", trade.order); cmd.ExecuteNonQuery(); } double amount = 0.0; sql = "SELECT amount FROM copy WHERE from_mt4 = @mt4_from AND to_mt4 = @mt4_to"; using (var cmd = new SQLiteCommand(sql, dock.CopySource)) { cmd.Parameters.AddWithValue("@mt4_from", mt4_from); cmd.Parameters.AddWithValue("@mt4_to", mt4_to); var amount_obj = cmd.ExecuteScalar(); if (amount_obj == null) { Utils.CommonLog.Warn("收到一个很奇怪的需要结算盈利的copy单,找不到copy表记录" + "单号{0}, MT4{1}", trade.order, trade.login); continue; } else { amount = Convert.ToDouble(amount_obj); } } //算钱模式 var order = api.AdmTradesRequest(copy_order, false); if (order.profit + order.storage + amount < 0) { amount = 0.0; } else { amount += trade.profit + trade.storage; } sql = "UPDATE copy SET amount=@amount WHERE from_mt4=@mt4_from AND to_mt4=@mt4_to"; using (var cmd = new SQLiteCommand(sql, dock.CopySource)) { cmd.Parameters.AddWithValue("@mt4_from", mt4_from); cmd.Parameters.AddWithValue("@mt4_to", mt4_to); cmd.Parameters.AddWithValue("@amount", amount); cmd.ExecuteNonQuery(); } sql = "SELECT user_code FROM user WHERE mt4=@mt4_id"; using (var cmd = new SQLiteCommand(sql, dock.CopySource)) { cmd.Parameters.AddWithValue("@mt4_id", mt4_to); var user_code_obj = cmd.ExecuteScalar(); if (user_code_obj != null) { key = string.Format(RedisCopyActivityTemplate, trade.login); dock.RedisCopy.ZAdd(key, TimeServer.Now.ToTime32().ToString(), user_code_obj.ToString()); Utils.CommonLog.Info("自动平掉复制订单{0}的copy订单{1}成功", trade.order, copy_order); } else { Utils.CommonLog.Info("Copy平仓复制订单{0}的copy订单{1}无法反查邀请码信息,MT4账号{2}", trade.order, copy_order, mt4_to); } } } else { Utils.CommonLog.Warn("自动平掉复制订单{0}的copy订单{1}失败,原因{2}", trade.order, copy_order, result); } } catch (Exception e) { Utils.CommonLog.Error("子订单{0}平仓出现问题{1},{2}", copy_order, e.Message, e.StackTrace); } } }
private void StartLink(TRANS_TYPE trade_type, TradeRecordResult trade) { var dock = new DockServer(); try { using (var db = dock.CopySource) { var sql = string.Empty; var mt4_from = trade.login; var jss = new JavaScriptSerializer(); if ((trade_type == TRANS_TYPE.TRANS_ADD || trade_type == TRANS_TYPE.TRANS_UPDATE) && trade.cmd <= (int)Utils.TRADE_COMMAND.OP_SELL) { var trade_date = trade.timestamp.FromTime32(); Utils.CommonLog.Info("MT4:{0}的订单{1}已收到", mt4_from, trade.order); try { sql = "SELECT * FROM copy WHERE from_mt4=@mt4_id"; var lst = new List <dynamic>(); using (var cmd = new SQLiteCommand(sql, db)) { cmd.Parameters.AddWithValue("@mt4_id", mt4_from); using (var copy_reader = cmd.ExecuteReader()) { while (copy_reader.Read()) { dynamic copy_item = new ExpandoObject(); copy_item.from_mt4 = int.Parse(copy_reader["from_mt4"] .ToString()); copy_item.to_mt4 = int.Parse(copy_reader["to_mt4"] .ToString()); copy_item.source = int.Parse(copy_reader["source"] .ToString()); copy_item.amount = double.Parse(copy_reader["amount"] .ToString()); lst.Add(copy_item); } } } var real_copy = lst.Where(i => i.source == 0); var demo_copy = lst.Where(i => i.source != 0); if (lst.Count > 0) { MT4Wrapper api = null; var equity = 0.0; var balance = 0.0; var free = 0.0; using (api = Poll.New()) { api.GetEquity(mt4_from, ref equity, ref free, ref balance); } if (real_copy.Count() > 0) { using (api = Poll.New()) { CopyNewTrade(trade, mt4_from, real_copy, trade_date, api, balance, dock, 0); } } if (demo_copy.Count() > 0) { using (api = Poll.DemoAPI()) { CopyNewTrade(trade, mt4_from, demo_copy, trade_date, api, balance, dock, 1); } } } } catch (Exception e) { Utils.CommonLog.Error("执行copy功能出现故障,订单号{0},{1},{2}", trade.order, e.Message, e.StackTrace); } } if (trade_type == TRANS_TYPE.TRANS_DELETE && !string.IsNullOrWhiteSpace(trade.symbol)) { try { sql = "SELECT * FROM copy_order WHERE order_from=@order_id"; var lst = new List <dynamic>(); using (var cmd = new SQLiteCommand(sql, db)) { cmd.Parameters.AddWithValue("@order_id", trade.order); using (var copy_reader = cmd.ExecuteReader()) { while (copy_reader.Read()) { dynamic copy_item = new ExpandoObject(); copy_item.mt4_from = int.Parse(copy_reader["mt4_from"] .ToString()); copy_item.mt4_to = int.Parse(copy_reader["mt4_to"] .ToString()); copy_item.source = int.Parse(copy_reader["source"] .ToString()); copy_item.order_from = int.Parse(copy_reader["order_from"] .ToString()); copy_item.order_to = int.Parse(copy_reader["order_to"] .ToString()); copy_item.direction = int.Parse(copy_reader["direction"] .ToString()); copy_item.volume = int.Parse(copy_reader["volume"] .ToString()); lst.Add(copy_item); } } } if (lst.Count > 0) { Utils.CommonLog.Info("可复制订单{0}已平仓,copy数量{1}", trade.order, lst.Count); } var real_copy = lst.Where(i => i.source == 0); var demo_copy = lst.Where(i => i.source != 0); MT4Wrapper api = null; if (real_copy.Count() > 0) { using (api = Poll.New()) { CopyBalanceTrade(trade, mt4_from, real_copy, api, dock, 0); } } if (demo_copy.Count() > 0) { using (api = Poll.DemoAPI()) { CopyBalanceTrade(trade, mt4_from, demo_copy, api, dock, 1); } } } catch (Exception e) { Utils.CommonLog.Error("执行copy平仓功能出现故障,订单号{0},{1},{2}", trade.order, e.Message, e.StackTrace); } } } } catch (Exception e) { Utils.CommonLog.Error(string.Format("复制StartLink出错,{0},{1}", e.Message, e.StackTrace)); } }