❓ASK – Is forex really easy? | Proxies-free

Pertaining to the question if forex is really easy. Well, I would say that forex isn’t easy especially when you are a beginner in it . That is why it is always advisable to go for knowledge first and gather experience which will make you a master and by then, you get familiar and it becomes simple/easy. Traders learn every day in the forex market

 

❓ASK – Your knowledg is your weapon in forex. | Proxies-free

Many newbie traders joins the market with high expectations that they will earn huge from forex market. But at the end, only a few is able to sustain for long time. For many people, forex market may seem easy from the outside, but once you start trading here, then only you will come to know that it’s much more complicated and uncertain.

Almost 90% of the newbie traders fails in the forex market. The main reason behind this is their lack of knowledge. A pro trader is rich in his knowledge and experience which a newbie trader lacks. And to survive here a newbie trader has to gain knowledge first. Because in manyb uncertain situation, only your knowledge will help you to come out of such adverse situation. That is why knowledge is called the weapon to sustain and earn long term from forex market.

Pamm Forex Brokers – Best Forex Brokers Offering

Reduced Size Image

The HotForex PAMM Program is an investment vehicle that allows anyone the opportunity to invest without having to trade the markets themselves. Our PAMM Program also allows Fund Managers to earn additional revenue for successful management of client funds.

Understanding how the HotForex PAMM Program Works
As a HotForex PAMM Manager, you open a HotForex PAMM Account and allocate funds to your Manager Account – this is known as the Manager’s Capital. When a PAMM Manager successfully manages investors’ funds by generating a profit, the Manager will receive a Success Fee – a pre-agreed percentage of the investor’s share of the profit.

To choose a PAMM Manager, Investors can review the PAMM Performance Rankings page and select the PAMM Managers who match their investment goals. It’s easy to find a Manager from the customisable PAMM Performance Table by filtering results by active/ inactive strategies, current ranking, PAMM strategy name, minimum deposit, gain and maximum drawdown.

PAMM Managers trade using their own capital (Manager’s Capital) and the funds of any investors in the account. Simply put, any profits and losses generated on the PAMM Manager’s Account will be shared between all accounts that are invested in the PAMM Manager on a proportional basis.

All investments and transfers within the HotForex PAMM program are fully controlled by us automatically, ensuring that both the Investor and Fund Manager have peace of mind when it comes to security. As a trade is closed, profits and losses (P/L) are distributed to the Investors and Fund Manager, based on their participation. At predefined periods of time, the HotForex PAMM Fund Manager receives the fee specified within the Manager’s Offer.

INVEST IN PAMM

What do you think about forex?

{
“lightbox_close”: “Close”,
“lightbox_next”: “Next”,
“lightbox_previous”: “Previous”,
“lightbox_error”: “The requested content cannot be loaded. Please try again later.”,
“lightbox_start_slideshow”: “Start slideshow”,
“lightbox_stop_slideshow”: “Stop slideshow”,
“lightbox_full_screen”: “Full screen”,
“lightbox_thumbnails”: “Thumbnails”,
“lightbox_download”: “Download”,
“lightbox_share”: “Share”,
“lightbox_zoom”: “Zoom”,
“lightbox_new_window”: “New window”,
“lightbox_toggle_sidebar”: “Toggle sidebar”
}

42AD9539-11E3-4553-91B5-2D3CA9F40298.png

object oriented – Rust backtest forex engine

I wrote a backtest engine in Rust – essentially it is a bunch of if statements mutating variables in a intensive loop.

Recently I had to rewrite the whole because it was getting too complicated for me to understand.

I first wrote the code in my usual procedural style with functional iterators. When it started getting complicated, only thing that made sense was object-oriented style – a big struct with many methods.

It’s easier now and makes sense. Is object-oriented style idiomatic Rust for this kind of problem?

Here is the core code

object-oriented

loop

let mut engine = Backtest{
        instruments,
        strategies,
        algos: data.clone(),
        combos,
        timestamps,
        candles:all_candles.clone(),
        equity: accounts(0).balance,
        initial_balance: accounts(0).balance,
        balance: accounts(0).balance,
        entry_candle: None,
        entry_timestamp_option: None,
        tp_price: None,
        sl_price: None,
        combo: None,
        instrument_candles_option: None,
        instrument_option: None,
        entry_candle_iter_option: None,
        entry_candle_index: 0,
        index_time: None,
        index_candle: None,
        candles_cursor: 0,
        prog_candles: vec!(),
        progs: vec!(),
        entry_price: None,
        exit_price: None,
        wl: None
    };
loop {
        if engine.is_account_drawdown_breached() { break; }

        if engine.entry_candle.is_none() {

            let pti = engine
                .get_previous_timestamp_id();

            let next_combo_candle = engine
                .get_next_combo_candle(&combo_candles,pti);

            if next_combo_candle.is_none() { break; }

            engine.set_instrument_by_candle(next_combo_candle.unwrap());
            engine.set_instrument_candles_by_instrument();

            let ci_from_instrument_candles =
                engine.get_candle_index_from_instrument_candles_by_candle(
                        next_combo_candle.unwrap());
            if engine.is_last_instrument_candle(ci_from_instrument_candles.unwrap()) { break; }

            engine.entry_candle_index = ci_from_instrument_candles.unwrap()+1;
            engine.candles_cursor = ci_from_instrument_candles.unwrap()+1;
            engine.set_entry_candle();
            engine.set_entry_timestamp();
            engine.set_combo();
            engine.set_tp_price();
            engine.set_sl_price();
            engine.set_entry_price();
        }

        // set up candle index
        engine.set_index_candle();
        if engine.is_last_index_candle() { break; }
        engine.set_index_time();
        engine.add_to_prog_candles(engine.index_candle.unwrap());

        engine.set_exit_price();
        engine.set_balance();
        engine.add_to_progs();

        engine.reset_prog_candles();

        engine.increment_candles_cursor();
    }

struct with methods

use crate::db::model::define::*;
use chrono::Duration;

pub struct Backtest {
    pub instruments:Vec<Instrument>,
    pub strategies:Vec<Strategy>,
    pub algos: Vec<Algo>,
    pub combos: Vec<Combo>,
    pub timestamps: Vec<Timestamp>,
    pub candles:Vec<CandleTable>,
    pub equity:f64,
    pub initial_balance:f64,
    pub balance:f64,
    pub entry_candle:Option<CandleTable>,
    pub entry_timestamp_option:Option<Timestamp>,
    pub tp_price:Option<f64>,
    pub sl_price:Option<f64>,
    pub combo:Option<Combo>,
    pub instrument_candles_option:Option<Vec<CandleTable>>,
    pub instrument_option:Option<Instrument>,
    pub entry_candle_iter_option:Option<std::vec::IntoIter<CandleTable>>,
    pub entry_candle_index:usize,
    pub index_time:Option<Timestamp>,
    pub index_candle:Option<CandleTable>,
    pub candles_cursor:usize,
    pub prog_candles:Vec<CandleTable>,
    pub progs:Vec<Prog>,
    pub entry_price:Option<f64>,
    pub exit_price:Option<f64>,
    pub wl:Option<f64>,
}


impl Backtest {

    pub fn is_account_drawdown_breached(&self) -> bool{
        self.balance <= self.initial_balance / 2.0 || self.equity < 0.0
    }

    pub fn is_next_combo_candle_required(&self) -> bool{
        self.entry_candle.is_none()
    }

    pub fn is_last_instrument_candle(&self, index:usize) -> bool{
        self.instrument_candles_option.as_ref().unwrap().get(index+1).is_none()
    }

    pub fn is_last_index_candle(&self) -> bool{
        self.index_candle.is_none()
    }

    pub fn is_trade_expired(&self) ->bool{
        self.index_time
            .unwrap()
            .timestamp
            .signed_duration_since(
                self.entry_timestamp_option.unwrap().timestamp) > Duration::weeks(2)
    }

    pub fn is_buy(&self) -> bool {
        self.combo.as_ref().unwrap().action == 1
    }

    pub fn is_sell(&self) -> bool {
        self.combo.as_ref().unwrap().action == 0
    }
    pub fn set_exit_price(&mut self){
        if self.is_trade_expired() {

            if self.is_buy() {
                self.exit_price = Some(self.index_candle.unwrap().bid_open_num);
            } else {
                self.exit_price = Some(self.index_candle.unwrap().ask_open_num);
            }

        } else if self.is_stop_loss_reached() {
            if self.is_buy() {
                self.exit_price = Some(self.index_candle.unwrap().bid_low_num)
            } else {
                self.exit_price = Some(self.index_candle.unwrap().ask_high_num)
            }
        } else if self.is_take_profit_reached() {
            if self.is_buy() {
                self.exit_price = Some(self.index_candle.unwrap().ask_high_num)
            } else {
                self.exit_price = Some(self.index_candle.unwrap().bid_low_num)
            }
        }
    }

}

procedural

everything

    let account = &accounts(0);
    let strategy = &strategies(0);
    let equity = account.balance;
    let mut balance = account.balance;
    let mut entry_candle:Option<CandleTable> = None;
    let mut entry_timestamp_option:Option<&Timestamp> = None;
    let mut tp_price:Option<f64> = None;
    let mut sl_price:Option<f64> = None;
    let mut combo:Option<&Combo> = None;
    let mut instrument_candles_option:Option<Vec<CandleTable>> = None;
    let mut instrument_option:Option<&Instrument> = None;
    let mut entry_candle_iter_option:Option<std::vec::IntoIter<CandleTable>> = None;
    let mut entry_candle_index = 0;
    let mut index_time:Option<Timestamp> = None;
    let mut index_candle:Option<CandleTable> = None;
    let mut candles_cursor = 0;
    let mut history:History = History{..Default::default()};
    let mut histories:Vec<History> = vec!();

    let mut prog_candles:Vec<CandleTable> = vec!();
    let mut progs:Vec<Prog> = vec!();
    let mut entry_price:Option<f64> = None;
    let mut exit_price:Option<f64> = None;
    let mut wl:Option<f64> = None;


    //Backtest loop

    loop {

        // TODO - add drawdown to db
        if balance <= account.balance / 2.0 || equity < 0.0 {
            break;
        }

        /// Set trade_candle, trade_time, sl, tp
        ///
        /// trade_candle?
        /// ! Entry candle (point of entry) is trade candle.
        /// ! Signal candle is candle where a combo is identified.
        /// Find trade_candle by getting latest combo candle
        /// that hasn't been traded. The entry candle would
        /// be in front.
        ///
        /// trade_time?
        /// timestamp of trade_candle
        ///
        /// sl?
        /// sl from trade_candle
        ///
        /// tp?
        /// tp from trade_candle
        if entry_candle.is_none() {

            // set last known timestamp index
            let last_known_tindex = if entry_candle_index == 0 {
                0 as usize
            } else {
                if index_time.is_none() {
                    println!("{:?} {:?}",index_candle,index_time);
                    unreachable!()
                }
                index_time
                    .unwrap()
                    .id.unwrap() as usize + 1 as usize
            };

            // Get signal candle
            let signal_candle = combo_candles
                .iter()
                .find(|x|
                    x.timestamp_id >= last_known_tindex as i64);
            if signal_candle.is_none() {
                break;
            }

            // set instrument,
            // instrument_id,
            // instrument_candles,
            // signal_candle_index,
            // and check for valid entry candle
            // then set entry candle index,
            // entry candle,
            // entry timestamp
            let instrument_id = signal_candle.unwrap().instrument_id;
            instrument_option = instruments
                .iter()
                .find(|x| x.id.unwrap() == instrument_id);
            let instrument_candles = candles
                .iter()
                .filter(|x| x.instrument_id == instrument_id)
                .cloned()
                .collect::<Vec<_>>();
            instrument_candles_option = Some(instrument_candles.clone());
            let signal_candle_index = instrument_candles
                .iter()
                .position(|x|x.timestamp_id == signal_candle.unwrap().timestamp_id);
            if signal_candle_index.is_none() ||
                instrument_candles.get(signal_candle_index.unwrap()+1).is_none() {
                break;
            }
            entry_candle_index = signal_candle_index.unwrap()+1;
            candles_cursor = entry_candle_index;
            entry_candle = instrument_candles
                .get(entry_candle_index)
                .cloned();
            entry_timestamp_option = timestamps
                .iter()
                .find(|x|x.id.unwrap() == entry_candle.unwrap().timestamp_id);


            prog_candles.push(entry_candle.unwrap());


            // set entry candle iter
            let entry_candle_iter = instrument_candles
                .into_iter();
            entry_candle_iter_option = Option::from(entry_candle_iter);

            // Set combo
            combo = combos
                .iter()
                .find(|x| x.has_instrument_id(instrument_id))
                .or(Option::from(combos.get(0)));

            if combo.as_ref().unwrap().action == 1 {
                sl_price = Some(entry_candle.unwrap().bid_open_num - (strategy.sl / instrument_option.unwrap().decimal_place_value as f64));
                tp_price = Some(entry_candle.unwrap().bid_open_num + (strategy.tp / instrument_option.unwrap().decimal_place_value as f64));
                entry_price = Some(entry_candle.unwrap().bid_open_num)
            } else {
                sl_price = Some(entry_candle.unwrap().ask_open_num + (strategy.sl / instrument_option.unwrap().decimal_place_value as f64));
                tp_price = Some(entry_candle.unwrap().ask_open_num - (strategy.tp / instrument_option.unwrap().decimal_place_value as f64));
                entry_price = Some(entry_candle.unwrap().ask_open_num)
            }
        }

        // necessary vars
        index_candle = instrument_candles_option
            .clone()
            .unwrap()
            .get(candles_cursor)
            .cloned();
        if index_candle.is_none() {
            println!("{:?} {:?} {} {:?}",entry_candle,instrument_option,candles_cursor,
            instrument_candles_option.clone().unwrap().get(3025));
            println!("{} {}","out of bounds",balance);
            break;
        }
        index_time = timestamps
            .iter()
            .cloned()
            .find(|x|x.id.unwrap() == index_candle.unwrap().timestamp_id);

        // 1. if trade expired, perform 2. or 3.
        // 2. if sl reached, deduct losses from balance
        // 3. if tp reached, add profit to balance
        let _sl_price = sl_price.unwrap();
        let _tp_price = tp_price.unwrap();

        //TODO - trade expiry duration should be in strategy db
        //TODO - handle edge case - expiry candle could open in loss or profit
        if index_time.unwrap().timestamp.signed_duration_since(entry_timestamp_option.unwrap().timestamp) > Duration::weeks(2) {
            if combo.as_ref().unwrap().action == 1 {
                exit_price = Some(index_candle.unwrap().bid_open_num);
                let pl = (index_candle.unwrap().bid_open_num - entry_candle.unwrap().bid_open_num) * instrument_option.unwrap().decimal_place_value as f64;
                balance = balance + pl;
                wl = Some(pl);
            } else {
                exit_price = Some(index_candle.unwrap().ask_open_num);
                let pl = (entry_candle.unwrap().ask_open_num - index_candle.unwrap().ask_open_num) * instrument_option.unwrap().decimal_place_value as f64;
                balance = balance + pl;
                wl = Some(pl);
            }


            progs.push(Prog{
                id: None,
                candles:prog_candles.clone(),
                instrument: instrument_option.unwrap().clone(),
                combo: combo.unwrap().clone(),
                entry_price: entry_price.unwrap(),
                exit_price: exit_price.unwrap(),
                wl: if wl.unwrap() > 0.0 {1} else { 0 }
            });

            entry_candle = None;
            tp_price = None;
            sl_price = None;
            instrument_candles_option = None;
            instrument_option = None;
        } else if (combo.as_ref().expect("combo issue").action == 1 && index_candle.expect("index candle issue").bid_low_num as f64 <= _sl_price) ||
            (combo.as_ref().expect("combo issue").action == 0 && index_candle.expect("index candle issue").ask_high_num as f64 >= _sl_price) {
            balance = balance - strategy.sl;
            // todo - not entirely correct but serves the point
            if combo.unwrap().action == 1 {
                exit_price = Some(index_candle.unwrap().bid_low_num)
            } else {
                exit_price = Some(index_candle.unwrap().ask_high_num)
            }


            progs.push(Prog{
                id: None,
                candles:prog_candles.clone(),
                instrument: instrument_option.unwrap().clone(),
                combo: combo.unwrap().clone(),
                entry_price: entry_price.unwrap(),
                exit_price: exit_price.unwrap(),
                wl: 0
            });

            entry_candle = None;
            tp_price = None;
            sl_price = None;

            instrument_candles_option = None;
            instrument_option = None;
        } else if (combo.as_ref().unwrap().action == 1 && index_candle.unwrap().ask_high_num as f64 >= _tp_price) ||
            (combo.as_ref().unwrap().action == 0 && index_candle.unwrap().bid_low_num as f64 <= _tp_price) {
            balance = balance + strategy.tp;
            if combo.unwrap().action == 1 {
                exit_price = Some(index_candle.unwrap().ask_high_num)
            } else {
                exit_price = Some(index_candle.unwrap().bid_low_num)
            }


            progs.push(Prog{
                id: None,
                candles:prog_candles.clone(),
                instrument: instrument_option.unwrap().clone(),
                combo: combo.unwrap().clone(),
                entry_price: entry_price.unwrap(),
                exit_price: exit_price.unwrap(),
                wl: 1
            });

            entry_candle = None;
            tp_price = None;
            sl_price = None;

            instrument_candles_option = None;
            instrument_option = None;
        } else {
            candles_cursor = candles_cursor + 1;
        }

    }
```

Xxl Forex Real Profit Ea

 

How I Make $1000 In One Week With Forex Copy Trading

IPB Image

Earn easy and invest in top traders!
Even if you are a beginner, you can benefit from financial markets thanks to our copy service!

See More

It is really simple to get started!
Choose traders with the best results and get the same results for you!
Choose most liked Get the same result Earn Money

Copy other’s success.
No minimum deposit to start! Use others’ knowledge to earn!