public StrategyActionData GAStrategy(int nn_output, int amount, SimAccount ac) { var ad = new StrategyActionData(); var pred_side = nn_output == 1 ? "buy" : "sell"; if (nn_output == 0) { pred_side = "no"; } if (pred_side == "buy" && ac.holding_data.holding_side == "") { ad.add_action("entry", pred_side, "market", 0, amount, -1, "entry order"); } else if (pred_side == "buy" && ac.holding_data.holding_side == "sell") { ad.add_action("entry", pred_side, "market", 0, ac.holding_data.holding_size + amount, -1, "exit & entry order"); } else if (pred_side == "sell" && ac.holding_data.holding_side == "") { ad.add_action("entry", pred_side, "market", 0, amount, -1, "entry order"); } else if (pred_side == "sell" && ac.holding_data.holding_side == "buy") { ad.add_action("entry", pred_side, "market", 0, ac.holding_data.holding_size + amount, -1, "exit & entry order"); } return(ad); }
/* * */ public StrategyActionData entryTimingPTLCStrategy(int i, double max_amount, SimAccount ac, string side, int num_entry, int entry_interval, double pt_ratio, double lc_ratio) { var ad = new StrategyActionData(); var a = max_amount / (Convert.ToDouble(1 + num_entry) * Convert.ToDouble(num_entry) / 2.0); var entry_amount = (ac.holding_data.holding_entry_num + 1) * a; if (ac.holding_data.holding_entry_num >= num_entry - 1) { entry_amount = max_amount - ac.holding_data.holding_size; } var otype = "market"; //0:pt if (ac.holding_data.holding_side != "" && ac.performance_data.unrealized_pl_ratio >= pt_ratio) { ad.add_action("entry", ac.holding_data.holding_side == "buy" ? "sell" : "buy", otype, 0, ac.holding_data.holding_size, -1, "0. Profit Taking"); } //1:lc else if (ac.holding_data.holding_side != "" && ac.performance_data.unrealized_pl_ratio <= lc_ratio) { ad.add_action("entry", ac.holding_data.holding_side == "buy" ? "sell" : "buy", otype, 0, ac.holding_data.holding_size, -1, "1. Loss Cut"); } //2:Entry else if (ac.holding_data.holding_entry_num < num_entry && ac.holding_data.holding_size < max_amount && i - ac.holding_data.holding_i >= entry_interval) { ad.add_action("entry", side, otype, 0, entry_amount, -1, "2. Entry"); } //3:Holding max amount, no action else if (ac.holding_data.holding_size < max_amount) { } return(ad); }
/*常にlimit entry、num order = 1以下。 * 1. pred_side == order_sideのときは、max_amountに達するまでamountを追加してupdate price * 2. pred_side != order_sideのときは、cancel all orders, pred_sideにamountのlimit orderを出す。 * 3. pred_side == holding_sideのときは、max_amountに達するまでamountのlimit orderを出す。 * 4. pred_side != holding_sideのときは、amount + holding_sizeのlimit orderを出す * */ public StrategyActionData GALimitStrategy(int i, int nn_output, int amount, int max_amount, SimAccount ac) { var ad = new StrategyActionData(); var output_action_list = new string[] { "no", "buy", "sell", "cancel" }; var pred_side = output_action_list[nn_output]; if (pred_side == "no") { } else if (pred_side == "cancel") { if (ac.order_data.getLastSerialNum() > 0) { ad.add_action("cancel", "", "", 0, 0, ac.order_data.order_serial_list.Last(), "cancel all order"); } } else { if (pred_side == ac.order_data.getLastOrderSide()) //1. { if (ac.holding_data.holding_size + ac.order_data.getLastOrderSize() < max_amount) { ad.add_action("update amount", pred_side, "limit", 0, ac.order_data.getLastOrderSize() + amount, ac.order_data.order_serial_list.Last(), "update order amount"); } //if ((ac.order_data.getLastOrderSide() == "buy" && MarketData.Close[i] > ac.order_data.getLastOrderPrice()) || (ac.order_data.getLastOrderSide() == "sell" && MarketData.Close[i] < ac.order_data.getLastOrderPrice())) if (ac.order_data.getLastOrderPrice() != MarketData.Close[i]) { ad.add_action("update price", pred_side, "limit", MarketData.Close[i], ac.order_data.getLastOrderSize(), ac.order_data.order_serial_list.Last(), "update order price"); } } else if (pred_side != ac.order_data.getLastOrderSide()) //2. { if (ac.order_data.getLastOrderSide() != "") { ad.add_action("cancel", "", "", 0, 0, ac.order_data.order_serial_list.Last(), "cancel all order"); } if ((pred_side == ac.holding_data.holding_side && ac.holding_data.holding_size + amount > max_amount) == false) { ad.add_action("entry", pred_side, "limit", MarketData.Close[i], amount, -1, "entry order"); } } else if (pred_side == ac.holding_data.holding_side && ac.holding_data.holding_size + ac.order_data.getLastOrderSize() < max_amount) //3. { ad.add_action("entry", pred_side, "limit", MarketData.Close[i], amount, -1, "entry order"); } else if (pred_side != ac.holding_data.holding_side && ac.order_data.getLastOrderSide() != pred_side) //4. { ad.add_action("entry", pred_side, "limit", MarketData.Close[i], Math.Min(ac.holding_data.holding_size + amount, ac.holding_data.holding_size + max_amount), -1, "entry order"); } } return(ad); }
public StrategyActionData entryTimingPTLCPriceChangeStrategy(int i, double max_amount, SimAccount ac, int num_entry, int entry_interval, double pt_ratio, double lc_ratio, int buy_price_change_minutes, double buy_price_change_ratio, int sell_price_change_minutes, double sell_price_change_ratio) { var ad = new StrategyActionData(); var a = max_amount / (Convert.ToDouble(1 + num_entry) * Convert.ToDouble(num_entry) / 2.0); var entry_amount = (ac.holding_data.holding_entry_num + 1) * a; if (ac.holding_data.holding_entry_num >= num_entry - 1) { entry_amount = max_amount - ac.holding_data.holding_size; } var price_change_trigger = ""; if ((MarketData.Close[i] - MarketData.Close[i - buy_price_change_minutes]) / MarketData.Close[i - buy_price_change_minutes] <= buy_price_change_ratio) { price_change_trigger = "buy"; } else if ((MarketData.Close[i] - MarketData.Close[i - sell_price_change_minutes]) / MarketData.Close[i - sell_price_change_minutes] >= sell_price_change_ratio) { price_change_trigger = "sell"; } var otype = "market"; //0:pt if (ac.holding_data.holding_side != "" && ac.performance_data.unrealized_pl_ratio >= pt_ratio) { ad.add_action("entry", ac.holding_data.holding_side == "buy" ? "sell" : "buy", otype, 0, ac.holding_data.holding_size, -1, "0. Profit Taking"); } //1:lc else if (ac.holding_data.holding_side != "" && ac.performance_data.unrealized_pl_ratio <= lc_ratio) { ad.add_action("entry", ac.holding_data.holding_side == "buy" ? "sell" : "buy", otype, 0, ac.holding_data.holding_size, -1, "1. Loss Cut"); } //2:Entry else if (price_change_trigger != "" && ac.holding_data.holding_entry_num < num_entry && ac.holding_data.holding_size < max_amount && i - ac.holding_data.holding_i >= entry_interval) { ad.add_action("entry", price_change_trigger, otype, 0, entry_amount, -1, "2. Entry"); } //3:Holding max amount, no action else if (ac.holding_data.holding_size < max_amount) { } return(ad); }
/* * buy / sellでエントリー or exitして、常にpositionを保有し続ける。 * orderは全てmarket order */ public StrategyActionData GAWinMarketStrategy(int i, int nn_output, SimAccount ac) { var ad = new StrategyActionData(); var output_action_list = new string[] { "no", "buy", "sell" }; var pred_side = output_action_list[nn_output]; var buy_entry_price = MarketData.Bid[i]; //- 0.5; var sell_entry_price = MarketData.Ask[i]; // + 0.5; var otype = "market"; var amount = 1; //1. New Entry if (pred_side != "no" && ac.holding_data.holding_side == "") { ad.add_action("entry", pred_side, otype, pred_side == "buy" ? buy_entry_price : sell_entry_price, amount, -1, "1. New Entry"); } //2.Exit Order else if (pred_side != "no" && (ac.holding_data.holding_side != pred_side)) { ad.add_action("entry", "", otype, pred_side == "buy" ? buy_entry_price : sell_entry_price, ac.holding_data.holding_size + amount, -1, "2. Eixt and Entry"); } return(ad); }
/* * NNでは最大出力ユニットを発火としているが、limit / marketのorder typeの別を決めるためにNN-ActivateUnitで最後のユニットが0.5以上・未満を判定してorder typeとして出力するように変更が必要。 */ //nn_output = "no", "buy", "sell", "cancel", "Market / Limit" public StrategyActionData GALimitMarketStrategy(int i, List <int> nn_output, int amount, int max_amount, SimAccount ac) { var ad = new StrategyActionData(); var output_action_list = new string[] { "no", "buy", "sell", "cancel" }; var pred_side = output_action_list[nn_output[0]]; var otype = nn_output[1] == 0 ? "market" : "limit"; var buy_entry_price = MarketData.Bid[i]; //- 0.5; var sell_entry_price = MarketData.Ask[i]; // + 0.5; var update_price_kijun = 10; //check invalid situation if (ac.holding_data.holding_size > max_amount) { Console.WriteLine("Sim Strategy: Holding size is larger than max_amount !"); } //1. No / Cancel if (pred_side == "no") { if (ac.order_data.getLastOrderSide() != "" && Math.Abs(ac.order_data.getLastOrderPrice() - (ac.order_data.getLastOrderSide() == "buy" ? buy_entry_price : sell_entry_price)) > update_price_kijun) { ad.add_action("update price", pred_side, otype, pred_side == "buy" ? buy_entry_price : sell_entry_price, -1, ac.order_data.getLastSerialNum(), "1. No: update order price"); } } else if (pred_side == "cancel") { if (ac.order_data.getLastOrderSide() != "") { ad.add_action("cancel", "", "", 0, 0, ac.order_data.getLastSerialNum(), "1. Cancel: cancel all order"); } } else { //2. New Entry if (ac.holding_data.holding_side == "" && pred_side != ac.order_data.getLastOrderSide() && ac.order_data.getLastOrderSide() == "") { ad.add_action("entry", pred_side, otype, pred_side == "buy" ? buy_entry_price : sell_entry_price, amount, -1, "2. New Entry"); } //3.Update Price else if (ac.order_data.getLastOrderSide() == pred_side && Math.Abs(ac.order_data.getLastOrderPrice() - (ac.order_data.getLastOrderSide() == "buy" ? buy_entry_price : sell_entry_price)) > update_price_kijun) { ad.add_action("update price", "", otype, pred_side == "buy" ? buy_entry_price : sell_entry_price, -1, ac.order_data.getLastSerialNum(), "3. update order price"); } //4. Additional Entry (pred = holding sideで現在orderなく、holding sizeにamount加えてもmax_amount以下の時に追加注文) else if (ac.holding_data.holding_side == pred_side && ac.holding_data.holding_size + amount <= max_amount && ac.order_data.getLastOrderSide() == "") { ad.add_action("entry", pred_side, otype, pred_side == "buy" ? buy_entry_price : sell_entry_price, amount, -1, "4. Additional Entry"); } //5. Exit (holding side != predでかつpred sideのorderがない時にexit orderを出す) else if ((ac.holding_data.holding_side != pred_side && ac.holding_data.holding_side != "") && (pred_side != ac.order_data.getLastOrderSide())) { //もし既存のadditional orderがあったらまずはそれをキャンセル) if (ac.order_data.getLastOrderSide() != "") { ad.add_action("cancel", "", "", 0, 0, ac.order_data.getLastSerialNum(), "5. cancel all order"); } ad.add_action("entry", pred_side, otype, pred_side == "buy" ? buy_entry_price : sell_entry_price, ac.holding_data.holding_size, -1, "5. Exit Entry"); } //6. Opposite Order Cancel else if (pred_side != ac.order_data.getLastOrderSide() && ac.order_data.getLastOrderSide() != "") { ad.add_action("cancel", "", "", 0, 0, ac.order_data.getLastSerialNum(), "6. cancel all order"); if (ac.holding_data.holding_size + amount <= max_amount) { ad.add_action("entry", pred_side, otype, pred_side == "buy" ? buy_entry_price : sell_entry_price, amount, -1, "6. Opposite Entry"); } if (ac.holding_data.holding_side != "" && ac.holding_data.holding_side != pred_side) { Console.WriteLine("Strategy: Opposite holding exist while cancelling opposite order !"); } } else { //7. Others1 (既にmax amountのholdingがあり、pred side=holding sideで何もしなくて良い場合) if (ac.holding_data.holding_size >= max_amount && ac.holding_data.holding_side == pred_side) { } //8.Others2(holding side == pred sideで既にpred sideのorderが存在しており、その価格の更新が不要な場合) else if (ac.holding_data.holding_side == pred_side && ac.order_data.getLastOrderSide() == pred_side && Math.Abs(ac.order_data.getLastOrderPrice() - (ac.order_data.getLastOrderSide() == "buy" ? buy_entry_price : sell_entry_price)) <= update_price_kijun) { } //9. Others3 (holding side != predで既にexit orderが存在しており、update priceも不要な場合) else if (ac.holding_data.holding_side != pred_side && ac.order_data.getLastOrderSide() == pred_side && Math.Abs(ac.order_data.getLastOrderPrice() - (ac.order_data.getLastOrderSide() == "buy" ? buy_entry_price : sell_entry_price)) <= update_price_kijun) { } //10.Others4(holding side == pred sideでorderもない場合) else if (ac.holding_data.holding_side == pred_side && ac.order_data.getLastOrderSide() == "") { } else { Console.WriteLine("Strategy - Unknown Situation !"); } } } return(ad); }